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 53% rename from deploy.sh rename to deploy/tfs.sh index fa1dc2b3623255d2dac82cc1d982c607b9b6af5b..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,61 +206,38 @@ 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..." DEPLOY_LOG="$TMP_LOGS_FOLDER/deploy_${COMPONENT}.log" kubectl --namespace $TFS_K8S_NAMESPACE apply -f "$MANIFEST" > "$DEPLOY_LOG" COMPONENT_OBJNAME=$(echo "${COMPONENT}" | sed "s/\_/-/") - kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=0 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG" - kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=1 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG" + #kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=0 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG" + #kubectl --namespace $TFS_K8S_NAMESPACE scale deployment --replicas=1 ${COMPONENT_OBJNAME}service >> "$DEPLOY_LOG" echo " Collecting env-vars for '$COMPONENT' component..." @@ -234,22 +270,15 @@ done echo "Deploying extra manifests..." for EXTRA_MANIFEST in $TFS_EXTRA_MANIFESTS; do echo "Processing manifest '$EXTRA_MANIFEST'..." - kubectl --namespace $TFS_K8S_NAMESPACE apply -f $EXTRA_MANIFEST + if [[ "$EXTRA_MANIFEST" == *"servicemonitor"* ]]; then + kubectl apply -f $EXTRA_MANIFEST + else + kubectl --namespace $TFS_K8S_NAMESPACE apply -f $EXTRA_MANIFEST + fi printf "\n" 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/\_/-/") @@ -260,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}'", @@ -297,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" : { @@ -321,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 @@ -340,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/gnmi/sonic.clab.yml b/hackfest/gnmi/sonic.clab.yml index dc4f743213406531fab9ac5988342c2b213d88ad..47c1e64643a70e3e0caff12aff8a6796598cea1f 100644 --- a/hackfest/gnmi/sonic.clab.yml +++ b/hackfest/gnmi/sonic.clab.yml @@ -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. + # file: sonic.clab.yml name: sonic-vs 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 5c07971a328a389473899375f2d2aad9031f473e..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,34 +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: "redis" - name: MB_BACKEND - value: "redis" - - 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"] @@ -74,6 +62,8 @@ apiVersion: v1 kind: Service metadata: name: contextservice + labels: + app: contextservice spec: type: ClusterIP selector: @@ -83,7 +73,7 @@ spec: protocol: TCP port: 1010 targetPort: 1010 - - name: http + - name: metrics protocol: TCP - port: 8080 - targetPort: 8080 + port: 9192 + targetPort: 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 d2595ab1915554d7ebfd786b8f39b531e40da490..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. @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: deviceservice + replicas: 1 template: metadata: labels: @@ -28,10 +29,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -53,6 +55,8 @@ apiVersion: v1 kind: Service metadata: name: deviceservice + labels: + app: deviceservice spec: type: ClusterIP selector: @@ -62,3 +66,7 @@ spec: protocol: TCP port: 2020 targetPort: 2020 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/dltservice.yaml b/manifests/dltservice.yaml index d2ad4f40444faa6b9de7724f8b3df077bb7910b2..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,10 +28,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -54,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 @@ -82,6 +83,8 @@ apiVersion: v1 kind: Service metadata: name: dltservice + labels: + app: dltservice spec: type: ClusterIP selector: @@ -91,3 +94,7 @@ spec: protocol: TCP port: 8080 targetPort: 8080 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/interdomainservice.yaml b/manifests/interdomainservice.yaml index 3ef3ffba301cadf26beaa34787dcd816e87c65a0..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,10 +28,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -53,6 +54,8 @@ apiVersion: v1 kind: Service metadata: name: interdomainservice + labels: + app: interdomainservice spec: type: ClusterIP selector: @@ -62,3 +65,7 @@ spec: protocol: TCP port: 10010 targetPort: 10010 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 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 39acfd52330ae6b1c3034e61e793d68491086237..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,26 +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 + - 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"] @@ -91,16 +48,18 @@ 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 metadata: name: monitoringservice + labels: + app: monitoringservice spec: type: ClusterIP selector: @@ -110,37 +69,7 @@ spec: protocol: TCP port: 7070 targetPort: 7070 - - name: http - protocol: TCP - port: 9000 - targetPort: 9000 - - name: influxdb + - name: metrics protocol: TCP - port: 9009 - targetPort: 9009 - - name: postgre - protocol: TCP - port: 8812 - targetPort: 8812 - ---- -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 + port: 9192 + targetPort: 9192 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 92e24ac42b7b86be6056709abd9a2cd6fc16598b..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. @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: pathcompservice + replicas: 1 template: metadata: labels: @@ -28,10 +29,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -49,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: @@ -75,6 +77,8 @@ apiVersion: v1 kind: Service metadata: name: pathcompservice + labels: + app: pathcompservice spec: type: ClusterIP selector: @@ -88,3 +92,7 @@ spec: protocol: TCP port: 8081 targetPort: 8081 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 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 new file mode 100644 index 0000000000000000000000000000000000000000..06c3390f4fddbcb6f8adec5d931989cc8a41cc68 --- /dev/null +++ b/manifests/servicemonitors.yaml @@ -0,0 +1,245 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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: + namespace: monitoring # namespace where prometheus is running + name: tfs-contextservice-metric + labels: + app: contextservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: contextservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-deviceservice-metric + labels: + app: deviceservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: deviceservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-serviceservice-metric + labels: + app: serviceservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: serviceservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-sliceservice-metric + labels: + app: sliceservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: sliceservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-pathcompservice-metric + labels: + app: pathcompservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: pathcompservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-monitoringservice-metric + labels: + app: monitoringservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: monitoringservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-dltservice-metric + labels: + app: dltservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: dltservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + namespace: monitoring # namespace where prometheus is running + name: tfs-interdomainservice-metric + labels: + app: interdomainservice + #release: prometheus + #release: prom # name of the release + # ( VERY IMPORTANT: You need to know the correct release name by viewing + # the servicemonitor of Prometheus itself: Without the correct name, + # Prometheus cannot identify the metrics of the Flask app as the target.) +spec: + selector: + matchLabels: + # Target app service + #namespace: tfs + app: interdomainservice # same as above + #release: prometheus # same as above + endpoints: + - port: metrics # named port in target app + scheme: http + path: /metrics # path to scrape + interval: 5s # scrape interval + namespaceSelector: + any: false + matchNames: + - tfs # namespace where the app is running diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index a5568a5112eb08a02df2178ba45db57b57c19cc3..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. @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: serviceservice + replicas: 1 template: metadata: labels: @@ -28,10 +29,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -53,6 +55,8 @@ apiVersion: v1 kind: Service metadata: name: serviceservice + labels: + app: serviceservice spec: type: ClusterIP selector: @@ -62,3 +66,7 @@ spec: protocol: TCP port: 3030 targetPort: 3030 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml index b20669b0c03cc22857abd1534e19780025b9066a..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. @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: sliceservice + replicas: 1 template: metadata: labels: @@ -28,10 +29,11 @@ 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 + - containerPort: 9192 env: - name: LOG_LEVEL value: "INFO" @@ -53,6 +55,8 @@ apiVersion: v1 kind: Service metadata: name: sliceservice + labels: + app: sliceservice spec: type: ClusterIP selector: @@ -62,3 +66,7 @@ spec: protocol: TCP port: 4040 targetPort: 4040 + - name: metrics + protocol: TCP + port: 9192 + targetPort: 9192 diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml index 7f70e837c4b6b979477a3a02db6e744b41387d73..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 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 1038d6ccd40c8393313fc7f8dbfd48b1e0cf1739..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. @@ -35,20 +35,24 @@ service DltConnectorService { message DltDeviceId { context.TopologyId topology_id = 1; - context.DeviceId device_id = 2; + context.DeviceId device_id = 2; + bool delete = 3; } message DltLinkId { context.TopologyId topology_id = 1; - context.LinkId link_id = 2; + context.LinkId link_id = 2; + bool delete = 3; } message DltServiceId { context.TopologyId topology_id = 1; - context.ServiceId service_id = 2; + context.ServiceId service_id = 2; + bool delete = 3; } message DltSliceId { context.TopologyId topology_id = 1; - context.SliceId slice_id = 2; + context.SliceId slice_id = 2; + bool delete = 3; } 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/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 f87346fed8ebe9b27c806759fafc851a15afd068..06a8c8e10819603dd07b9be9e2cb0bac8652477e 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}" @@ -74,6 +86,7 @@ class XrDriver(_Driver): return [] #pylint: disable=dangerous-default-value + @metered_subclass_method(METRICS_POOL) def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]: LOGGER.info(f"GetConfig[{self}]: {resource_keys=}") chk_type('resources', resource_keys, list) @@ -89,6 +102,7 @@ class XrDriver(_Driver): else: return [] + @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: LOGGER.info(f"SetConfig[{self}]: {resources=}") # Logged config seems like: @@ -116,6 +130,7 @@ class XrDriver(_Driver): return results + @metered_subclass_method(METRICS_POOL) def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: LOGGER.info(f"DeleteConfig[{self}]: {resources=}") @@ -156,10 +171,12 @@ class XrDriver(_Driver): return results + @metered_subclass_method(METRICS_POOL) def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: # Not supported return [False for _ in subscriptions] + @metered_subclass_method(METRICS_POOL) def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]: # Not supported return [False for _ in subscriptions] 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/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 6c5401cb1724f8a759001d790e835ab78ce4c6c6..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. @@ -13,11 +13,12 @@ # limitations under the License. import grpc, logging -from common.proto.context_pb2 import DeviceId, Empty, LinkId, ServiceId, SliceId, TopologyId +from typing import Optional +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method +from common.proto.context_pb2 import Empty, TopologyId from common.proto.dlt_connector_pb2 import DltDeviceId, DltLinkId, DltServiceId, DltSliceId from common.proto.dlt_connector_pb2_grpc import DltConnectorServiceServicer from common.proto.dlt_gateway_pb2 import DltRecord, DltRecordId, DltRecordOperationEnum, DltRecordTypeEnum -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method from common.tools.grpc.Tools import grpc_message_to_json_string from context.client.ContextClient import ContextClient from dlt.connector.client.DltGatewayClient import DltGatewayClient @@ -25,137 +26,122 @@ from .tools.Checkers import record_exists LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'DltConnector' -METHOD_NAMES = [ - 'RecordAll', - 'RecordAllDevices', 'RecordDevice', - 'RecordAllLinks', 'RecordLink', - 'RecordAllServices', 'RecordService', - 'RecordAllSlices', 'RecordSlice', -] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('DltConnector', 'RPC') class DltConnectorServiceServicerImpl(DltConnectorServiceServicer): def __init__(self): LOGGER.debug('Creating Servicer...') LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordAll(self, request : TopologyId, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordAllDevices(self, request : TopologyId, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordDevice(self, request : DltDeviceId, context : grpc.ServicerContext) -> Empty: - context_client = ContextClient() - device = context_client.GetDevice(request.device_id) - - dltgateway_client = DltGatewayClient() - - dlt_record_id = DltRecordId() - dlt_record_id.domain_uuid.uuid = request.topology_id.topology_uuid.uuid - dlt_record_id.type = DltRecordTypeEnum.DLTRECORDTYPE_DEVICE - dlt_record_id.record_uuid.uuid = device.device_id.device_uuid.uuid - - LOGGER.info('[RecordDevice] sent dlt_record_id = {:s}'.format(grpc_message_to_json_string(dlt_record_id))) - dlt_record = dltgateway_client.GetFromDlt(dlt_record_id) - LOGGER.info('[RecordDevice] recv dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) - - exists = record_exists(dlt_record) - LOGGER.info('[RecordDevice] exists = {:s}'.format(str(exists))) - - dlt_record = DltRecord() - dlt_record.record_id.CopyFrom(dlt_record_id) - dlt_record.operation = \ - DltRecordOperationEnum.DLTRECORDOPERATION_UPDATE \ - if exists else \ - DltRecordOperationEnum.DLTRECORDOPERATION_ADD - - dlt_record.data_json = grpc_message_to_json_string(device) - LOGGER.info('[RecordDevice] sent dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) - dlt_record_status = dltgateway_client.RecordToDlt(dlt_record) - LOGGER.info('[RecordDevice] recv dlt_record_status = {:s}'.format(grpc_message_to_json_string(dlt_record_status))) + data_json = None + if not request.delete: + context_client = ContextClient() + device = context_client.GetDevice(request.device_id) + data_json = grpc_message_to_json_string(device) + + self._record_entity( + request.topology_id.topology_uuid.uuid, DltRecordTypeEnum.DLTRECORDTYPE_DEVICE, + request.device_id.device_uuid.uuid, request.delete, data_json) return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordAllLinks(self, request : TopologyId, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordLink(self, request : DltLinkId, context : grpc.ServicerContext) -> Empty: - context_client = ContextClient() - link = context_client.GetLink(request.link_id) - - dltgateway_client = DltGatewayClient() - - dlt_record_id = DltRecordId() - dlt_record_id.domain_uuid.uuid = request.topology_id.topology_uuid.uuid - dlt_record_id.type = DltRecordTypeEnum.DLTRECORDTYPE_LINK - dlt_record_id.record_uuid.uuid = link.link_id.link_uuid.uuid - - LOGGER.info('[RecordLink] sent dlt_record_id = {:s}'.format(grpc_message_to_json_string(dlt_record_id))) - dlt_record = dltgateway_client.GetFromDlt(dlt_record_id) - LOGGER.info('[RecordLink] recv dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) - - exists = record_exists(dlt_record) - LOGGER.info('[RecordLink] exists = {:s}'.format(str(exists))) - - dlt_record = DltRecord() - dlt_record.record_id.CopyFrom(dlt_record_id) - dlt_record.operation = \ - DltRecordOperationEnum.DLTRECORDOPERATION_UPDATE \ - if exists else \ - DltRecordOperationEnum.DLTRECORDOPERATION_ADD - - dlt_record.data_json = grpc_message_to_json_string(link) - LOGGER.info('[RecordLink] sent dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) - dlt_record_status = dltgateway_client.RecordToDlt(dlt_record) - LOGGER.info('[RecordLink] recv dlt_record_status = {:s}'.format(grpc_message_to_json_string(dlt_record_status))) + data_json = None + if not request.delete: + context_client = ContextClient() + link = context_client.GetLink(request.link_id) + data_json = grpc_message_to_json_string(link) + + self._record_entity( + request.topology_id.topology_uuid.uuid, DltRecordTypeEnum.DLTRECORDTYPE_LINK, + request.link_id.link_uuid.uuid, request.delete, data_json) return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordAllServices(self, request : TopologyId, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordService(self, request : DltServiceId, context : grpc.ServicerContext) -> Empty: + data_json = None + if not request.delete: + context_client = ContextClient() + service = context_client.GetService(request.service_id) + data_json = grpc_message_to_json_string(service) + + self._record_entity( + request.topology_id.topology_uuid.uuid, DltRecordTypeEnum.DLTRECORDTYPE_SERVICE, + request.service_id.service_uuid.uuid, request.delete, data_json) return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordAllSlices(self, request : TopologyId, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RecordSlice(self, request : DltSliceId, context : grpc.ServicerContext) -> Empty: - context_client = ContextClient() - slice_ = context_client.GetSlice(request.slice_id) + data_json = None + if not request.delete: + context_client = ContextClient() + slice_ = context_client.GetSlice(request.slice_id) + data_json = grpc_message_to_json_string(slice_) + + self._record_entity( + request.topology_id.topology_uuid.uuid, DltRecordTypeEnum.DLTRECORDTYPE_SLICE, + request.slice_id.slice_uuid.uuid, request.delete, data_json) + return Empty() + def _record_entity( + self, dlt_domain_uuid : str, dlt_record_type : DltRecordTypeEnum, dlt_record_uuid : str, delete : bool, + data_json : Optional[str] = None + ) -> None: dltgateway_client = DltGatewayClient() dlt_record_id = DltRecordId() - dlt_record_id.domain_uuid.uuid = request.topology_id.topology_uuid.uuid - dlt_record_id.type = DltRecordTypeEnum.DLTRECORDTYPE_SLICE - dlt_record_id.record_uuid.uuid = slice_.slice_id.slice_uuid.uuid + dlt_record_id.domain_uuid.uuid = dlt_domain_uuid # pylint: disable=no-member + dlt_record_id.type = dlt_record_type + dlt_record_id.record_uuid.uuid = dlt_record_uuid # pylint: disable=no-member - LOGGER.info('[RecordSlice] sent dlt_record_id = {:s}'.format(grpc_message_to_json_string(dlt_record_id))) + str_dlt_record_id = grpc_message_to_json_string(dlt_record_id) + LOGGER.debug('[_record_entity] sent dlt_record_id = {:s}'.format(str_dlt_record_id)) dlt_record = dltgateway_client.GetFromDlt(dlt_record_id) - LOGGER.info('[RecordSlice] recv dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) + str_dlt_record = grpc_message_to_json_string(dlt_record) + LOGGER.debug('[_record_entity] recv dlt_record = {:s}'.format(str_dlt_record)) exists = record_exists(dlt_record) - LOGGER.info('[RecordSlice] exists = {:s}'.format(str(exists))) + LOGGER.debug('[_record_entity] exists = {:s}'.format(str(exists))) dlt_record = DltRecord() - dlt_record.record_id.CopyFrom(dlt_record_id) - dlt_record.operation = \ - DltRecordOperationEnum.DLTRECORDOPERATION_UPDATE \ - if exists else \ - DltRecordOperationEnum.DLTRECORDOPERATION_ADD - - dlt_record.data_json = grpc_message_to_json_string(slice_) - LOGGER.info('[RecordSlice] sent dlt_record = {:s}'.format(grpc_message_to_json_string(dlt_record))) + dlt_record.record_id.CopyFrom(dlt_record_id) # pylint: disable=no-member + if delete and exists: + dlt_record.operation = DltRecordOperationEnum.DLTRECORDOPERATION_DELETE + elif not delete and exists: + dlt_record.operation = DltRecordOperationEnum.DLTRECORDOPERATION_UPDATE + if data_json is None: raise Exception('data_json must be provided when updating') + dlt_record.data_json = data_json + elif not delete and not exists: + dlt_record.operation = DltRecordOperationEnum.DLTRECORDOPERATION_ADD + if data_json is None: raise Exception('data_json must be provided when adding') + dlt_record.data_json = data_json + else: + return + + str_dlt_record = grpc_message_to_json_string(dlt_record) + LOGGER.debug('[_record_entity] sent dlt_record = {:s}'.format(str_dlt_record)) dlt_record_status = dltgateway_client.RecordToDlt(dlt_record) - LOGGER.info('[RecordSlice] recv dlt_record_status = {:s}'.format(grpc_message_to_json_string(dlt_record_status))) - return Empty() + str_dlt_record_status = grpc_message_to_json_string(dlt_record_status) + LOGGER.debug('[_record_entity] recv dlt_record_status = {:s}'.format(str_dlt_record_status)) 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 a178095aeee81c3e6407cf1c6706b047fd1c65fc..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.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +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 @@ -33,9 +33,9 @@ from .Tools import compose_slice, compute_slice_owner, map_abstract_endpoints_to LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'Interdomain' -METHOD_NAMES = ['RequestSlice', 'Authenticate', 'LookUpSlice', 'OrderSliceFromCatalog', 'CreateSliceAndAddToCatalog'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('Interdomain', 'RPC') + +USE_DLT = True class InterdomainServiceServicerImpl(InterdomainServiceServicer): def __init__(self, remote_domain_clients : RemoteDomainClients): @@ -43,7 +43,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): self.remote_domain_clients = remote_domain_clients LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RequestSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: context_client = ContextClient() pathcomp_client = PathCompClient() @@ -95,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, @@ -111,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 @@ -133,14 +147,14 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): slice_id = context_client.SetSlice(reply) return slice_id - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def Authenticate(self, request : TeraFlowController, context : grpc.ServicerContext) -> AuthenticationResult: auth_result = AuthenticationResult() auth_result.context_id.CopyFrom(request.context_id) # pylint: disable=no-member auth_result.authenticated = True return auth_result - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def LookUpSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: try: context_client = ContextClient() @@ -150,16 +164,16 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): #LOGGER.exception('Unable to get slice({:s})'.format(grpc_message_to_json_string(request.slice_id))) return SliceId() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def OrderSliceFromCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice: raise NotImplementedError('OrderSliceFromCatalog') #return Slice() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def CreateSliceAndAddToCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice: 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 01ba90ef5a6cb098e6d419fa0d6abb450893f8c6..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. @@ -13,7 +13,7 @@ # limitations under the License. import grpc, logging -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.context_pb2 import ( AuthenticationResult, Slice, SliceId, SliceStatus, SliceStatusEnum, TeraFlowController) from common.proto.interdomain_pb2_grpc import InterdomainServiceServicer @@ -24,9 +24,7 @@ from slice.client.SliceClient import SliceClient LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'Interdomain' -METHOD_NAMES = ['RequestSlice', 'Authenticate', 'LookUpSlice', 'OrderSliceFromCatalog', 'CreateSliceAndAddToCatalog'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('Interdomain', 'RPC') class InterdomainServiceServicerImpl(InterdomainServiceServicer): def __init__(self, remote_domain_clients : RemoteDomainClients): @@ -34,7 +32,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): self.remote_domain_clients = remote_domain_clients LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RequestSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: context_client = ContextClient() slice_client = SliceClient() @@ -110,25 +108,23 @@ 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, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def Authenticate(self, request : TeraFlowController, context : grpc.ServicerContext) -> AuthenticationResult: auth_result = AuthenticationResult() auth_result.context_id.CopyFrom(request.context_id) # pylint: disable=no-member auth_result.authenticated = True return auth_result - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def LookUpSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: try: context_client = ContextClient() @@ -138,12 +134,12 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer): #LOGGER.exception('Unable to get slice({:s})'.format(grpc_message_to_json_string(request.slice_id))) return SliceId() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def OrderSliceFromCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice: raise NotImplementedError('OrderSliceFromCatalog') #return Slice() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def CreateSliceAndAddToCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice: context_client = ContextClient() slice_client = SliceClient() 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/load_generator/__init__.py b/src/load_generator/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/__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/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/load_generator/client/__init__.py b/src/load_generator/client/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/load_generator/client/__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/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/load_generator/command/__main__.py b/src/load_generator/command/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..7504eb6da6d6adea698249240abf2c4e4559297a --- /dev/null +++ b/src/load_generator/command/__main__.py @@ -0,0 +1,56 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging, sys +from 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__) + +def main(): + LOGGER.info('Starting...') + 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, + 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 + ) + + LOGGER.info('Initializing Generator...') + generator = RequestGenerator(parameters) + generator.initialize() + + LOGGER.info('Running Schedule...') + scheduler = RequestScheduler(parameters, generator, scheduler_class=BlockingScheduler) + scheduler.start() + + LOGGER.info('Done!') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/context/service/grpc_server/Constants.py b/src/load_generator/load_gen/Constants.py similarity index 52% rename from src/context/service/grpc_server/Constants.py rename to src/load_generator/load_gen/Constants.py index 9d7c886c725d22308f33dc274234ad17f595633d..b71dd9a35329e2aef6ce64739f59103a656b4de3 100644 --- a/src/context/service/grpc_server/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. @@ -12,14 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -TOPIC_CONNECTION = 'connection' -TOPIC_CONTEXT = 'context' -TOPIC_TOPOLOGY = 'topology' -TOPIC_DEVICE = 'device' -TOPIC_LINK = 'link' -TOPIC_SERVICE = 'service' -TOPIC_SLICE = 'slice' +from enum import Enum -TOPICS = {TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_TOPOLOGY, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE} +class RequestType(Enum): + SERVICE_L2NM = 'svc-l2nm' + SERVICE_L3NM = 'svc-l3nm' + SERVICE_TAPI = 'svc-tapi' + SERVICE_MW = 'svc-mw' + SLICE_L2NM = 'slc-l2nm' + SLICE_L3NM = 'slc-l3nm' -CONSUME_TIMEOUT = 0.5 # seconds +ENDPOINT_COMPATIBILITY = { + 'PHOTONIC_MEDIA:FLEX:G_6_25GHZ:INPUT': 'PHOTONIC_MEDIA:FLEX:G_6_25GHZ:OUTPUT', + 'PHOTONIC_MEDIA:DWDM:G_50GHZ:INPUT' : 'PHOTONIC_MEDIA:DWDM:G_50GHZ:OUTPUT', +} diff --git a/src/load_generator/load_gen/DltTools.py b/src/load_generator/load_gen/DltTools.py new file mode 100644 index 0000000000000000000000000000000000000000..8799f7d8a13aff6018ffe06700b4478daa2b3271 --- /dev/null +++ b/src/load_generator/load_gen/DltTools.py @@ -0,0 +1,123 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json, queue +from typing import Optional, Set, Tuple +from common.proto.context_pb2 import DeviceId, LinkId, ServiceId, SliceId, TopologyId +from common.proto.dlt_connector_pb2 import DltDeviceId, DltLinkId, DltServiceId, DltSliceId +from common.tools.grpc.Tools import grpc_message_to_json_string +from common.tools.object_factory.Topology import json_topology_id +from context.client.ContextClient import ContextClient +from dlt.connector.client.DltConnectorClient import DltConnectorClient + +def explore_entities_to_record( + slice_id : Optional[SliceId] = None, service_id : Optional[ServiceId] = None +) -> Tuple[Set[str], Set[str], Set[str]]: + + context_client = ContextClient() + + slices_to_record : Set[str] = set() + services_to_record : Set[str] = set() + devices_to_record : Set[str] = set() + + slices_to_explore = queue.Queue() + services_to_explore = queue.Queue() + if slice_id is not None: slices_to_explore.put(slice_id) + if service_id is not None: services_to_explore.put(service_id) + + while not slices_to_explore.empty(): + slice_id = slices_to_explore.get() + slices_to_record.add(grpc_message_to_json_string(slice_id)) + + slice_ = context_client.GetSlice(slice_id) + + for endpoint_id in slice_.slice_endpoint_ids: + devices_to_record.add(grpc_message_to_json_string(endpoint_id.device_id)) + for subslice_id in slice_.slice_subslice_ids: + slices_to_explore.put(subslice_id) + for service_id in slice_.slice_service_ids: + services_to_explore.put(service_id) + + while not services_to_explore.empty(): + service_id = services_to_explore.get() + services_to_record.add(grpc_message_to_json_string(service_id)) + + service = context_client.GetService(service_id) + + for endpoint_id in service.service_endpoint_ids: + devices_to_record.add(grpc_message_to_json_string(endpoint_id.device_id)) + + connections = context_client.ListConnections(service_id) + for connection in connections.connections: + for endpoint_id in connection.path_hops_endpoint_ids: + devices_to_record.add(grpc_message_to_json_string(endpoint_id.device_id)) + for service_id in connection.sub_service_ids: + services_to_explore.put(service_id) + + return slices_to_record, services_to_record, devices_to_record + +def record_device_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, device_id : DeviceId, delete : bool = False +) -> None: + dlt_device_id = DltDeviceId() + dlt_device_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_device_id.device_id.CopyFrom(device_id) # pylint: disable=no-member + dlt_device_id.delete = delete + dlt_connector_client.RecordDevice(dlt_device_id) + +def record_link_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, link_id : LinkId, delete : bool = False +) -> None: + dlt_link_id = DltLinkId() + dlt_link_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_link_id.link_id.CopyFrom(link_id) # pylint: disable=no-member + dlt_link_id.delete = delete + dlt_connector_client.RecordLink(dlt_link_id) + +def record_service_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, service_id : ServiceId, delete : bool = False +) -> None: + dlt_service_id = DltServiceId() + dlt_service_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_service_id.service_id.CopyFrom(service_id) # pylint: disable=no-member + dlt_service_id.delete = delete + dlt_connector_client.RecordService(dlt_service_id) + +def record_slice_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, slice_id : SliceId, delete : bool = False +) -> None: + dlt_slice_id = DltSliceId() + dlt_slice_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_slice_id.slice_id.CopyFrom(slice_id) # pylint: disable=no-member + dlt_slice_id.delete = delete + dlt_connector_client.RecordSlice(dlt_slice_id) + +def record_entities( + slices_to_record : Set[str] = set(), services_to_record : Set[str] = set(), devices_to_record : Set[str] = set(), + delete : bool = False +) -> None: + dlt_connector_client = DltConnectorClient() + dlt_domain_id = TopologyId(**json_topology_id('dlt-perf-eval')) + + for str_device_id in devices_to_record: + device_id = DeviceId(**(json.loads(str_device_id))) + record_device_to_dlt(dlt_connector_client, dlt_domain_id, device_id, delete=delete) + + for str_service_id in services_to_record: + service_id = ServiceId(**(json.loads(str_service_id))) + record_service_to_dlt(dlt_connector_client, dlt_domain_id, service_id, delete=delete) + + for str_slice_id in slices_to_record: + slice_id = SliceId(**(json.loads(str_slice_id))) + record_slice_to_dlt(dlt_connector_client, dlt_domain_id, slice_id, delete=delete) diff --git a/src/load_generator/load_gen/Parameters.py b/src/load_generator/load_gen/Parameters.py new file mode 100644 index 0000000000000000000000000000000000000000..f0de3ea1aa268c520fd214f7f621953289ac5bc9 --- /dev/null +++ b/src/load_generator/load_gen/Parameters.py @@ -0,0 +1,72 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import 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, do_teardown : bool = True, + dry_mode : bool = False, record_to_dlt : bool = False, dlt_domain_id : Optional[str] = None + ) -> None: + self._num_requests = num_requests + self._request_types = request_types + self._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 + + if self._offered_load is None and self._holding_time is not None and self._inter_arrival_time is not None: + self._offered_load = self._holding_time / self._inter_arrival_time + elif self._offered_load is not None and self._holding_time is not None and self._inter_arrival_time is None: + self._inter_arrival_time = self._holding_time / self._offered_load + elif self._offered_load is not None and self._holding_time is None and self._inter_arrival_time is not None: + self._holding_time = self._offered_load * self._inter_arrival_time + else: + MSG = 'Exactly two of offered_load({:s}), inter_arrival_time({:s}), holding_time({:s}) must be specified.' + raise Exception(MSG.format(str(self._offered_load), str(self._inter_arrival_time), str(self._holding_time))) + + if self._record_to_dlt and self._dlt_domain_id is None: + MSG = 'Parameter dlt_domain_id({:s}) must be specified with record_to_dlt({:s}).' + raise Exception(MSG.format(str(self._dlt_domain_id), str(self._record_to_dlt))) + + @property + def num_requests(self): return self._num_requests + + @property + def request_types(self): return self._request_types + + @property + def offered_load(self): return self._offered_load + + @property + def inter_arrival_time(self): return self._inter_arrival_time + + @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 + + @property + def record_to_dlt(self): return self._record_to_dlt + + @property + def dlt_domain_id(self): return self._dlt_domain_id diff --git a/src/load_generator/load_gen/RequestGenerator.py b/src/load_generator/load_gen/RequestGenerator.py new file mode 100644 index 0000000000000000000000000000000000000000..906c26e98a75fe3c8f15d628f863faac4ba2ea16 --- /dev/null +++ b/src/load_generator/load_gen/RequestGenerator.py @@ -0,0 +1,452 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, 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 +from common.tools.object_factory.EndPoint import json_endpoint_id +from common.tools.object_factory.Service import ( + json_service_l2nm_planned, json_service_l3nm_planned, json_service_tapi_planned) +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 .Constants import ENDPOINT_COMPATIBILITY, RequestType +from .DltTools import record_device_to_dlt, record_link_to_dlt +from .Parameters import Parameters + +LOGGER = logging.getLogger(__name__) + +class RequestGenerator: + def __init__(self, parameters : Parameters) -> None: + self._parameters = parameters + self._lock = threading.Lock() + self._num_requests = 0 + self._available_device_endpoints : Dict[str, Set[str]] = dict() + self._used_device_endpoints : Dict[str, Dict[str, str]] = dict() + self._endpoint_ids_to_types : Dict[Tuple[str, str], str] = dict() + 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() + self._used_device_endpoints.clear() + + context_client = ContextClient() + dlt_connector_client = DltConnectorClient() + + if self._parameters.record_to_dlt: + dlt_domain_id = TopologyId(**json_topology_id('dlt-perf-eval')) + + 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) + self._endpoint_types_to_ids.setdefault(endpoint_type, set()).add((device_uuid, endpoint_uuid)) + + if self._parameters.record_to_dlt: + record_device_to_dlt(dlt_connector_client, dlt_domain_id, device.device_id) + + links = context_client.ListLinks(Empty()) + for link in links.links: + for endpoint_id in link.link_endpoint_ids: + device_uuid = endpoint_id.device_id.device_uuid.uuid + endpoint_uuid = endpoint_id.endpoint_uuid.uuid + _endpoints = self._available_device_endpoints.get(device_uuid, set()) + _endpoints.discard(endpoint_uuid) + if len(_endpoints) == 0: self._available_device_endpoints.pop(device_uuid, None) + + endpoint_type = self._endpoint_ids_to_types.pop((device_uuid, endpoint_uuid), None) + if endpoint_type is None: continue + + if endpoint_type not in self._endpoint_types_to_ids: continue + endpoints_for_type = self._endpoint_types_to_ids[endpoint_type] + endpoint_key = (device_uuid, endpoint_uuid) + if endpoint_key not in endpoints_for_type: continue + endpoints_for_type.discard(endpoint_key) + + if self._parameters.record_to_dlt: + record_link_to_dlt(dlt_connector_client, dlt_domain_id, link.link_id) + + @property + def num_requests_generated(self): return self._num_requests + + def dump_state(self) -> None: + with self._lock: + _endpoints = { + device_uuid:[endpoint_uuid for endpoint_uuid in endpoint_uuids] + for device_uuid,endpoint_uuids in self._available_device_endpoints.items() + } + LOGGER.info('[dump_state] available_device_endpoints = {:s}'.format(json.dumps(_endpoints))) + LOGGER.info('[dump_state] used_device_endpoints = {:s}'.format(json.dumps(self._used_device_endpoints))) + + def _use_device_endpoint( + self, service_uuid : str, request_type : RequestType, endpoint_types : Optional[Set[str]] = None, + exclude_device_uuids : Set[str] = set(), exclude_endpoint_uuids : Set[Tuple[str, str]] = set(), + ) -> Optional[Tuple[str, str]]: + with self._lock: + compatible_endpoints : Set[Tuple[str, str]] = set() + elegible_device_endpoints : Dict[str, Set[str]] = {} + + if endpoint_types is None: + # allow all + elegible_device_endpoints : Dict[str, Set[str]] = { + device_uuid:[ + endpoint_uuid for endpoint_uuid in device_endpoint_uuids + if (len(exclude_endpoint_uuids) == 0) or \ + ((device_uuid,endpoint_uuid) not in exclude_endpoint_uuids) + ] + for device_uuid,device_endpoint_uuids in self._available_device_endpoints.items() + if (device_uuid not in exclude_device_uuids) and \ + (len(device_endpoint_uuids) > 0) + } + else: + # allow only compatible endpoints + for endpoint_type in endpoint_types: + if endpoint_type not in self._endpoint_types_to_ids: continue + compatible_endpoints.update(self._endpoint_types_to_ids[endpoint_type]) + + for device_uuid,device_endpoint_uuids in self._available_device_endpoints.items(): + if device_uuid in exclude_device_uuids or len(device_endpoint_uuids) == 0: continue + for endpoint_uuid in device_endpoint_uuids: + endpoint_key = (device_uuid,endpoint_uuid) + if endpoint_key in exclude_endpoint_uuids: continue + if endpoint_key not in compatible_endpoints: continue + elegible_device_endpoints.setdefault(device_uuid, set()).add(endpoint_uuid) + + if len(elegible_device_endpoints) == 0: + LOGGER.warning(' '.join([ + '>> No endpoint is available:', + 'endpoint_types={:s}'.format(str(endpoint_types)), + 'exclude_device_uuids={:s}'.format(str(exclude_device_uuids)), + 'self._endpoint_types_to_ids={:s}'.format(str(self._endpoint_types_to_ids)), + 'self._available_device_endpoints={:s}'.format(str(self._available_device_endpoints)), + 'compatible_endpoints={:s}'.format(str(compatible_endpoints)), + ])) + return None + + device_uuid = random.choice(list(elegible_device_endpoints.keys())) + device_endpoint_uuids = elegible_device_endpoints.get(device_uuid) + endpoint_uuid = random.choice(list(device_endpoint_uuids)) + if request_type not in {RequestType.SERVICE_MW}: + # reserve the resources + self._available_device_endpoints.setdefault(device_uuid, set()).discard(endpoint_uuid) + self._used_device_endpoints.setdefault(device_uuid, dict())[endpoint_uuid] = service_uuid + return device_uuid, endpoint_uuid + + def _release_device_endpoint(self, device_uuid : str, endpoint_uuid : str) -> None: + with self._lock: + self._used_device_endpoints.setdefault(device_uuid, dict()).pop(endpoint_uuid, None) + self._available_device_endpoints.setdefault(device_uuid, set()).add(endpoint_uuid) + + def compose_request(self) -> Optional[Dict]: + with self._lock: + self._num_requests += 1 + num_request = self._num_requests + + #request_uuid = str(uuid.uuid4()) + request_uuid = 'svc_{:d}'.format(num_request) + + # choose request type + request_type = random.choice(self._parameters.request_types) + + if request_type in { + RequestType.SERVICE_L2NM, RequestType.SERVICE_L3NM, RequestType.SERVICE_TAPI, RequestType.SERVICE_MW + }: + return self._compose_service(num_request, request_uuid, request_type) + elif request_type in {RequestType.SLICE_L2NM, RequestType.SLICE_L3NM}: + return self._compose_slice(num_request, request_uuid, request_type) + + def _compose_service(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + # choose source endpoint + src_endpoint_types = set(ENDPOINT_COMPATIBILITY.keys()) if request_type in {RequestType.SERVICE_TAPI} else None + src = self._use_device_endpoint(request_uuid, request_type, endpoint_types=src_endpoint_types) + if src is None: + LOGGER.warning('>> No source endpoint is available') + return None + src_device_uuid,src_endpoint_uuid = src + + # identify compatible destination endpoint types + src_endpoint_type = self._endpoint_ids_to_types.get((src_device_uuid,src_endpoint_uuid)) + dst_endpoint_type = ENDPOINT_COMPATIBILITY.get(src_endpoint_type) + dst_endpoint_types = {dst_endpoint_type} if request_type in {RequestType.SERVICE_TAPI} else None + + # identify excluded destination devices + 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, endpoint_types=dst_endpoint_types, exclude_device_uuids=exclude_device_uuids, + exclude_endpoint_uuids={src}) + + # if destination endpoint not found, release source, and terminate current service generation + if dst is None: + LOGGER.warning('>> No destination endpoint is available') + self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) + return None + + # compose endpoints + dst_device_uuid,dst_endpoint_uuid = dst + endpoint_ids = [ + json_endpoint_id(json_device_id(src_device_uuid), src_endpoint_uuid), + json_endpoint_id(json_device_id(dst_device_uuid), dst_endpoint_uuid), + ] + + if request_type == RequestType.SERVICE_L2NM: + constraints = [ + json_constraint_custom('bandwidth[gbps]', '10.0'), + json_constraint_custom('latency[ms]', '20.0'), + ] + vlan_id = num_request % 1000 + circuit_id = '{:03d}'.format(vlan_id) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + + 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, + }), + ] + return json_service_l2nm_planned( + request_uuid, endpoint_ids=endpoint_ids, constraints=constraints, config_rules=config_rules) + + elif request_type == RequestType.SERVICE_L3NM: + constraints = [ + json_constraint_custom('bandwidth[gbps]', '10.0'), + json_constraint_custom('latency[ms]', '20.0'), + ] + vlan_id = num_request % 1000 + bgp_as = 60000 + (num_request % 10000) + bgp_route_target = '{:5d}:{:03d}'.format(bgp_as, 333) + route_distinguisher = '{:5d}:{:03d}'.format(bgp_as, vlan_id) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_endpoint_name = self._device_endpoint_data[src_device_uuid][src_endpoint_uuid]['name'] + src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + src_address_ip = '.'.join([src_device_name.replace('R', ''), '0'] + src_endpoint_name.split('/')) + + 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, + }), + ] + return json_service_l3nm_planned( + request_uuid, endpoint_ids=endpoint_ids, constraints=constraints, config_rules=config_rules) + + elif request_type == RequestType.SERVICE_TAPI: + config_rules = [ + json_config_rule_set('/settings', { + 'capacity_value' : 50.0, + 'capacity_unit' : 'GHz', + 'layer_proto_name': 'PHOTONIC_MEDIA', + 'layer_proto_qual': 'tapi-photonic-media:PHOTONIC_LAYER_QUALIFIER_NMC', + 'direction' : 'UNIDIRECTIONAL', + }), + ] + return json_service_tapi_planned( + request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules) + + elif request_type == RequestType.SERVICE_MW: + vlan_id = 1000 + num_request % 1000 + config_rules = [ + json_config_rule_set('/settings', { + 'vlan_id': vlan_id, + }), + ] + return json_service_l2nm_planned( + request_uuid, endpoint_ids=endpoint_ids, constraints=[], config_rules=config_rules) + + def _compose_slice(self, num_request : int, request_uuid : str, request_type : str) -> Optional[Dict]: + # choose source endpoint + src = self._use_device_endpoint(request_uuid, request_type) + if src is None: + LOGGER.warning('>> No source endpoint is available') + return None + src_device_uuid,src_endpoint_uuid = src + + # identify excluded destination devices + 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) + + # if destination endpoint not found, release source, and terminate current service generation + if dst is None: + LOGGER.warning('>> No destination endpoint is available') + self._release_device_endpoint(src_device_uuid, src_endpoint_uuid) + return None + + # compose endpoints + dst_device_uuid,dst_endpoint_uuid = dst + endpoint_ids = [ + json_endpoint_id(json_device_id(src_device_uuid), src_endpoint_uuid), + json_endpoint_id(json_device_id(dst_device_uuid), dst_endpoint_uuid), + ] + constraints = [ + json_constraint_custom('bandwidth[gbps]', '10.0'), + json_constraint_custom('latency[ms]', '20.0'), + ] + + if request_type == RequestType.SLICE_L2NM: + vlan_id = num_request % 1000 + circuit_id = '{:03d}'.format(vlan_id) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + + 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, + }), + ] + + elif request_type == RequestType.SLICE_L3NM: + vlan_id = num_request % 1000 + bgp_as = 60000 + (num_request % 10000) + bgp_route_target = '{:5d}:{:03d}'.format(bgp_as, 333) + route_distinguisher = '{:5d}:{:03d}'.format(bgp_as, vlan_id) + + src_device_name = self._device_data[src_device_uuid]['name'] + src_endpoint_name = self._device_endpoint_data[src_device_uuid][src_endpoint_uuid]['name'] + src_router_id = '10.0.0.{:d}'.format(int(src_device_name.replace('R', ''))) + src_address_ip = '.'.join([src_device_name.replace('R', ''), '0'] + src_endpoint_name.split('/')) + + 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, + }), + ] + + return json_slice( + request_uuid, endpoint_ids=endpoint_ids, constraints=constraints, config_rules=config_rules) + + def release_request(self, json_request : Dict) -> None: + if 'service_id' in json_request: + for endpoint_id in json_request['service_endpoint_ids']: + device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] + endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] + self._release_device_endpoint(device_uuid, endpoint_uuid) + elif 'slice_id' in json_request: + for endpoint_id in json_request['slice_endpoint_ids']: + device_uuid = endpoint_id['device_id']['device_uuid']['uuid'] + endpoint_uuid = endpoint_id['endpoint_uuid']['uuid'] + self._release_device_endpoint(device_uuid, endpoint_uuid) diff --git a/src/load_generator/load_gen/RequestScheduler.py b/src/load_generator/load_gen/RequestScheduler.py new file mode 100644 index 0000000000000000000000000000000000000000..775da1580a2a6521dbdc8fe32236c1f2adb4b3a7 --- /dev/null +++ b/src/load_generator/load_gen/RequestScheduler.py @@ -0,0 +1,200 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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, pytz, random +from apscheduler.executors.pool import ThreadPoolExecutor +from apscheduler.jobstores.memory import MemoryJobStore +from apscheduler.schedulers.blocking import BlockingScheduler +from datetime import datetime, timedelta +from typing import Dict, Optional +from common.proto.context_pb2 import Service, ServiceId, Slice, SliceId +from service.client.ServiceClient import ServiceClient +from slice.client.SliceClient import SliceClient +from .DltTools import explore_entities_to_record, record_entities +from .Parameters import Parameters +from .RequestGenerator import RequestGenerator + +logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING) +logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING) + +LOGGER = logging.getLogger(__name__) + +class RequestScheduler: + 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)}, + job_defaults = { + 'coalesce': False, + 'max_instances': 100, + 'misfire_grace_time': 120, + }, + timezone=pytz.utc) + self._parameters = parameters + self._generator = generator + + def _schedule_request_setup(self) -> None: + 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 + iat = random.expovariate(1.0 / self._parameters.inter_arrival_time) + run_date = datetime.utcnow() + timedelta(seconds=iat) + self._scheduler.add_job( + self._request_setup, trigger='date', run_date=run_date, timezone=pytz.utc) + + def _schedule_request_teardown(self, request : Dict) -> None: + ht = random.expovariate(1.0 / self._parameters.holding_time) + run_date = datetime.utcnow() + timedelta(seconds=ht) + self._scheduler.add_job( + self._request_teardown, args=(request,), trigger='date', run_date=run_date, timezone=pytz.utc) + + def start(self): + self._schedule_request_setup() + self._scheduler.start() + + def stop(self): + self._scheduler.shutdown() + + def _request_setup(self) -> None: + self._schedule_request_setup() + + request = self._generator.compose_request() + if request is None: + LOGGER.warning('No resources available to compose new request') + return + + if 'service_id' in request: + service_uuid = request['service_id']['service_uuid']['uuid'] + src_device_uuid = request['service_endpoint_ids'][0]['device_id']['device_uuid']['uuid'] + src_endpoint_uuid = request['service_endpoint_ids'][0]['endpoint_uuid']['uuid'] + dst_device_uuid = request['service_endpoint_ids'][1]['device_id']['device_uuid']['uuid'] + dst_endpoint_uuid = request['service_endpoint_ids'][1]['endpoint_uuid']['uuid'] + LOGGER.info('Setup Service: uuid=%s src=%s:%s dst=%s:%s', + service_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) + self._create_update(service=request) + + elif 'slice_id' in request: + slice_uuid = request['slice_id']['slice_uuid']['uuid'] + src_device_uuid = request['slice_endpoint_ids'][0]['device_id']['device_uuid']['uuid'] + src_endpoint_uuid = request['slice_endpoint_ids'][0]['endpoint_uuid']['uuid'] + dst_device_uuid = request['slice_endpoint_ids'][1]['device_id']['device_uuid']['uuid'] + dst_endpoint_uuid = request['slice_endpoint_ids'][1]['endpoint_uuid']['uuid'] + LOGGER.info('Setup Slice: uuid=%s src=%s:%s dst=%s:%s', + slice_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) + self._create_update(slice_=request) + + if self._parameters.do_teardown: + self._schedule_request_teardown(request) + + def _request_teardown(self, request : Dict) -> None: + if 'service_id' in request: + service_uuid = request['service_id']['service_uuid']['uuid'] + src_device_uuid = request['service_endpoint_ids'][0]['device_id']['device_uuid']['uuid'] + src_endpoint_uuid = request['service_endpoint_ids'][0]['endpoint_uuid']['uuid'] + dst_device_uuid = request['service_endpoint_ids'][1]['device_id']['device_uuid']['uuid'] + dst_endpoint_uuid = request['service_endpoint_ids'][1]['endpoint_uuid']['uuid'] + LOGGER.info('Teardown Service: uuid=%s src=%s:%s dst=%s:%s', + service_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) + self._delete(service_id=ServiceId(**(request['service_id']))) + + elif 'slice_id' in request: + slice_uuid = request['slice_id']['slice_uuid']['uuid'] + src_device_uuid = request['slice_endpoint_ids'][0]['device_id']['device_uuid']['uuid'] + src_endpoint_uuid = request['slice_endpoint_ids'][0]['endpoint_uuid']['uuid'] + dst_device_uuid = request['slice_endpoint_ids'][1]['device_id']['device_uuid']['uuid'] + dst_endpoint_uuid = request['slice_endpoint_ids'][1]['endpoint_uuid']['uuid'] + LOGGER.info('Teardown Slice: uuid=%s src=%s:%s dst=%s:%s', + slice_uuid, src_device_uuid, src_endpoint_uuid, dst_device_uuid, dst_endpoint_uuid) + self._delete(slice_id=SliceId(**(request['slice_id']))) + + self._generator.release_request(request) + + def _create_update(self, service : Optional[Dict] = None, slice_ : Optional[Dict] = None) -> None: + if self._parameters.dry_mode: return + + service_id = None + if service is not None: + service_add = copy.deepcopy(service) + service_add['service_endpoint_ids'] = [] + service_add['service_constraints'] = [] + service_add['service_config'] = {'config_rules': []} + + service_client = ServiceClient() + service_id = service_client.CreateService(Service(**service_add)) + service_client.close() + + slice_id = None + if slice_ is not None: + slice_add = copy.deepcopy(slice_) + slice_add['slice_endpoint_ids'] = [] + slice_add['slice_constraints'] = [] + slice_add['slice_config'] = {'config_rules': []} + + slice_client = SliceClient() + slice_id = slice_client.CreateSlice(Slice(**slice_add)) + slice_client.close() + + if self._parameters.record_to_dlt: + entities_to_record = explore_entities_to_record(slice_id=slice_id, service_id=service_id) + slices_to_record, services_to_record, devices_to_record = entities_to_record + record_entities( + slices_to_record=slices_to_record, services_to_record=services_to_record, + devices_to_record=devices_to_record, delete=False) + + service_id = None + if service is not None: + service_client = ServiceClient() + service_id = service_client.UpdateService(Service(**service)) + service_client.close() + + slice_id = None + if slice_ is not None: + slice_client = SliceClient() + slice_id = slice_client.UpdateSlice(Slice(**slice_)) + slice_client.close() + + if self._parameters.record_to_dlt: + entities_to_record = explore_entities_to_record(slice_id=slice_id, service_id=service_id) + slices_to_record, services_to_record, devices_to_record = entities_to_record + record_entities( + slices_to_record=slices_to_record, services_to_record=services_to_record, + devices_to_record=devices_to_record, delete=False) + + def _delete(self, service_id : Optional[ServiceId] = None, slice_id : Optional[SliceId] = None) -> None: + if self._parameters.dry_mode: return + + if self._parameters.record_to_dlt: + entities_to_record = explore_entities_to_record(slice_id=slice_id, service_id=service_id) + slices_to_record, services_to_record, devices_to_record = entities_to_record + + if slice_id is not None: + slice_client = SliceClient() + slice_client.DeleteSlice(slice_id) + slice_client.close() + + if service_id is not None: + service_client = ServiceClient() + service_client.DeleteService(service_id) + service_client.close() + + if self._parameters.record_to_dlt: + record_entities( + slices_to_record=slices_to_record, services_to_record=services_to_record, + devices_to_record=devices_to_record, delete=True) 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/load_generator/run.sh b/src/load_generator/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..0ef004598ea91e54b6b054a48a0b830287ce5ed3 --- /dev/null +++ b/src/load_generator/run.sh @@ -0,0 +1,19 @@ +#!/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. + +# Use this script to run standalone + +source tfs_runtime_env_vars.sh +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/load_generator/tests/deploy_specs.sh b/src/load_generator/tests/deploy_specs.sh new file mode 100755 index 0000000000000000000000000000000000000000..571990ecabfbf120b517f44fd99b4550a4b8a9a1 --- /dev/null +++ b/src/load_generator/tests/deploy_specs.sh @@ -0,0 +1,40 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/" + +# 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 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" + +# Set the name of the Kubernetes namespace to deploy 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 manifests/servicemonitors.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="NO" #${TFS_SKIP_BUILD:-"YES"} diff --git a/src/load_generator/tests/descriptors.json b/src/load_generator/tests/descriptors.json new file mode 100644 index 0000000000000000000000000000000000000000..5fb0c086749cab3343277c28a902b3db48651320 --- /dev/null +++ b/src/load_generator/tests/descriptors.json @@ -0,0 +1,229 @@ +{ + "contexts": [ + { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_ids": [], "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_uuid": {"uuid": "admin"} + }, + "device_ids": [ + {"device_uuid": {"uuid": "R1"}}, + {"device_uuid": {"uuid": "R2"}}, + {"device_uuid": {"uuid": "R3"}}, + {"device_uuid": {"uuid": "R4"}}, + {"device_uuid": {"uuid": "R5"}}, + {"device_uuid": {"uuid": "R6"}}, + {"device_uuid": {"uuid": "R7"}} + ], + "link_ids": [ + {"link_uuid": {"uuid": "R1==R2"}}, + {"link_uuid": {"uuid": "R2==R3"}}, + {"link_uuid": {"uuid": "R3==R4"}}, + {"link_uuid": {"uuid": "R4==R5"}}, + {"link_uuid": {"uuid": "R5==R6"}}, + {"link_uuid": {"uuid": "R6==R1"}}, + {"link_uuid": {"uuid": "R1==R7"}}, + {"link_uuid": {"uuid": "R3==R7"}}, + {"link_uuid": {"uuid": "R5==R7"}} + ] + } + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R4"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R5"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R6"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R7"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/4"}, + {"sample_types": [], "type": "copper", "uuid": "2/5"}, + {"sample_types": [], "type": "copper", "uuid": "2/6"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "R1==R2"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R2==R3"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R3==R4"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R4==R5"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R5==R6"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R6==R1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R1==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R3==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/3"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R5==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/5"}} + ] + } + ] +} \ No newline at end of file diff --git a/src/load_generator/tests/test_dlt_functional.py b/src/load_generator/tests/test_dlt_functional.py new file mode 100644 index 0000000000000000000000000000000000000000..764b0432053902b5533cc7844fcb12f42888de83 --- /dev/null +++ b/src/load_generator/tests/test_dlt_functional.py @@ -0,0 +1,73 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 +from common.proto.context_pb2 import ( + DEVICEOPERATIONALSTATUS_ENABLED, Device, DeviceId, LinkId, ServiceId, SliceId, TopologyId) +from common.proto.dlt_connector_pb2 import DltDeviceId, DltLinkId, DltServiceId, DltSliceId +from common.tools.object_factory.Device import json_device +from common.tools.object_factory.Topology import json_topology_id +from context.client.ContextClient import ContextClient +from dlt.connector.client.DltConnectorClient import DltConnectorClient + +def record_device_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, device_id : DeviceId, delete : bool = False +) -> None: + dlt_device_id = DltDeviceId() + dlt_device_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_device_id.device_id.CopyFrom(device_id) # pylint: disable=no-member + dlt_device_id.delete = delete + dlt_connector_client.RecordDevice(dlt_device_id) + +def record_link_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, link_id : LinkId, delete : bool = False +) -> None: + dlt_link_id = DltLinkId() + dlt_link_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_link_id.link_id.CopyFrom(link_id) # pylint: disable=no-member + dlt_link_id.delete = delete + dlt_connector_client.RecordLink(dlt_link_id) + +def record_service_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, service_id : ServiceId, delete : bool = False +) -> None: + dlt_service_id = DltServiceId() + dlt_service_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_service_id.service_id.CopyFrom(service_id) # pylint: disable=no-member + dlt_service_id.delete = delete + dlt_connector_client.RecordService(dlt_service_id) + +def record_slice_to_dlt( + dlt_connector_client : DltConnectorClient, domain_id : TopologyId, slice_id : SliceId, delete : bool = False +) -> None: + dlt_slice_id = DltSliceId() + dlt_slice_id.topology_id.CopyFrom(domain_id) # pylint: disable=no-member + dlt_slice_id.slice_id.CopyFrom(slice_id) # pylint: disable=no-member + dlt_slice_id.delete = delete + dlt_connector_client.RecordSlice(dlt_slice_id) + +def main(): + context_client = ContextClient() + dlt_connector_client = DltConnectorClient() + + device = Device(**json_device('test-device', 'packet-router', DEVICEOPERATIONALSTATUS_ENABLED)) + device_id = context_client.SetDevice(device) + + dlt_domain_id = TopologyId(**json_topology_id('dlt-func-test')) + record_device_to_dlt(dlt_connector_client, dlt_domain_id, device_id, delete=False) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) 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 4999d2a95991d79ed5417948e220d35aa668c653..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 common.rpc_method_wrapper.ServiceExceptions import ServiceException +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 548f34c8a07a1d8df17f2702879dbbadf60f6d13..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 @@ -27,7 +25,7 @@ from common.proto.monitoring_pb2_grpc import MonitoringServiceServicer from common.proto.monitoring_pb2 import AlarmResponse, AlarmDescriptor, AlarmList, SubsList, KpiId, \ KpiDescriptor, KpiList, KpiQuery, SubsDescriptor, SubscriptionID, AlarmID, KpiDescriptorList, \ MonitorKpiRequest, Kpi, AlarmSubscription, SubsResponse, RawKpiTable, RawKpi, RawKpiList -from common.rpc_method_wrapper.ServiceExceptions import ServiceException +from common.method_wrappers.ServiceExceptions import ServiceException from common.tools.timestamp.Converters import timestamp_string_to_float, timestamp_utcnow_to_float from monitoring.service import ManagementDBTools, MetricsDBTools @@ -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 4a2dd041b52eaf89bda65acb7ae1e46beed8c48a..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. @@ -14,16 +14,14 @@ import os, grpc, logging, random from influxdb import InfluxDBClient -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from opticalattackmitigator.proto.optical_attack_mitigator_pb2_grpc import ( AttackMitigatorServicer) from opticalattackmitigator.proto.optical_attack_mitigator_pb2 import AttackDescription, AttackResponse LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'OpticalAttackMitigator' -METHOD_NAMES = ['NotifyAttack'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('OpticalAttackMitigator', 'RPC') class OpticalAttackMitigatorServiceServicerImpl(AttackMitigatorServicer): @@ -32,7 +30,7 @@ class OpticalAttackMitigatorServiceServicerImpl(AttackMitigatorServicer): LOGGER.debug('Creating Servicer...') LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def NotifyAttack(self, request : AttackDescription, context : grpc.ServicerContext) -> AttackResponse: LOGGER.debug(f"NotifyAttack: {request}") response: AttackResponse = AttackResponse() 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 d4c71476f016081f7d230a3cfe87e73b35654987..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. @@ -14,7 +14,7 @@ import os, grpc, logging, random from influxdb import InfluxDBClient -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from context.client.ContextClient import ContextClient from monitoring.client.MonitoringClient import MonitoringClient from service.client.ServiceClient import ServiceClient @@ -37,9 +37,7 @@ from opticalcentralizedattackdetector.Config import ( LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'OpticalCentralizedAttackDetector' -METHOD_NAMES = ['NotifyServiceUpdate', 'DetectAttack', 'ReportSummarizedKpi', 'ReportKpi'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('OpticalCentralizedAttackDetector', 'RPC') INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME") INFLUXDB_USER = os.environ.get("INFLUXDB_USER") @@ -63,11 +61,11 @@ class OpticalCentralizedAttackDetectorServiceServicerImpl(OpticalCentralizedAtta LOGGER.debug('Creating Servicer...') LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def NotifyServiceUpdate(self, request : Service, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def DetectAttack(self, request : Empty, context : grpc.ServicerContext) -> Empty: # retrieve list with current contexts @@ -131,10 +129,10 @@ class OpticalCentralizedAttackDetectorServiceServicerImpl(OpticalCentralizedAtta # if attack is detected, run the attack mitigator return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ReportSummarizedKpi(self, request : KpiList, context : grpc.ServicerContext) -> Empty: return Empty() - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ReportKpi(self, request : KpiList, context : grpc.ServicerContext) -> Empty: return Empty() diff --git a/src/opticalcentralizedattackdetector/service/__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 8fe704c3932c219e0f04046fcc62d6f1da5f9b66..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 10 // 100 # LGR: reduced from 100 to 10 to divide by 10 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 205306d0ec2d156a2050d1f95c5c1e990796e018..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. @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import grpc, logging -from common.Constants import DEFAULT_CONTEXT_UUID, INTERDOMAIN_TOPOLOGY_UUID +import grpc, logging, threading +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 from common.proto.pathcomp_pb2_grpc import PathCompServiceServicer -from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method from common.tools.context_queries.Device import get_devices_in_topology from common.tools.context_queries.Link import get_links_in_topology from common.tools.context_queries.InterDomain import is_inter_domain @@ -28,26 +28,25 @@ from pathcomp.frontend.service.algorithms.Factory import get_algorithm LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'PathComp' -METHOD_NAMES = ['Compute'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +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: LOGGER.debug('Creating Servicer...') + self._lock = threading.Lock() LOGGER.debug('Servicer Created') - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def Compute(self, request : PathCompRequest, context : grpc.ServicerContext) -> PathCompReply: - LOGGER.info('[Compute] begin ; request = {:s}'.format(grpc_message_to_json_string(request))) + LOGGER.debug('[Compute] begin ; request = {:s}'.format(grpc_message_to_json_string(request))) 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 @@ -68,8 +67,10 @@ class PathCompServiceServicerImpl(PathCompServiceServicer): #import time #ts = time.time() #algorithm.execute('request-{:f}.json'.format(ts), 'reply-{:f}.json'.format(ts)) - algorithm.execute() + with self._lock: + # ensure backend receives requests one at a time + algorithm.execute() reply = algorithm.get_reply() - LOGGER.info('[Compute] end ; reply = {:s}'.format(grpc_message_to_json_string(reply))) + LOGGER.debug('[Compute] end ; reply = {:s}'.format(grpc_message_to_json_string(reply))) return reply 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 3833642457bc5f8c2ba7b7d09f384a87dfabe41d..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,22 +105,22 @@ 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.info('[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)) - self.logger.info('[execute] BACKEND_URL: {:s}'.format(str(BACKEND_URL))) + self.logger.debug('[execute] BACKEND_URL: {:s}'.format(str(BACKEND_URL))) reply = requests.post(BACKEND_URL, json=request) self.status_code = reply.status_code self.raw_reply = reply.content.decode('UTF-8') - self.logger.info('[execute] status_code={:s} reply={:s}'.format(str(reply.status_code), str(self.raw_reply))) + self.logger.debug('[execute] status_code={:s} reply={:s}'.format(str(reply.status_code), str(self.raw_reply))) if dump_reply_filename is not None: with open(dump_reply_filename, 'w', encoding='UTF-8') as f: f.write('status_code={:s} reply={:s}'.format(str(self.status_code), str(self.raw_reply))) - if reply.status_code not in {requests.codes.ok}: + if reply.status_code not in {requests.codes.ok}: # pylint: disable=no-member raise Exception('Backend error({:s}) for request({:s})'.format( str(self.raw_reply), json.dumps(request, sort_keys=True))) 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))) - json_config_rule = json_config_rule_set('/service[{:s}]'.format(service_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, 'tp_id_src' : tp_id_src, @@ -85,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))) @@ -95,25 +90,33 @@ class MicrowaveServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def DeleteEndpoint( self, endpoints : List[Tuple[str, str, Optional[str]]], connection_uuid : Optional[str] = None ) -> List[Union[bool, Exception]]: - 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) != 2: raise Exception('len(endpoints) != 2') - - 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))) @@ -121,6 +124,7 @@ class MicrowaveServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('constraints', constraints, list) if len(constraints) == 0: return [] @@ -129,6 +133,7 @@ class MicrowaveServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('constraints', constraints, list) if len(constraints) == 0: return [] @@ -137,6 +142,7 @@ class MicrowaveServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] @@ -144,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))) @@ -154,6 +159,7 @@ class MicrowaveServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] @@ -161,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 f94948129f23c1aff3a3db3dbb4c236ae161e5e1..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,53 +12,41 @@ # 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.proto.context_pb2 import ConfigActionEnum, ConfigRule, DeviceId, Service +from common.method_wrappers.Decorator import MetricsPool, metered_subclass_method +from common.proto.context_pb2 import ConfigRule, DeviceId, Service from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set from common.tools.object_factory.Device import json_device_id from common.type_checkers.Checkers import chk_type +from service.service.service_handler_api.Tools import get_device_endpoint_uuids, get_endpoint_matching from service.service.service_handler_api._ServiceHandler import _ServiceHandler -from service.service.service_handler_api.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__) +METRICS_POOL = MetricsPool('Service', 'Handler', labels={'handler': 'tapi_tapi'}) + class TapiServiceHandler(_ServiceHandler): def __init__( # pylint: disable=super-init-not-called self, service : Service, task_executor : TaskExecutor, **settings ) -> None: self.__service = service - self.__task_executor = task_executor # 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') @@ -67,46 +55,64 @@ 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 + @metered_subclass_method(METRICS_POOL) 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))) @@ -114,6 +120,7 @@ class TapiServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def SetConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('constraints', constraints, list) if len(constraints) == 0: return [] @@ -122,6 +129,7 @@ class TapiServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def DeleteConstraint(self, constraints : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('constraints', constraints, list) if len(constraints) == 0: return [] @@ -130,6 +138,7 @@ class TapiServiceHandler(_ServiceHandler): LOGGER.warning(msg.format(str(constraints))) return [True for _ in range(len(constraints))] + @metered_subclass_method(METRICS_POOL) def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] @@ -137,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))) @@ -147,6 +155,7 @@ class TapiServiceHandler(_ServiceHandler): return results + @metered_subclass_method(METRICS_POOL) def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]: chk_type('resources', resources, list) if len(resources) == 0: return [] @@ -154,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 757a660590dde1b3fb2eee7090b2329cd45ec8cb..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. @@ -14,8 +14,8 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Dict, Optional, Union +from common.method_wrappers.ServiceExceptions import NotFoundException from common.proto.context_pb2 import Connection, ConnectionId, Device, DeviceId, Service, ServiceId -from common.rpc_method_wrapper.ServiceExceptions import NotFoundException from context.client.ContextClient import ContextClient from device.client.DeviceClient import DeviceClient from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory, get_service_handler_class 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 beb7e5a0426b7705dbf780d8305a587a3d4fec14..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. @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from common.method_wrappers.ServiceExceptions import OperationFailedException from common.proto.context_pb2 import ConnectionId -from common.rpc_method_wrapper.ServiceExceptions import OperationFailedException from common.tools.grpc.Tools import grpc_message_to_json_string from service.service.service_handler_api.Tools import check_errors_setendpoint from service.service.task_scheduler.TaskExecutor import TaskExecutor diff --git a/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py b/src/service/service/task_scheduler/tasks/Task_ConnectionDeconfigure.py index c04d950a8993166c3bbfab3c083d4f2898dcd3e8..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. @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from common.method_wrappers.ServiceExceptions import OperationFailedException from common.proto.context_pb2 import ConnectionId -from common.rpc_method_wrapper.ServiceExceptions import OperationFailedException from common.tools.grpc.Tools import grpc_message_to_json_string from service.service.service_handler_api.Tools import check_errors_deleteendpoint from service.service.task_scheduler.TaskExecutor import TaskExecutor 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 ada7218588391766147a02f9713b540016522aa7..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.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method +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 @@ -29,9 +31,7 @@ from service.client.ServiceClient import ServiceClient LOGGER = logging.getLogger(__name__) -SERVICE_NAME = 'Slice' -METHOD_NAMES = ['CreateSlice', 'UpdateSlice', 'DeleteSlice'] -METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES) +METRICS_POOL = MetricsPool('Slice', 'RPC') class SliceServiceServicerImpl(SliceServiceServicer): def __init__(self): @@ -39,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) @@ -69,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_) @@ -82,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: @@ -94,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) @@ -139,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() @@ -158,7 +156,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): context_client.SetSlice(slice_active) return slice_id - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: #try: # slice_ = context_client.GetSlice(request.slice_id) @@ -168,7 +166,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): #return slice_id return self.create_update(request) - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: #slice_id = context_client.SetSlice(request) #if len(request.slice_endpoint_ids) != 2: return slice_id @@ -186,7 +184,7 @@ class SliceServiceServicerImpl(SliceServiceServicer): # raise NotImplementedError('Slice should create local services for single domain slice') return self.create_update(request) - @safe_and_metered_rpc_method(METRICS, LOGGER) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty: context_client = ContextClient() try: @@ -201,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/Credentials.py b/src/tests/ecoc22/tests/Credentials.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 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_scenario/README.md b/src/tests/tools/load_scenario/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3845cbf01dda4385c431a3b52d381360e6dc5e9f --- /dev/null +++ b/src/tests/tools/load_scenario/README.md @@ -0,0 +1,17 @@ +# Tool: Load Scenario: + +Simple tool to populate ETSI TeraFlowSDN controller with same descriptors that can be loaded through the WebUI. + +## Example: + +Deploy TeraFlowSDN controller with your specific settings: +```(bash) +cd ~/tfs-ctrl +source my_deploy.sh +./deploy.sh +``` + +Populate TeraFlowSDN controller with your descriptor file: +```(bash) +./src/tests/tools/load_scenario/run.sh src/tests/tools/load_scenario/example_descriptors.json +``` diff --git a/src/tests/tools/load_scenario/__init__.py b/src/tests/tools/load_scenario/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612 --- /dev/null +++ b/src/tests/tools/load_scenario/__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_scenario/__main__.py b/src/tests/tools/load_scenario/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..3559f778d7cf850c3bbb4f2d516f45f18423d28c --- /dev/null +++ b/src/tests/tools/load_scenario/__main__.py @@ -0,0 +1,37 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging, sys +from common.tests.LoadScenario import load_scenario_from_descriptor +from context.client.ContextClient import ContextClient +from device.client.DeviceClient import DeviceClient +from service.client.ServiceClient import ServiceClient +from slice.client.SliceClient import SliceClient + +logging.basicConfig(level=logging.INFO) +LOGGER = logging.getLogger(__name__) + +def main(): + context_client = ContextClient() + device_client = DeviceClient() + service_client = ServiceClient() + slice_client = SliceClient() + + LOGGER.info('Loading scenario...') + load_scenario_from_descriptor(sys.argv[1], context_client, device_client, service_client, slice_client) + LOGGER.info('Done!') + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/tests/tools/load_scenario/example_descriptors.json b/src/tests/tools/load_scenario/example_descriptors.json new file mode 100644 index 0000000000000000000000000000000000000000..5fb0c086749cab3343277c28a902b3db48651320 --- /dev/null +++ b/src/tests/tools/load_scenario/example_descriptors.json @@ -0,0 +1,229 @@ +{ + "contexts": [ + { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_ids": [], "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_uuid": {"uuid": "admin"} + }, + "device_ids": [ + {"device_uuid": {"uuid": "R1"}}, + {"device_uuid": {"uuid": "R2"}}, + {"device_uuid": {"uuid": "R3"}}, + {"device_uuid": {"uuid": "R4"}}, + {"device_uuid": {"uuid": "R5"}}, + {"device_uuid": {"uuid": "R6"}}, + {"device_uuid": {"uuid": "R7"}} + ], + "link_ids": [ + {"link_uuid": {"uuid": "R1==R2"}}, + {"link_uuid": {"uuid": "R2==R3"}}, + {"link_uuid": {"uuid": "R3==R4"}}, + {"link_uuid": {"uuid": "R4==R5"}}, + {"link_uuid": {"uuid": "R5==R6"}}, + {"link_uuid": {"uuid": "R6==R1"}}, + {"link_uuid": {"uuid": "R1==R7"}}, + {"link_uuid": {"uuid": "R3==R7"}}, + {"link_uuid": {"uuid": "R5==R7"}} + ] + } + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R3"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R4"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R5"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R6"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "1/4"}, + {"sample_types": [], "type": "copper", "uuid": "1/5"}, + {"sample_types": [], "type": "copper", "uuid": "1/6"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "R7"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 1, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper", "uuid": "1/1"}, + {"sample_types": [], "type": "copper", "uuid": "1/2"}, + {"sample_types": [], "type": "copper", "uuid": "1/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/1"}, + {"sample_types": [], "type": "copper", "uuid": "2/2"}, + {"sample_types": [], "type": "copper", "uuid": "2/3"}, + {"sample_types": [], "type": "copper", "uuid": "2/4"}, + {"sample_types": [], "type": "copper", "uuid": "2/5"}, + {"sample_types": [], "type": "copper", "uuid": "2/6"} + ]}}} + ]} + } + ], + "links": [ + { + "link_id": {"link_uuid": {"uuid": "R1==R2"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R2==R3"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R3==R4"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R4==R5"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R5==R6"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R6==R1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R6"}}, "endpoint_uuid": {"uuid": "2/1"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/2"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R1==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/1"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R3==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/3"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "R5==R7"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R5"}}, "endpoint_uuid": {"uuid": "2/3"}}, + {"device_id": {"device_uuid": {"uuid": "R7"}}, "endpoint_uuid": {"uuid": "2/5"}} + ] + } + ] +} \ No newline at end of file diff --git a/src/tests/tools/load_scenario/run.sh b/src/tests/tools/load_scenario/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..98ebc6c1790ae256c592408ff731e347ec8ebb0e --- /dev/null +++ b/src/tests/tools/load_scenario/run.sh @@ -0,0 +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. + +source tfs_runtime_env_vars.sh +python -m tests.tools.load_scenario $1 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 }} + +