From b4b217029b981702d6cccddf9fe1a22f7e4909ed Mon Sep 17 00:00:00 2001 From: mansoca Date: Wed, 27 Mar 2024 11:45:39 +0000 Subject: [PATCH 01/13] Creation VTNManager service --- my_deploy.sh | 3 + src/vnt_manager/.gitlab-ci.yml | 38 ++++++++ src/vnt_manager/Config.py | 13 +++ src/vnt_manager/Dockerfile | 84 ++++++++++++++++ src/vnt_manager/__init__.py | 13 +++ src/vnt_manager/client/VNTManagerClient.py | 71 ++++++++++++++ src/vnt_manager/client/__init__.py | 13 +++ src/vnt_manager/requirements.in | 15 +++ src/vnt_manager/service/VNTManagerService.py | 35 +++++++ .../service/VNTManagerServiceServicerImpl.py | 95 +++++++++++++++++++ src/vnt_manager/service/__init__.py | 13 +++ src/vnt_manager/service/__main__.py | 80 ++++++++++++++++ 12 files changed, 473 insertions(+) create mode 100644 src/vnt_manager/.gitlab-ci.yml create mode 100644 src/vnt_manager/Config.py create mode 100644 src/vnt_manager/Dockerfile create mode 100644 src/vnt_manager/__init__.py create mode 100644 src/vnt_manager/client/VNTManagerClient.py create mode 100644 src/vnt_manager/client/__init__.py create mode 100644 src/vnt_manager/requirements.in create mode 100644 src/vnt_manager/service/VNTManagerService.py create mode 100644 src/vnt_manager/service/VNTManagerServiceServicerImpl.py create mode 100644 src/vnt_manager/service/__init__.py create mode 100644 src/vnt_manager/service/__main__.py diff --git a/my_deploy.sh b/my_deploy.sh index 7dd5e5c3e..212dd7bd6 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -52,6 +52,9 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_gene # Uncomment to activate E2E Orchestrator #export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" +# Uncomment to activate VNT Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" + # Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" diff --git a/src/vnt_manager/.gitlab-ci.yml b/src/vnt_manager/.gitlab-ci.yml new file mode 100644 index 000000000..d1b9da495 --- /dev/null +++ b/src/vnt_manager/.gitlab-ci.yml @@ -0,0 +1,38 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# build, tag and push the Docker image to the gitlab registry +build vntmanager: + variables: + IMAGE_NAME: 'vntmanager' # name of the microservice + IMAGE_TAG: 'latest' # tag of the container image (production, development, etc) + stage: build + before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + script: + - docker buildx build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile . + - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" + - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" + after_script: + - docker images --filter="dangling=true" --quiet | xargs -r docker rmi + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)' + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' + - changes: + - src/$IMAGE_NAME/**/*.{py,in,yml} + - src/$IMAGE_NAME/Dockerfile + - src/$IMAGE_NAME/tests/*.py + - src/$IMAGE_NAME/tests/Dockerfile + - manifests/${IMAGE_NAME}service.yaml + - .gitlab-ci.yml diff --git a/src/vnt_manager/Config.py b/src/vnt_manager/Config.py new file mode 100644 index 000000000..38d04994f --- /dev/null +++ b/src/vnt_manager/Config.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/vnt_manager/Dockerfile b/src/vnt_manager/Dockerfile new file mode 100644 index 000000000..8f40741ee --- /dev/null +++ b/src/vnt_manager/Dockerfile @@ -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. + +FROM python:3.9-slim + +# Install dependencies +RUN apt-get --yes --quiet --quiet update && \ + apt-get --yes --quiet --quiet install wget g++ && \ + rm -rf /var/lib/apt/lists/* + +# Set Python to show logs as they occur +ENV PYTHONUNBUFFERED=0 +ENV PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + +# Download the gRPC health probe +RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \ + wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \ + chmod +x /bin/grpc_health_probe + +# Creating a user for security reasons +RUN groupadd -r teraflow && useradd -u 1001 --no-log-init -r -m -g teraflow teraflow +USER teraflow + +# set working directory +RUN mkdir -p /home/teraflow/controller/common/ +WORKDIR /home/teraflow/controller + +# Get Python packages per module +ENV VIRTUAL_ENV=/home/teraflow/venv +RUN python3 -m venv ${VIRTUAL_ENV} +ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" + +# Get generic Python packages +RUN python3 -m pip install --upgrade pip +RUN python3 -m pip install --upgrade setuptools wheel +RUN python3 -m pip install --upgrade pip-tools + +# Get common Python packages +# Note: this step enables sharing the previous Docker build steps among all the Python components +COPY --chown=teraflow:teraflow common_requirements.in common_requirements.in +RUN pip-compile --quiet --output-file=common_requirements.txt common_requirements.in +RUN python3 -m pip install -r common_requirements.txt + +# Add common files into working directory +WORKDIR /home/teraflow/controller/common +COPY --chown=teraflow:teraflow src/common/. ./ +RUN rm -rf proto + +# Create proto sub-folder, copy .proto files, and generate Python code +RUN mkdir -p /home/teraflow/controller/common/proto +WORKDIR /home/teraflow/controller/common/proto +RUN touch __init__.py +COPY --chown=teraflow:teraflow proto/*.proto ./ +RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto +RUN rm *.proto +RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \; + +# Create module sub-folders +RUN mkdir -p /home/teraflow/controller/vnt_manager +WORKDIR /home/teraflow/controller + +# Get Python packages per module +COPY --chown=teraflow:teraflow ./src/vnt_manager/requirements.in vnt_manager/requirements.in +# consider common and specific requirements to avoid inconsistencies with dependencies +RUN pip-compile --quiet --output-file=vnt_manager/requirements.txt vnt_manager/requirements.in common_requirements.in +RUN python3 -m pip install -r vnt_manager/requirements.txt + +# Add component files into working directory +COPY --chown=teraflow:teraflow ./src/context/. context +COPY --chown=teraflow:teraflow ./src/vnt_manager/. vnt_manager + +# Start the service +ENTRYPOINT ["python", "-m", "vnt_manager.service"] diff --git a/src/vnt_manager/__init__.py b/src/vnt_manager/__init__.py new file mode 100644 index 000000000..38d04994f --- /dev/null +++ b/src/vnt_manager/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/vnt_manager/client/VNTManagerClient.py b/src/vnt_manager/client/VNTManagerClient.py new file mode 100644 index 000000000..95db3b6da --- /dev/null +++ b/src/vnt_manager/client/VNTManagerClient.py @@ -0,0 +1,71 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +import grpc + +from common.Constants import ServiceNameEnum +from common.proto.context_pb2 import Empty +from common.proto.vntmanager_pb2_grpc import VNTManagerServiceStub +from common.Settings import get_service_host, get_service_port_grpc +from common.tools.client.RetryDecorator import delay_exponential, retry +from common.tools.grpc.Tools import grpc_message_to_json +# from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply + +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 VNTManagerClient: + def __init__(self, host=None, port=None): + if not host: + host = get_service_host(ServiceNameEnum.VNTMANAGER) + if not port: + port = get_service_port_grpc(ServiceNameEnum.VNTMANAGER) + self.endpoint = "{:s}:{:s}".format(str(host), str(port)) + LOGGER.debug("Creating channel to {:s}...".format(str(self.endpoint))) + self.channel = None + self.stub = None + self.connect() + LOGGER.debug("Channel created") + + def connect(self): + self.channel = grpc.insecure_channel(self.endpoint) + self.stub = VNTManagerServiceStub(self.channel) + + def close(self): + if self.channel is not None: + self.channel.close() + self.channel = None + self.stub = None + + """ + @RETRY_DECORATOR + def Compute(self, request: E2EOrchestratorRequest) -> E2EOrchestratorReply: + LOGGER.info( + "Compute request: {:s}".format(str(grpc_message_to_json(request))) + ) + response = self.stub.Compute(request) + LOGGER.info( + "Compute result: {:s}".format(str(grpc_message_to_json(response))) + ) + return response + """ \ No newline at end of file diff --git a/src/vnt_manager/client/__init__.py b/src/vnt_manager/client/__init__.py new file mode 100644 index 000000000..38d04994f --- /dev/null +++ b/src/vnt_manager/client/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/vnt_manager/requirements.in b/src/vnt_manager/requirements.in new file mode 100644 index 000000000..4c4720a2d --- /dev/null +++ b/src/vnt_manager/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. + +networkx \ No newline at end of file diff --git a/src/vnt_manager/service/VNTManagerService.py b/src/vnt_manager/service/VNTManagerService.py new file mode 100644 index 000000000..b61b213a6 --- /dev/null +++ b/src/vnt_manager/service/VNTManagerService.py @@ -0,0 +1,35 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from common.Constants import ServiceNameEnum +from common.proto.vntmanager_pb2_grpc import add_VNTManagerServiceServicer_to_server +from common.Settings import get_service_port_grpc +from common.tools.service.GenericGrpcService import GenericGrpcService +from .VNTManagerServiceServicerImpl import VNTManagerServiceServicerImpl + +LOGGER = logging.getLogger(__name__) + + +class VNTManagerService(GenericGrpcService): + def __init__(self, cls_name: str = __name__): + port = get_service_port_grpc(ServiceNameEnum.VNTMANAGER) + super().__init__(port, cls_name=cls_name) + self.vntmanager_servicer = VNTManagerServiceServicerImpl() + + def install_servicers(self): + add_VNTManagerServiceServicer_to_server( + self.vntmanager_servicer, self.server + ) diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py new file mode 100644 index 000000000..4869218a7 --- /dev/null +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -0,0 +1,95 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +import networkx as nx +import grpc +import copy + +from common.Constants import ServiceNameEnum +from common.method_wrappers.Decorator import (MetricsPool, MetricTypeEnum, safe_and_metered_rpc_method) +from common.proto.vntmanager_pb2 import VNTManagerRequest, VNTManagerReply +from common.proto.context_pb2 import Empty, Connection, EndPointId +from common.proto.vntmanager_pb2_grpc import VNTManagerServiceServicer +from context.client.ContextClient import ContextClient +from context.service.database.uuids.EndPoint import endpoint_get_uuid + + +LOGGER = logging.getLogger(__name__) + +METRICS_POOL = MetricsPool("VNTManager", "RPC") + +context_client: ContextClient = ContextClient() + + +class E2EOrchestratorServiceServicerImpl(VNTManagerServiceServicer): + def __init__(self): + LOGGER.debug("Creating Servicer...") + LOGGER.debug("Servicer Created") + + """ + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def Compute(self, request: E2EOrchestratorRequest, context: grpc.ServicerContext) -> E2EOrchestratorReply: + endpoints_ids = [] + for endpoint_id in request.service.service_endpoint_ids: + endpoints_ids.append(endpoint_get_uuid(endpoint_id)[2]) + + graph = nx.Graph() + + devices = context_client.ListDevices(Empty()).devices + + for device in devices: + endpoints_uuids = [endpoint.endpoint_id.endpoint_uuid.uuid + for endpoint in device.device_endpoints] + for ep in endpoints_uuids: + graph.add_node(ep) + + for ep in endpoints_uuids: + for ep_i in endpoints_uuids: + if ep == ep_i: + continue + graph.add_edge(ep, ep_i) + + links = context_client.ListLinks(Empty()).links + for link in links: + eps = [] + for endpoint_id in link.link_endpoint_ids: + eps.append(endpoint_id.endpoint_uuid.uuid) + graph.add_edge(eps[0], eps[1]) + + + shortest = nx.shortest_path(graph, endpoints_ids[0], endpoints_ids[1]) + + path = E2EOrchestratorReply() + path.services.append(copy.deepcopy(request.service)) + for i in range(0, int(len(shortest)/2)): + conn = Connection() + ep_a_uuid = str(shortest[i*2]) + ep_z_uuid = str(shortest[i*2+1]) + + conn.connection_id.connection_uuid.uuid = str(ep_a_uuid) + '_->_' + str(ep_z_uuid) + + ep_a_id = EndPointId() + ep_a_id.endpoint_uuid.uuid = ep_a_uuid + conn.path_hops_endpoint_ids.append(ep_a_id) + + ep_z_id = EndPointId() + ep_z_id.endpoint_uuid.uuid = ep_z_uuid + conn.path_hops_endpoint_ids.append(ep_z_id) + + path.connections.append(conn) + + return path + """ \ No newline at end of file diff --git a/src/vnt_manager/service/__init__.py b/src/vnt_manager/service/__init__.py new file mode 100644 index 000000000..38d04994f --- /dev/null +++ b/src/vnt_manager/service/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/vnt_manager/service/__main__.py b/src/vnt_manager/service/__main__.py new file mode 100644 index 000000000..03fb4dd5d --- /dev/null +++ b/src/vnt_manager/service/__main__.py @@ -0,0 +1,80 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import signal +import sys +import threading + +from prometheus_client import start_http_server + +from common.Constants import ServiceNameEnum +from common.Settings import (ENVVAR_SUFIX_SERVICE_HOST, + ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, + get_log_level, get_metrics_port, + wait_for_environment_variables) + +from .VNTManagerService import VNTManagerService + +terminate = threading.Event() +LOGGER = None + + +def signal_handler(signal, frame): # pylint: disable=redefined-outer-name + LOGGER.warning("Terminate signal received") + terminate.set() + + +def main(): + global LOGGER # pylint: disable=global-statement + + log_level = get_log_level() + logging.basicConfig(level=log_level) + LOGGER = logging.getLogger(__name__) + + wait_for_environment_variables( + [ + get_env_var_name(ServiceNameEnum.VNTMANAGER, ENVVAR_SUFIX_SERVICE_HOST), + get_env_var_name(ServiceNameEnum.VNTMANAGER, ENVVAR_SUFIX_SERVICE_PORT_GRPC), + ] + ) + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + + LOGGER.info("Starting...") + + # Start metrics server + metrics_port = get_metrics_port() + start_http_server(metrics_port) + + # Starting CentralizedCybersecurity service + grpc_service = VNTManagerService() + grpc_service.start() + LOGGER.info("Started...") + # Wait for Ctrl+C or termination signal + + while not terminate.wait(timeout=1): + pass + + + LOGGER.info("Terminating...") + grpc_service.stop() + + LOGGER.info("Bye") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) -- GitLab From bfb879d37dd5f9e0d7a8d60de45021099878cd1a Mon Sep 17 00:00:00 2001 From: mansoca Date: Thu, 28 Mar 2024 14:36:30 +0000 Subject: [PATCH 02/13] ecoc2024 --- manifests/vnt_managerservice.yaml | 91 +++++++++++ scripts/show_logs_vntmanager.sh | 27 ++++ src/common/Constants.py | 4 +- src/tests/ecoc24/.gitignore | 2 + src/tests/ecoc24/__init__.py | 14 ++ src/tests/ecoc24/delete.sh | 22 +++ src/tests/ecoc24/deploy.sh | 36 +++++ src/tests/ecoc24/deploy_e2e.sh | 29 ++++ src/tests/ecoc24/deploy_ip.sh | 29 ++++ src/tests/ecoc24/deploy_specs_e2e.sh | 151 +++++++++++++++++ src/tests/ecoc24/deploy_specs_ip.sh | 153 ++++++++++++++++++ src/tests/ecoc24/dump_logs.sh | 39 +++++ src/tests/ecoc24/fast_redeploy.sh | 67 ++++++++ .../ecoc24/nginx-ingress-controller-e2e.yaml | 134 +++++++++++++++ .../ecoc24/nginx-ingress-controller-ip.yaml | 134 +++++++++++++++ src/tests/ecoc24/show_deploy.sh | 34 ++++ src/tests/ecoc24/tfs-ingress-e2e.yaml | 53 ++++++ src/tests/ecoc24/tfs-ingress-ip.yaml | 53 ++++++ 18 files changed, 1071 insertions(+), 1 deletion(-) create mode 100644 manifests/vnt_managerservice.yaml create mode 100644 scripts/show_logs_vntmanager.sh create mode 100644 src/tests/ecoc24/.gitignore create mode 100644 src/tests/ecoc24/__init__.py create mode 100755 src/tests/ecoc24/delete.sh create mode 100755 src/tests/ecoc24/deploy.sh create mode 100755 src/tests/ecoc24/deploy_e2e.sh create mode 100755 src/tests/ecoc24/deploy_ip.sh create mode 100755 src/tests/ecoc24/deploy_specs_e2e.sh create mode 100755 src/tests/ecoc24/deploy_specs_ip.sh create mode 100755 src/tests/ecoc24/dump_logs.sh create mode 100755 src/tests/ecoc24/fast_redeploy.sh create mode 100644 src/tests/ecoc24/nginx-ingress-controller-e2e.yaml create mode 100644 src/tests/ecoc24/nginx-ingress-controller-ip.yaml create mode 100755 src/tests/ecoc24/show_deploy.sh create mode 100644 src/tests/ecoc24/tfs-ingress-e2e.yaml create mode 100644 src/tests/ecoc24/tfs-ingress-ip.yaml diff --git a/manifests/vnt_managerservice.yaml b/manifests/vnt_managerservice.yaml new file mode 100644 index 000000000..95070564b --- /dev/null +++ b/manifests/vnt_managerservice.yaml @@ -0,0 +1,91 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vnt-managerservice +spec: + selector: + matchLabels: + app: vnt-managerservice + template: + metadata: + labels: + app: vnt-managerservice + spec: + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: labs.etsi.org:5050/tfs/controller/vnt_manager:latest + imagePullPolicy: Always + ports: + - containerPort: 10070 + - containerPort: 9192 + env: + - name: LOG_LEVEL + value: "INFO" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10070"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:10070"] + resources: + requests: + cpu: 150m + memory: 128Mi + limits: + cpu: 1000m + memory: 1024Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: vnt-managerservice + labels: + app: vnt-managerservice +spec: + type: ClusterIP + selector: + app: vnt-managerservice + ports: + - name: grpc + port: 10070 + targetPort: 10070 + - name: metrics + port: 9192 + targetPort: 9192 +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: vnt-managerservice-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: vnt-managerservice + minReplicas: 1 + maxReplicas: 20 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 80 + #behavior: + # scaleDown: + # stabilizationWindowSeconds: 30 diff --git a/scripts/show_logs_vntmanager.sh b/scripts/show_logs_vntmanager.sh new file mode 100644 index 000000000..15469e647 --- /dev/null +++ b/scripts/show_logs_vntmanager.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +######################################################################################################################## +# Define your deployment settings here +######################################################################################################################## + +# If not already set, set the name of the Kubernetes namespace to deploy to. +export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/vntmanagerservice -c server diff --git a/src/common/Constants.py b/src/common/Constants.py index a1913a951..276603463 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -58,8 +58,9 @@ class ServiceNameEnum(Enum): CACHING = 'caching' TE = 'te' FORECASTER = 'forecaster' - E2EORCHESTRATOR = 'e2eorchestrator' + E2EORCHESTRATOR = 'e2e_orchestrator' OPTICALCONTROLLER = 'opticalcontroller' + VNTMANAGER = 'vnt_manager' BGPLS = 'bgpls-speaker' # Used for test and debugging only @@ -89,6 +90,7 @@ DEFAULT_SERVICE_GRPC_PORTS = { ServiceNameEnum.FORECASTER .value : 10040, ServiceNameEnum.E2EORCHESTRATOR .value : 10050, ServiceNameEnum.OPTICALCONTROLLER .value : 10060, + ServiceNameEnum.VNTMANAGER .value : 10070, ServiceNameEnum.BGPLS .value : 20030, # Used for test and debugging only diff --git a/src/tests/ecoc24/.gitignore b/src/tests/ecoc24/.gitignore new file mode 100644 index 000000000..0a3f4400d --- /dev/null +++ b/src/tests/ecoc24/.gitignore @@ -0,0 +1,2 @@ +# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. +descriptors_real.json diff --git a/src/tests/ecoc24/__init__.py b/src/tests/ecoc24/__init__.py new file mode 100644 index 000000000..1549d9811 --- /dev/null +++ b/src/tests/ecoc24/__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/ecoc24/delete.sh b/src/tests/ecoc24/delete.sh new file mode 100755 index 000000000..3acd872a3 --- /dev/null +++ b/src/tests/ecoc24/delete.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Delete old namespaces +kubectl delete namespace tfs-e2e tfs-ip + +# Delete secondary ingress controllers +kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml +kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml diff --git a/src/tests/ecoc24/deploy.sh b/src/tests/ecoc24/deploy.sh new file mode 100755 index 000000000..153e98b1a --- /dev/null +++ b/src/tests/ecoc24/deploy.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Delete old namespaces +kubectl delete namespace tfs-e2e tfs-ip + +# Delete secondary ingress controllers +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml + +# Create secondary ingress controllers +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml + +# Deploy TFS for e2e +source src/tests/ecoc24/deploy_specs_e2e.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh + +# Deploy TFS for ip +source src/tests/ecoc24/deploy_specs_ip.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_ip.sh diff --git a/src/tests/ecoc24/deploy_e2e.sh b/src/tests/ecoc24/deploy_e2e.sh new file mode 100755 index 000000000..7f1bfe945 --- /dev/null +++ b/src/tests/ecoc24/deploy_e2e.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Delete old namespaces +kubectl delete namespace tfs-e2e + +# Delete secondary ingress controllers +kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml + +# Create secondary ingress controllers +kubectl apply -f ecoc24/nginx-ingress-controller-e2e.yaml + +# Deploy TFS for E2E +source ecoc24/deploy_specs_e2e.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh diff --git a/src/tests/ecoc24/deploy_ip.sh b/src/tests/ecoc24/deploy_ip.sh new file mode 100755 index 000000000..5d14f2b07 --- /dev/null +++ b/src/tests/ecoc24/deploy_ip.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Delete old namespaces +kubectl delete namespace tfs-ip + +# Delete secondary ingress controllers +kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml + +# Create secondary ingress controllers +kubectl apply -f ecoc24/nginx-ingress-controller-ip.yaml + +# Deploy TFS for ip +source ecoc24/deploy_specs_ip.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_ip.sh diff --git a/src/tests/ecoc24/deploy_specs_e2e.sh b/src/tests/ecoc24/deploy_specs_e2e.sh new file mode 100755 index 000000000..1d9a6228b --- /dev/null +++ b/src/tests/ecoc24/deploy_specs_e2e.sh @@ -0,0 +1,151 @@ +#!/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 pathcomp service slice nbi webui load_generator" +export TFS_COMPONENTS="context device pathcomp service nbi webui" + +# Uncomment to activate Monitoring +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" + +# Uncomment to activate ZTP and Policy Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp policy" + +# Uncomment to activate Optical CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" + +# Uncomment to activate L3 CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" + +# Uncomment to activate TE +#export TFS_COMPONENTS="${TFS_COMPONENTS} te" + +# Uncomment to activate E2E Orchestrator +export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" + +# Set the tag you want to use for your images. +export TFS_IMAGE_TAG="dev" + +# Set the name of the Kubernetes namespace to deploy TFS to. +export TFS_K8S_NAMESPACE="tfs-e2e" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="src/testsecoc24/tfs-ingress-e2e.yaml" + +# Uncomment to monitor performance of components +export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" + +# Uncomment when deploying Optical CyberSecurity +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" + +# Set the new Grafana admin password +export TFS_GRAFANA_PASSWORD="admin123+" + +# Disable skip-build flag to rebuild the Docker images. +export TFS_SKIP_BUILD="" + + +# ----- CockroachDB ------------------------------------------------------------ + +# Set the namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE="crdb" + +# Set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL="26257" + +# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP="8081" + +# Set the database username to be used by Context. +export CRDB_USERNAME="tfs" + +# Set the database user's password to be used by Context. +export CRDB_PASSWORD="tfs123" + +# Set the database name to be used by Context. +export CRDB_DATABASE="tfs_e2e" + +# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing. +# See ./deploy/all.sh or ./deploy/crdb.sh for additional details +export CRDB_DEPLOY_MODE="single" + +# Disable flag for dropping database, if it exists. +export CRDB_DROP_DATABASE_IF_EXISTS="YES" + +# Disable flag for re-deploying CockroachDB from scratch. +export CRDB_REDEPLOY="" + + +# ----- NATS ------------------------------------------------------------------- + +# Set the namespace where NATS will be deployed. +export NATS_NAMESPACE="nats-e2e" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4223" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8223" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-e2e" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8813" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9011" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9001" + +# Set the database username to be used for QuestDB. +export QDB_USERNAME="admin" + +# Set the database user's password to be used for QuestDB. +export QDB_PASSWORD="quest" + +# Set the table name to be used by Monitoring for KPIs. +export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis" + +# Set the table name to be used by Slice for plotting groups. +export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups" + +# Disable flag for dropping tables if they exist. +export QDB_DROP_TABLES_IF_EXIST="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" + + +# ----- K8s Observability ------------------------------------------------------ + +# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP="9090" + +# Set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP="3000" diff --git a/src/tests/ecoc24/deploy_specs_ip.sh b/src/tests/ecoc24/deploy_specs_ip.sh new file mode 100755 index 000000000..256e6e8e2 --- /dev/null +++ b/src/tests/ecoc24/deploy_specs_ip.sh @@ -0,0 +1,153 @@ +#!/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 pathcomp service slice nbi webui load_generator" +export TFS_COMPONENTS="context device pathcomp service nbi webui " + + +# Uncomment to activate Monitoring +#export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" + +# Uncomment to activate ZTP and Policy Manager +#export TFS_COMPONENTS="${TFS_COMPONENTS} ztp policy" + +# Uncomment to activate Optical CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} dbscanserving opticalattackmitigator opticalattackdetector opticalattackmanager" + +# Uncomment to activate L3 CyberSecurity +#export TFS_COMPONENTS="${TFS_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector" + +# Uncomment to activate TE +#export TFS_COMPONENTS="${TFS_COMPONENTS} te" + +# Uncomment to activate VNT Manager +export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" + + +# Set the tag you want to use for your images. +export TFS_IMAGE_TAG="dev" + +# Set the name of the Kubernetes namespace to deploy TFS to. +export TFS_K8S_NAMESPACE="tfs-ip" + +# Set additional manifest files to be applied after the deployment +export TFS_EXTRA_MANIFESTS="src/tests/ecoc24/tfs-ingress-ip.yaml" + +# Uncomment to monitor performance of components +export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" + +# Uncomment when deploying Optical CyberSecurity +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" + +# Set the new Grafana admin password +export TFS_GRAFANA_PASSWORD="admin123+" + +# Disable skip-build flag to rebuild the Docker images. +export TFS_SKIP_BUILD="YES" + + +# ----- CockroachDB ------------------------------------------------------------ + +# Set the namespace where CockroackDB will be deployed. +export CRDB_NAMESPACE="crdb" + +# Set the external port CockroackDB Postgre SQL interface will be exposed to. +export CRDB_EXT_PORT_SQL="26257" + +# Set the external port CockroackDB HTTP Mgmt GUI interface will be exposed to. +export CRDB_EXT_PORT_HTTP="8081" + +# Set the database username to be used by Context. +export CRDB_USERNAME="tfs" + +# Set the database user's password to be used by Context. +export CRDB_PASSWORD="tfs123" + +# Set the database name to be used by Context. +export CRDB_DATABASE="tfs_ip" + +# Set CockroachDB installation mode to 'single'. This option is convenient for development and testing. +# See ./deploy/all.sh or ./deploy/crdb.sh for additional details +export CRDB_DEPLOY_MODE="single" + +# Disable flag for dropping database, if it exists. +export CRDB_DROP_DATABASE_IF_EXISTS="YES" + +# Disable flag for re-deploying CockroachDB from scratch. +export CRDB_REDEPLOY="" + + +# ----- NATS ------------------------------------------------------------------- + +# Set the namespace where NATS will be deployed. +export NATS_NAMESPACE="nats-ip" + +# Set the external port NATS Client interface will be exposed to. +export NATS_EXT_PORT_CLIENT="4224" + +# Set the external port NATS HTTP Mgmt GUI interface will be exposed to. +export NATS_EXT_PORT_HTTP="8224" + +# Disable flag for re-deploying NATS from scratch. +export NATS_REDEPLOY="" + + +# ----- QuestDB ---------------------------------------------------------------- + +# Set the namespace where QuestDB will be deployed. +export QDB_NAMESPACE="qdb-ip" + +# Set the external port QuestDB Postgre SQL interface will be exposed to. +export QDB_EXT_PORT_SQL="8814" + +# Set the external port QuestDB Influx Line Protocol interface will be exposed to. +export QDB_EXT_PORT_ILP="9012" + +# Set the external port QuestDB HTTP Mgmt GUI interface will be exposed to. +export QDB_EXT_PORT_HTTP="9002" + +# Set the database username to be used for QuestDB. +export QDB_USERNAME="admin" + +# Set the database user's password to be used for QuestDB. +export QDB_PASSWORD="quest" + +# Set the table name to be used by Monitoring for KPIs. +export QDB_TABLE_MONITORING_KPIS="tfs_monitoring_kpis" + +# Set the table name to be used by Slice for plotting groups. +export QDB_TABLE_SLICE_GROUPS="tfs_slice_groups" + +# Disable flag for dropping tables if they exist. +export QDB_DROP_TABLES_IF_EXIST="YES" + +# Disable flag for re-deploying QuestDB from scratch. +export QDB_REDEPLOY="" + + +# ----- K8s Observability ------------------------------------------------------ + +# Set the external port Prometheus Mgmt HTTP GUI interface will be exposed to. +export PROM_EXT_PORT_HTTP="9090" + +# Set the external port Grafana HTTP Dashboards will be exposed to. +export GRAF_EXT_PORT_HTTP="3000" diff --git a/src/tests/ecoc24/dump_logs.sh b/src/tests/ecoc24/dump_logs.sh new file mode 100755 index 000000000..2e41e90a4 --- /dev/null +++ b/src/tests/ecoc24/dump_logs.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +rm -rf tmp/exec + +echo "Collecting logs for E2E..." +mkdir -p tmp/exec/e2e +kubectl --namespace tfs-e2e logs deployments/contextservice server > tmp/exec/e2e/context.log +kubectl --namespace tfs-e2e logs deployments/deviceservice server > tmp/exec/e2e/device.log +kubectl --namespace tfs-e2e logs deployments/serviceservice server > tmp/exec/e2e/service.log +kubectl --namespace tfs-e2e logs deployments/pathcompservice frontend > tmp/exec/e2e/pathcomp-frontend.log +kubectl --namespace tfs-e2e logs deployments/pathcompservice backend > tmp/exec/e2e/pathcomp-backend.log +kubectl --namespace tfs-e2e logs deployments/sliceservice server > tmp/exec/e2e/slice.log +printf "\n" + +echo "Collecting logs for IP..." +mkdir -p tmp/exec/ip +kubectl --namespace tfs-ip logs deployments/contextservice server > tmp/exec/ip/context.log +kubectl --namespace tfs-ip logs deployments/deviceservice server > tmp/exec/ip/device.log +kubectl --namespace tfs-ip logs deployments/serviceservice server > tmp/exec/ip/service.log +kubectl --namespace tfs-ip logs deployments/pathcompservice frontend > tmp/exec/ip/pathcomp-frontend.log +kubectl --namespace tfs-ip logs deployments/pathcompservice backend > tmp/exec/ip/pathcomp-backend.log +kubectl --namespace tfs-ip logs deployments/sliceservice server > tmp/exec/ip/slice.log +printf "\n" + +echo "Done!" diff --git a/src/tests/ecoc24/fast_redeploy.sh b/src/tests/ecoc24/fast_redeploy.sh new file mode 100755 index 000000000..cef672fed --- /dev/null +++ b/src/tests/ecoc24/fast_redeploy.sh @@ -0,0 +1,67 @@ +#!/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-e2e tfs-ip + +echo "Deploying tfs-e2e ..." +kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl create namespace tfs-e2e > ./tmp/logs/deploy-tfs-e2e.log +kubectl apply -f ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/e2eorchestratorservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ecoc24/tfs-ingress-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +printf "\n" + +echo "Deploying tfs-ip ..." +kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl create namespace tfs-ip > ./tmp/logs/deploy-tfs-ip.log +kubectl apply -f ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/vntmanagerservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ecoc24/tfs-ingress-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +printf "\n" + +echo "Waiting tfs-e2e ..." +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/e2eorchestratorservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Waiting tfs-ip ..." +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/contextservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/deviceservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/pathcompservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/serviceservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/sliceservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/vntmanagerservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/webuiservice +printf "\n" + +echo "Done!" diff --git a/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml new file mode 100644 index 000000000..2e7ca2ca4 --- /dev/null +++ b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-e2e + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-e2e + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-e2e + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-e2e + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-e2e +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-e2e + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-e2e +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-e2e + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-e2e + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8001 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4431 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12541 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-e2e + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-e2e + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-e2e + - --election-id=ingress-controller-leader-e2e + - --controller-class=tfs.etsi.org/controller-class-e2e + - --ingress-class=tfs-ingress-class-e2e + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/ecoc24/nginx-ingress-controller-ip.yaml b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml new file mode 100644 index 000000000..0160b7bba --- /dev/null +++ b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml @@ -0,0 +1,134 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-load-balancer-microk8s-conf-ip + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-udp-microk8s-conf-ip + namespace: ingress +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nginx-ingress-tcp-microk8s-conf-ip + namespace: ingress +--- +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: tfs-ingress-class-ip + annotations: + ingressclass.kubernetes.io/is-default-class: "false" +spec: + controller: tfs.etsi.org/controller-class-ip +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: nginx-ingress-microk8s-controller-ip + namespace: ingress + labels: + microk8s-application: nginx-ingress-microk8s-ip +spec: + selector: + matchLabels: + name: nginx-ingress-microk8s-ip + updateStrategy: + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + name: nginx-ingress-microk8s-ip + spec: + terminationGracePeriodSeconds: 60 + restartPolicy: Always + serviceAccountName: nginx-ingress-microk8s-serviceaccount + containers: + - image: k8s.gcr.io/ingress-nginx/controller:v1.2.0 + imagePullPolicy: IfNotPresent + name: nginx-ingress-microk8s + livenessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 5 + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + securityContext: + capabilities: + add: + - NET_BIND_SERVICE + drop: + - ALL + runAsUser: 101 # www-data + env: + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + hostPort: 8002 + protocol: TCP + - name: https + containerPort: 443 + hostPort: 4432 + protocol: TCP + - name: health + containerPort: 10254 + hostPort: 12542 + protocol: TCP + args: + - /nginx-ingress-controller + - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-ip + - --tcp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-tcp-microk8s-conf-ip + - --udp-services-configmap=$(POD_NAMESPACE)/nginx-ingress-udp-microk8s-conf-ip + - --election-id=ingress-controller-leader-ip + - --controller-class=tfs.etsi.org/controller-class-ip + - --ingress-class=tfs-ingress-class-ip + - ' ' + - --publish-status-address=127.0.0.1 diff --git a/src/tests/ecoc24/show_deploy.sh b/src/tests/ecoc24/show_deploy.sh new file mode 100755 index 000000000..63f8fae37 --- /dev/null +++ b/src/tests/ecoc24/show_deploy.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +echo "Deployment Resources:" +kubectl --namespace tfs-e2e get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-e2e get ingress +printf "\n" + +echo "Deployment Resources:" +kubectl --namespace tfs-ip get all +printf "\n" + +echo "Deployment Ingress:" +kubectl --namespace tfs-ip get ingress +printf "\n" diff --git a/src/tests/ecoc24/tfs-ingress-e2e.yaml b/src/tests/ecoc24/tfs-ingress-e2e.yaml new file mode 100644 index 000000000..0ba8a08d5 --- /dev/null +++ b/src/tests/ecoc24/tfs-ingress-e2e.yaml @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-e2e + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-e2e + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /context(/|$)(.*) + pathType: Prefix + backend: + service: + name: contextservice + port: + number: 8080 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: nbiservice + port: + number: 8080 diff --git a/src/tests/ecoc24/tfs-ingress-ip.yaml b/src/tests/ecoc24/tfs-ingress-ip.yaml new file mode 100644 index 000000000..56cec1360 --- /dev/null +++ b/src/tests/ecoc24/tfs-ingress-ip.yaml @@ -0,0 +1,53 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tfs-ingress-ip + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: tfs-ingress-class-ip + rules: + - http: + paths: + - path: /webui(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 8004 + - path: /grafana(/|$)(.*) + pathType: Prefix + backend: + service: + name: webuiservice + port: + number: 3000 + - path: /context(/|$)(.*) + pathType: Prefix + backend: + service: + name: contextservice + port: + number: 8080 + - path: /()(restconf/.*) + pathType: Prefix + backend: + service: + name: nbiservice + port: + number: 8080 -- GitLab From 811a3eb1002af81ac64e5ab9cfb4ffef811610b1 Mon Sep 17 00:00:00 2001 From: mansoca Date: Sun, 31 Mar 2024 14:38:00 +0200 Subject: [PATCH 03/13] deploy paths fixed --- src/tests/ecoc24/delete.sh | 4 +-- src/tests/ecoc24/deploy_e2e.sh | 6 ++-- src/tests/ecoc24/deploy_ip.sh | 8 +++--- src/tests/ecoc24/deploy_specs_e2e.sh | 2 +- src/tests/ecoc24/deploy_specs_ip.sh | 2 +- src/tests/ecoc24/fast_redeploy.sh | 42 ++++++++++++++-------------- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/tests/ecoc24/delete.sh b/src/tests/ecoc24/delete.sh index 3acd872a3..6ad12d15c 100755 --- a/src/tests/ecoc24/delete.sh +++ b/src/tests/ecoc24/delete.sh @@ -18,5 +18,5 @@ kubectl delete namespace tfs-e2e tfs-ip # Delete secondary ingress controllers -kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml -kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml diff --git a/src/tests/ecoc24/deploy_e2e.sh b/src/tests/ecoc24/deploy_e2e.sh index 7f1bfe945..8e1041cf9 100755 --- a/src/tests/ecoc24/deploy_e2e.sh +++ b/src/tests/ecoc24/deploy_e2e.sh @@ -18,12 +18,12 @@ kubectl delete namespace tfs-e2e # Delete secondary ingress controllers -kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml # Create secondary ingress controllers -kubectl apply -f ecoc24/nginx-ingress-controller-e2e.yaml +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml # Deploy TFS for E2E -source ecoc24/deploy_specs_e2e.sh +source src/tests/ecoc24/deploy_specs_e2e.sh ./deploy/all.sh mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh diff --git a/src/tests/ecoc24/deploy_ip.sh b/src/tests/ecoc24/deploy_ip.sh index 5d14f2b07..f51e9762b 100755 --- a/src/tests/ecoc24/deploy_ip.sh +++ b/src/tests/ecoc24/deploy_ip.sh @@ -18,12 +18,12 @@ kubectl delete namespace tfs-ip # Delete secondary ingress controllers -kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml # Create secondary ingress controllers -kubectl apply -f ecoc24/nginx-ingress-controller-ip.yaml +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml -# Deploy TFS for ip -source ecoc24/deploy_specs_ip.sh +# Deploy TFS for IP +source src/tests/ecoc24/deploy_specs_ip.sh ./deploy/all.sh mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_ip.sh diff --git a/src/tests/ecoc24/deploy_specs_e2e.sh b/src/tests/ecoc24/deploy_specs_e2e.sh index 1d9a6228b..f91933694 100755 --- a/src/tests/ecoc24/deploy_specs_e2e.sh +++ b/src/tests/ecoc24/deploy_specs_e2e.sh @@ -48,7 +48,7 @@ export TFS_IMAGE_TAG="dev" export TFS_K8S_NAMESPACE="tfs-e2e" # Set additional manifest files to be applied after the deployment -export TFS_EXTRA_MANIFESTS="src/testsecoc24/tfs-ingress-e2e.yaml" +export TFS_EXTRA_MANIFESTS="src/tests/ecoc24/tfs-ingress-e2e.yaml" # Uncomment to monitor performance of components export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" diff --git a/src/tests/ecoc24/deploy_specs_ip.sh b/src/tests/ecoc24/deploy_specs_ip.sh index 256e6e8e2..12c718330 100755 --- a/src/tests/ecoc24/deploy_specs_ip.sh +++ b/src/tests/ecoc24/deploy_specs_ip.sh @@ -21,7 +21,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. # export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator" -export TFS_COMPONENTS="context device pathcomp service nbi webui " +export TFS_COMPONENTS="context device pathcomp service nbi webui" # Uncomment to activate Monitoring diff --git a/src/tests/ecoc24/fast_redeploy.sh b/src/tests/ecoc24/fast_redeploy.sh index cef672fed..0a6d9bf32 100755 --- a/src/tests/ecoc24/fast_redeploy.sh +++ b/src/tests/ecoc24/fast_redeploy.sh @@ -17,31 +17,31 @@ kubectl delete namespace tfs-e2e tfs-ip echo "Deploying tfs-e2e ..." -kubectl delete -f ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl create namespace tfs-e2e > ./tmp/logs/deploy-tfs-e2e.log -kubectl apply -f ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl create namespace tfs-e2e > ./tmp/logs/deploy-tfs-e2e.log +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log kubectl --namespace tfs-e2e apply -f ./tmp/manifests/e2eorchestratorservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ecoc24/tfs-ingress-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ecoc24/tfs-ingress-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log printf "\n" echo "Deploying tfs-ip ..." -kubectl delete -f ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl create namespace tfs-ip > ./tmp/logs/deploy-tfs-ip.log -kubectl apply -f ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/vntmanagerservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ecoc24/tfs-ingress-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl create namespace tfs-ip > ./tmp/logs/deploy-tfs-ip.log +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/vntmanagerservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ecoc24/tfs-ingress-ip.yaml > ./tmp/logs/deploy-tfs-ip.log printf "\n" echo "Waiting tfs-e2e ..." -- GitLab From 3c786ac4a971def7e95834432106c833e255c5a1 Mon Sep 17 00:00:00 2001 From: mansoca Date: Thu, 11 Apr 2024 10:52:28 +0200 Subject: [PATCH 04/13] Subscription created --- .gitignore | 3 + deploy/all.sh | 3 + deploy/subscription_ws.sh | 45 +++++ install_requirements.sh | 3 + manifests/e2e_orchestratorservice.yaml | 7 + manifests/nbiservice.yaml | 8 + proto/e2eorchestrator.proto | 4 +- proto/vnt_manager.proto | 37 ++++ scripts/show_logs_e2eorchestrator.sh | 2 +- scripts/show_logs_vntmanager.sh | 2 +- src/common/Constants.py | 4 +- src/e2e_orchestrator/requirements.in | 3 +- .../E2EOrchestratorServiceServicerImpl.py | 61 +++++- src/e2e_orchestrator/service/__main__.py | 7 - src/nbi/Dockerfile | 6 + src/nbi/README.md | 3 + src/nbi/requirements.in | 1 + src/nbi/service/NbiServiceServicerImpl.py | 2 +- src/nbi/service/__main__.py | 3 + .../context_subscription/__init__.py | 74 ++++++++ .../nbi_plugins/debug_api/Resources.py | 23 +++ .../nbi_plugins/debug_api/__init__.py | 55 +++--- src/vnt_manager/client/VNTManagerClient.py | 56 ++++-- src/vnt_manager/requirements.in | 3 +- src/vnt_manager/service/VNTManagerService.py | 2 +- .../service/VNTManagerServiceServicerImpl.py | 173 ++++++++++++------ src/vnt_manager/service/__main__.py | 8 +- 27 files changed, 482 insertions(+), 116 deletions(-) create mode 100755 deploy/subscription_ws.sh create mode 100644 proto/vnt_manager.proto mode change 100644 => 100755 scripts/show_logs_e2eorchestrator.sh mode change 100644 => 100755 scripts/show_logs_vntmanager.sh create mode 100644 src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py diff --git a/.gitignore b/.gitignore index a9144d669..20b98c30c 100644 --- a/.gitignore +++ b/.gitignore @@ -171,5 +171,8 @@ local_k8s_deployment.sh # asdf configuration .tool-versions +# libyang build files +libyang/ + # Other logs **/logs/*.log.* diff --git a/deploy/all.sh b/deploy/all.sh index 25d69b485..d99ffa88c 100755 --- a/deploy/all.sh +++ b/deploy/all.sh @@ -175,6 +175,9 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} # Deploy TeraFlowSDN ./deploy/tfs.sh +#Configure Subscription WS +#./deploy/subscription_ws.sh + # Show deploy summary ./deploy/show.sh diff --git a/deploy/subscription_ws.sh b/deploy/subscription_ws.sh new file mode 100755 index 000000000..133abd396 --- /dev/null +++ b/deploy/subscription_ws.sh @@ -0,0 +1,45 @@ +#!/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 SUBSCRIPTION_WS_NAMESPACE=${SUBSCRIPTION_WS_NAMESPACE:-"tfs"} + +# If not already set, set the internal port interface will be exposed to. +export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8765"} + +# If not already set, set the external port interface will be exposed to. +export SUBSCRIPTION_WS_EXT_PORT=${SUBSCRIPTION_WS_EXT_PORT:-"8765"} +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + + +echo "Subscription WebSocket Port Mapping" +echo ">>> ExposeSubscription WebSocket port (${SUBSCRIPTION_WS_EXT_PORT}->${SUBSCRIPTION_WS_EXT_PORT})" +PATCH='{"data": {"'${SUBSCRIPTION_WS_EXT_PORT}'": "'${SUBSCRIPTION_WS_NAMESPACE}'/nbiservice:'${SUBSCRIPTION_WS_EXT_PORT}'"}}' +kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + +PORT_MAP='{"containerPort": '${SUBSCRIPTION_WS_EXT_PORT}', "hostPort": '${SUBSCRIPTION_WS_EXT_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 + + diff --git a/install_requirements.sh b/install_requirements.sh index c59ea7f13..65f60c121 100755 --- a/install_requirements.sh +++ b/install_requirements.sh @@ -32,8 +32,11 @@ sudo apt-get --yes --quiet --quiet update sudo apt-get --yes --quiet --quiet install build-essential cmake libpcre2-dev python3-dev python3-cffi mkdir libyang git clone https://github.com/CESNET/libyang.git libyang +git fetch +git checkout v2.1.148 mkdir libyang/build cd libyang/build +echo "*" > .gitignore cmake -D CMAKE_BUILD_TYPE:String="Release" .. make sudo make install diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index 90d377711..11d7dc398 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -22,6 +22,9 @@ spec: app: e2e-orchestratorservice template: metadata: + annotations: + config.linkerd.io/skip-outbound-ports: "8765" + config.linkerd.io/skip-inbound-ports: "8765" labels: app: e2e-orchestratorservice spec: @@ -33,6 +36,7 @@ spec: ports: - containerPort: 10050 - containerPort: 9192 + - containerPort: 8765 env: - name: LOG_LEVEL value: "INFO" @@ -67,6 +71,9 @@ spec: - name: metrics port: 9192 targetPort: 9192 + - name: ws + port: 8765 + targetPort: 8765 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler diff --git a/manifests/nbiservice.yaml b/manifests/nbiservice.yaml index 0a3bd1ea6..1d0ffc1a1 100644 --- a/manifests/nbiservice.yaml +++ b/manifests/nbiservice.yaml @@ -23,6 +23,9 @@ spec: replicas: 1 template: metadata: + annotations: + config.linkerd.io/skip-outbound-ports: "8765" + config.linkerd.io/skip-inbound-ports: "8765" labels: app: nbiservice spec: @@ -35,6 +38,7 @@ spec: - containerPort: 8080 - containerPort: 9090 - containerPort: 9192 + - containerPort: 8765 env: - name: LOG_LEVEL value: "INFO" @@ -75,3 +79,7 @@ spec: protocol: TCP port: 9192 targetPort: 9192 + - name: websocket + protocol: TCP + port: 8765 + targetPort: 8765 diff --git a/proto/e2eorchestrator.proto b/proto/e2eorchestrator.proto index 9eed8523e..d4cd868ee 100644 --- a/proto/e2eorchestrator.proto +++ b/proto/e2eorchestrator.proto @@ -20,7 +20,9 @@ import "context.proto"; service E2EOrchestratorService { - rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {} + rpc Compute(E2EOrchestratorRequest) returns (E2EOrchestratorReply) {} + rpc PushTopology(context.Topology) returns (context.Empty) {} + } message E2EOrchestratorRequest { diff --git a/proto/vnt_manager.proto b/proto/vnt_manager.proto new file mode 100644 index 000000000..d56473522 --- /dev/null +++ b/proto/vnt_manager.proto @@ -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. + +// protocol buffers documentation: https://developers.google.com/protocol-buffers/docs/proto3 +syntax = "proto3"; +package vnt_manager; +import "context.proto"; + + +service VNTManagerService { + rpc VNTSubscript (VNTSubscriptionRequest) returns (VNTSubscriptionReply) {} + rpc ListVirtualLinkIds (context.Empty) returns (context.LinkIdList) {} + rpc ListVirtualLinks (context.Empty) returns (context.LinkList) {} + rpc GetVirtualLink (context.LinkId) returns (context.Link) {} + rpc SetVirtualLink (context.Link) returns (context.LinkId) {} + rpc RemoveVirtualLink (context.LinkId) returns (context.Empty) {} +} + +message VNTSubscriptionRequest { + string host = 1; + string port = 2; +} + +message VNTSubscriptionReply { + string subscription = 1; +} diff --git a/scripts/show_logs_e2eorchestrator.sh b/scripts/show_logs_e2eorchestrator.sh old mode 100644 new mode 100755 index 84951ed8d..a69abdc91 --- a/scripts/show_logs_e2eorchestrator.sh +++ b/scripts/show_logs_e2eorchestrator.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/e2eorchestratorservice -c server +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/e2e-orchestratorservice -c server diff --git a/scripts/show_logs_vntmanager.sh b/scripts/show_logs_vntmanager.sh old mode 100644 new mode 100755 index 15469e647..aadc2c578 --- a/scripts/show_logs_vntmanager.sh +++ b/scripts/show_logs_vntmanager.sh @@ -24,4 +24,4 @@ export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} # Automated steps start here ######################################################################################################################## -kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/vntmanagerservice -c server +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/vnt_managerservice -c server diff --git a/src/common/Constants.py b/src/common/Constants.py index 276603463..babde64e4 100644 --- a/src/common/Constants.py +++ b/src/common/Constants.py @@ -58,9 +58,9 @@ class ServiceNameEnum(Enum): CACHING = 'caching' TE = 'te' FORECASTER = 'forecaster' - E2EORCHESTRATOR = 'e2e_orchestrator' + E2EORCHESTRATOR = 'e2e-orchestrator' OPTICALCONTROLLER = 'opticalcontroller' - VNTMANAGER = 'vnt_manager' + VNTMANAGER = 'vnt-manager' BGPLS = 'bgpls-speaker' # Used for test and debugging only diff --git a/src/e2e_orchestrator/requirements.in b/src/e2e_orchestrator/requirements.in index 4c4720a2d..3f780913b 100644 --- a/src/e2e_orchestrator/requirements.in +++ b/src/e2e_orchestrator/requirements.in @@ -12,4 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -networkx \ No newline at end of file +networkx +websockets==12.0 \ No newline at end of file diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index d233f2e17..cf4475ad0 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -17,15 +17,17 @@ import logging import networkx as nx import grpc import copy - -from common.Constants import ServiceNameEnum -from common.method_wrappers.Decorator import (MetricsPool, MetricTypeEnum, safe_and_metered_rpc_method) +from websockets.sync.client import connect +import time +from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply from common.proto.context_pb2 import Empty, Connection, EndPointId from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from context.service.database.uuids.EndPoint import endpoint_get_uuid - +from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest, VNTSubscriptionReply +from common.tools.grpc.Tools import grpc_message_to_json_string +from websockets.sync.server import serve LOGGER = logging.getLogger(__name__) @@ -34,11 +36,26 @@ METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") context_client: ContextClient = ContextClient() +def event_received(websocket): + for message in websocket: + LOGGER.info("Message received!!!: {}".format(message)) + websocket.send(message) + + class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): def __init__(self): LOGGER.debug("Creating Servicer...") LOGGER.debug("Servicer Created") + time.sleep(15) + try: + LOGGER.info("Requesting subscription") + self.RequestSubscription() + except Exception as E: + LOGGER.info("Exception!: {}".format(E)) + + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def Compute(self, request: E2EOrchestratorRequest, context: grpc.ServicerContext) -> E2EOrchestratorReply: endpoints_ids = [] @@ -90,4 +107,38 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): path.connections.append(conn) - return path + def RequestSubscription(self): + HOST = "10.1.1.83" + PORT = str(8765) + + url = "ws://" + str(HOST) + ":" + str(PORT) + request = VNTSubscriptionRequest() + request.host = HOST + request.port = PORT + LOGGER.info("Trying to connect... to {}".format(url)) + with connect(url, logger=LOGGER) as websocket: + send = grpc_message_to_json_string(request) + LOGGER.info("Sending {}".format(send)) + websocket.send(send) + + try: + message = websocket.recv() + except Exception as e: + LOGGER.info('Exception1!: {}'.format(e)) + + try: + LOGGER.info("Received ws: {}".format(message)) + except Exception as e: + LOGGER.info('Exception2!: {}'.format(e)) + + + with serve(event_received, HOST, PORT, logger=LOGGER) as server: + LOGGER.info("Running subscription server...: {}:{}".format(HOST, str(PORT))) + server.serve_forever() + LOGGER.info("Exiting subscription server...") + + + + + + diff --git a/src/e2e_orchestrator/service/__main__.py b/src/e2e_orchestrator/service/__main__.py index a586543a7..ef01baeaf 100644 --- a/src/e2e_orchestrator/service/__main__.py +++ b/src/e2e_orchestrator/service/__main__.py @@ -43,13 +43,6 @@ def main(): logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) - wait_for_environment_variables( - [ - get_env_var_name(ServiceNameEnum.E2EORCHESTRATOR, ENVVAR_SUFIX_SERVICE_HOST), - get_env_var_name(ServiceNameEnum.E2EORCHESTRATOR, ENVVAR_SUFIX_SERVICE_PORT_GRPC), - ] - ) - signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/src/nbi/Dockerfile b/src/nbi/Dockerfile index eda4d2956..33f229534 100644 --- a/src/nbi/Dockerfile +++ b/src/nbi/Dockerfile @@ -61,6 +61,9 @@ RUN apt-get --yes --quiet --quiet update && \ rm -rf /var/lib/apt/lists/* RUN mkdir -p /var/libyang RUN git clone https://github.com/CESNET/libyang.git /var/libyang +WORKDIR /var/libyang +RUN git fetch +RUN git checkout v2.1.148 RUN mkdir -p /var/libyang/build WORKDIR /var/libyang/build RUN cmake -D CMAKE_BUILD_TYPE:String="Release" .. @@ -86,6 +89,9 @@ COPY src/service/__init__.py service/__init__.py COPY src/service/client/. service/client/ COPY src/slice/__init__.py slice/__init__.py COPY src/slice/client/. slice/client/ +# COPY src/vnt_manager/__init__.py vnt_manager/__init__.py +# COPY src/vnt_manager/client/. vnt_manager/client/ +COPY --chown=teraflow:teraflow ./src/vnt_manager/. vnt_manager RUN mkdir -p /var/teraflow/tests/tools COPY src/tests/tools/mock_osm/. tests/tools/mock_osm/ diff --git a/src/nbi/README.md b/src/nbi/README.md index c5ed72704..32902a0b3 100644 --- a/src/nbi/README.md +++ b/src/nbi/README.md @@ -18,6 +18,9 @@ sudo apt-get install python3-dev gcc python3-cffi ```bash mkdir ~/tfs-ctrl/libyang git clone https://github.com/CESNET/libyang.git ~/tfs-ctrl/libyang +cd ~/tfs-ctrl/libyang +git fetch +git checkout v2.1.148 mkdir ~/tfs-ctrl/libyang/build cd ~/tfs-ctrl/libyang/build cmake -D CMAKE_BUILD_TYPE:String="Release" .. diff --git a/src/nbi/requirements.in b/src/nbi/requirements.in index 6e3eb9440..37c41550f 100644 --- a/src/nbi/requirements.in +++ b/src/nbi/requirements.in @@ -24,3 +24,4 @@ pyang==2.6.0 git+https://github.com/robshakir/pyangbind.git requests==2.27.1 werkzeug==2.3.7 +websockets==12.0 diff --git a/src/nbi/service/NbiServiceServicerImpl.py b/src/nbi/service/NbiServiceServicerImpl.py index d454a4df9..2f641d324 100644 --- a/src/nbi/service/NbiServiceServicerImpl.py +++ b/src/nbi/service/NbiServiceServicerImpl.py @@ -20,7 +20,7 @@ from common.proto.nbi_pb2_grpc import NbiServiceServicer LOGGER = logging.getLogger(__name__) -METRICS_POOL = MetricsPool('Compute', 'RPC') +METRICS_POOL = MetricsPool('NBI', 'RPC') class NbiServiceServicerImpl(NbiServiceServicer): def __init__(self): diff --git a/src/nbi/service/__main__.py b/src/nbi/service/__main__.py index 8834e45a2..aa16ee897 100644 --- a/src/nbi/service/__main__.py +++ b/src/nbi/service/__main__.py @@ -26,6 +26,7 @@ from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn from .rest_server.nbi_plugins.ietf_network import register_ietf_network from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss +from .rest_server.nbi_plugins.context_subscription import register_context_subscription terminate = threading.Event() LOGGER = None @@ -70,6 +71,8 @@ def main(): register_ietf_nss(rest_server) # Registering NSS entrypoint rest_server.start() + register_context_subscription() + # Wait for Ctrl+C or termination signal while not terminate.wait(timeout=1.0): pass diff --git a/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py b/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py new file mode 100644 index 000000000..d5deb9352 --- /dev/null +++ b/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py @@ -0,0 +1,74 @@ +# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from websockets.sync.server import serve +from common.proto.vnt_manager_pb2 import VNTSubscriptionReply, VNTSubscriptionRequest +from common.proto.context_pb2 import Empty + +# from vnt_manager.client.VNTManagerClient import VNTManagerClient +from context.client.ContextClient import ContextClient +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME +from common.tools.object_factory.Topology import json_topology_id +from common.tools.object_factory.Context import json_context_id +from common.proto.context_pb2 import ContextId, TopologyId +import json +import os +from vnt_manager.client.VNTManagerClient import VNTManagerClient + +JSON_ADMIN_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +ADMIN_CONTEXT_ID = ContextId(**JSON_ADMIN_CONTEXT_ID) +ADMIN_TOPOLOGY_ID = TopologyId(**json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=JSON_ADMIN_CONTEXT_ID)) + +vnt_manager_client: VNTManagerClient = VNTManagerClient() +context_client: ContextClient = ContextClient() + +HOST = "0.0.0.0" +PORT = 8765 + +LOGGER = logging.getLogger(__name__) + + +def register_context_subscription(): + with serve(subcript_to_vnt_manager, HOST, PORT, logger=LOGGER) as server: + LOGGER.info("Running subscription server...: {}:{}".format(HOST, str(PORT))) + server.serve_forever() + LOGGER.info("Exiting subscription server...") + + +def subcript_to_vnt_manager(websocket): + for message in websocket: + LOGGER.info("Message received: {}".format(message)) + message_json = json.loads(message) + request = VNTSubscriptionRequest() + request.host = message_json['host'] + request.port = message_json['port'] + LOGGER.info("Received gRPC from ws: {}".format(request)) + + reply = VNTSubscriptionReply() + try: + vntm_reply = vnt_manager_client.VNTSubscript(request) + LOGGER.info("Received gRPC from vntm: {}".format(vntm_reply)) + except Exception as e: + LOGGER.error('Could not subscript to VTNManager: {}'.format(e)) + reply.subscription = "NOT OK" + else: + reply.subscription = "OK" + + + websocket.send(reply.subscription) + + + diff --git a/src/nbi/service/rest_server/nbi_plugins/debug_api/Resources.py b/src/nbi/service/rest_server/nbi_plugins/debug_api/Resources.py index 5fb46a302..876877c25 100644 --- a/src/nbi/service/rest_server/nbi_plugins/debug_api/Resources.py +++ b/src/nbi/service/rest_server/nbi_plugins/debug_api/Resources.py @@ -19,6 +19,8 @@ from common.proto.context_pb2 import Empty from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient +from vnt_manager.client.VNTManagerClient import VNTManagerClient + from .Tools import ( format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link_id, grpc_policy_rule_id, grpc_service_id, grpc_service, grpc_slice_id, grpc_topology_id) @@ -28,6 +30,7 @@ class _Resource(Resource): super().__init__() self.client = ContextClient() self.service_client = ServiceClient() + self.vntmanager_client = VNTManagerClient() class ContextIds(_Resource): def get(self): @@ -186,6 +189,26 @@ class Link(_Resource): def get(self, link_uuid : str): return format_grpc_to_json(self.client.GetLink(grpc_link_id(link_uuid))) +class VirtualLinkIds(_Resource): + def get(self): + return format_grpc_to_json(self.vntmanager_client.ListLinkIds(Empty())) + +class VirtualLinks(_Resource): + def get(self): + return format_grpc_to_json(self.vntmanager_client.ListLinks(Empty())) + +class VirtualLink(_Resource): + def get(self, link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.GetLink(grpc_link_id(link_uuid))) + def post(self, link_uuid : str): + link = request.get_json() + return format_grpc_to_json(self.vntmanager_client.SetLink(grpc_link_id(link))) + def put(self, link_uuid : str): + link = request.get_json() + return format_grpc_to_json(self.vntmanager_client.SetLink(grpc_link_id(link))) + def delete(self, link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.RemoveVirtualLink(grpc_link_id(link_uuid))) + class ConnectionIds(_Resource): def get(self, context_uuid : str, service_uuid : str): return format_grpc_to_json(self.client.ListConnectionIds(grpc_service_id(context_uuid, service_uuid))) diff --git a/src/nbi/service/rest_server/nbi_plugins/debug_api/__init__.py b/src/nbi/service/rest_server/nbi_plugins/debug_api/__init__.py index 1ccf93144..e420fa949 100644 --- a/src/nbi/service/rest_server/nbi_plugins/debug_api/__init__.py +++ b/src/nbi/service/rest_server/nbi_plugins/debug_api/__init__.py @@ -19,6 +19,7 @@ from .Resources import ( Device, DeviceIds, Devices, DummyContexts, Link, LinkIds, Links, + VirtualLink, VirtualLinkIds, VirtualLinks, PolicyRule, PolicyRuleIds, PolicyRules, Service, ServiceIds, Services, Slice, SliceIds, Slices, @@ -30,38 +31,42 @@ URL_PREFIX = '/debug-api' # Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type. RESOURCES = [ # (endpoint_name, resource_class, resource_url) - ('api.context_ids', ContextIds, '/context_ids'), - ('api.contexts', Contexts, '/contexts'), - ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), - ('api.context', Context, '/context/'), + ('api.context_ids', ContextIds, '/context_ids'), + ('api.contexts', Contexts, '/contexts'), + ('api.dummy_contexts', DummyContexts, '/dummy_contexts'), + ('api.context', Context, '/context/'), - ('api.topology_ids', TopologyIds, '/context//topology_ids'), - ('api.topologies', Topologies, '/context//topologies'), - ('api.topology', Topology, '/context//topology/'), + ('api.topology_ids', TopologyIds, '/context//topology_ids'), + ('api.topologies', Topologies, '/context//topologies'), + ('api.topology', Topology, '/context//topology/'), - ('api.service_ids', ServiceIds, '/context//service_ids'), - ('api.services', Services, '/context//services'), - ('api.service', Service, '/context//service/'), + ('api.service_ids', ServiceIds, '/context//service_ids'), + ('api.services', Services, '/context//services'), + ('api.service', Service, '/context//service/'), - ('api.slice_ids', SliceIds, '/context//slice_ids'), - ('api.slices', Slices, '/context//slices'), - ('api.slice', Slice, '/context//slice/'), + ('api.slice_ids', SliceIds, '/context//slice_ids'), + ('api.slices', Slices, '/context//slices'), + ('api.slice', Slice, '/context//slice/'), - ('api.device_ids', DeviceIds, '/device_ids'), - ('api.devices', Devices, '/devices'), - ('api.device', Device, '/device/'), + ('api.device_ids', DeviceIds, '/device_ids'), + ('api.devices', Devices, '/devices'), + ('api.device', Device, '/device/'), - ('api.link_ids', LinkIds, '/link_ids'), - ('api.links', Links, '/links'), - ('api.link', Link, '/link/'), + ('api.link_ids', LinkIds, '/link_ids'), + ('api.links', Links, '/links'), + ('api.link', Link, '/link/'), - ('api.connection_ids', ConnectionIds, '/context//service//connection_ids'), - ('api.connections', Connections, '/context//service//connections'), - ('api.connection', Connection, '/connection/'), + ('api.virtual_link_ids', VirtualLinkIds, '/virtual_link_ids'), + ('api.virtual_links', VirtualLinks, '/virtual_links'), + ('api.virtual_link', VirtualLink, '/virtual_link/'), - ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), - ('api.policyrules', PolicyRules, '/policyrules'), - ('api.policyrule', PolicyRule, '/policyrule/'), + ('api.connection_ids', ConnectionIds, '/context//service//connection_ids'), + ('api.connections', Connections, '/context//service//connections'), + ('api.connection', Connection, '/connection/'), + + ('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'), + ('api.policyrules', PolicyRules, '/policyrules'), + ('api.policyrule', PolicyRule, '/policyrule/'), ] def register_debug_api(rest_server : RestServer): diff --git a/src/vnt_manager/client/VNTManagerClient.py b/src/vnt_manager/client/VNTManagerClient.py index 95db3b6da..67850a602 100644 --- a/src/vnt_manager/client/VNTManagerClient.py +++ b/src/vnt_manager/client/VNTManagerClient.py @@ -18,11 +18,16 @@ import grpc from common.Constants import ServiceNameEnum from common.proto.context_pb2 import Empty -from common.proto.vntmanager_pb2_grpc import VNTManagerServiceStub +from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest, VNTSubscriptionReply +from common.proto.vnt_manager_pb2_grpc import VNTManagerServiceStub from common.Settings import get_service_host, get_service_port_grpc from common.tools.client.RetryDecorator import delay_exponential, retry from common.tools.grpc.Tools import grpc_message_to_json # from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply +from common.proto.context_pb2 import ( + Link, LinkId, LinkIdList, LinkList, +) +from common.tools.grpc.Tools import grpc_message_to_json_string LOGGER = logging.getLogger(__name__) MAX_RETRIES = 15 @@ -57,15 +62,44 @@ class VNTManagerClient: self.channel = None self.stub = None - """ @RETRY_DECORATOR - def Compute(self, request: E2EOrchestratorRequest) -> E2EOrchestratorReply: - LOGGER.info( - "Compute request: {:s}".format(str(grpc_message_to_json(request))) - ) - response = self.stub.Compute(request) - LOGGER.info( - "Compute result: {:s}".format(str(grpc_message_to_json(response))) - ) + def VNTSubscript(self, request: VNTSubscriptionRequest) -> VNTSubscriptionReply: + LOGGER.info("Subscript request: {:s}".format(str(grpc_message_to_json(request)))) + response = self.stub.VNTSubscript(request) + LOGGER.info("Subscript result: {:s}".format(str(grpc_message_to_json(response)))) + return response + + @RETRY_DECORATOR + def ListVirtualLinkIds(self, request: Empty) -> LinkIdList: + LOGGER.debug('ListVirtualLinkIds request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.ListVirtualLinkIds(request) + LOGGER.debug('ListVirtualLinkIds result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def ListVirtualLinks(self, request: Empty) -> LinkList: + LOGGER.debug('ListVirtualLinks request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.ListVirtualLinks(request) + LOGGER.debug('ListVirtualLinks result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def GetVirtualLink(self, request: LinkId) -> Link: + LOGGER.debug('GetVirtualLink request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.GetVirtualLink(request) + LOGGER.debug('GetVirtualLink result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def SetVirtualLink(self, request: Link) -> LinkId: + LOGGER.debug('SetVirtualLink request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.SetVirtualLink(request) + LOGGER.debug('SetVirtualLink result: {:s}'.format(grpc_message_to_json_string(response))) + return response + + @RETRY_DECORATOR + def RemoveVirtualLink(self, request: LinkId) -> Empty: + LOGGER.debug('RemoveVirtualLink request: {:s}'.format(grpc_message_to_json_string(request))) + response = self.stub.RemoveVirtualLink(request) + LOGGER.debug('RemoveVirtualLink result: {:s}'.format(grpc_message_to_json_string(response))) return response - """ \ No newline at end of file diff --git a/src/vnt_manager/requirements.in b/src/vnt_manager/requirements.in index 4c4720a2d..3f780913b 100644 --- a/src/vnt_manager/requirements.in +++ b/src/vnt_manager/requirements.in @@ -12,4 +12,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -networkx \ No newline at end of file +networkx +websockets==12.0 \ No newline at end of file diff --git a/src/vnt_manager/service/VNTManagerService.py b/src/vnt_manager/service/VNTManagerService.py index b61b213a6..0580d1c7f 100644 --- a/src/vnt_manager/service/VNTManagerService.py +++ b/src/vnt_manager/service/VNTManagerService.py @@ -15,7 +15,7 @@ import logging from common.Constants import ServiceNameEnum -from common.proto.vntmanager_pb2_grpc import add_VNTManagerServiceServicer_to_server +from common.proto.vnt_manager_pb2_grpc import add_VNTManagerServiceServicer_to_server from common.Settings import get_service_port_grpc from common.tools.service.GenericGrpcService import GenericGrpcService from .VNTManagerServiceServicerImpl import VNTManagerServiceServicerImpl diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index 4869218a7..e2b110de0 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -16,15 +16,30 @@ import logging import networkx as nx import grpc -import copy - -from common.Constants import ServiceNameEnum +import time +from websockets.sync.client import connect from common.method_wrappers.Decorator import (MetricsPool, MetricTypeEnum, safe_and_metered_rpc_method) -from common.proto.vntmanager_pb2 import VNTManagerRequest, VNTManagerReply -from common.proto.context_pb2 import Empty, Connection, EndPointId -from common.proto.vntmanager_pb2_grpc import VNTManagerServiceServicer +from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest, VNTSubscriptionReply +from common.proto.vnt_manager_pb2_grpc import VNTManagerServiceServicer +from context.client.ContextClient import ContextClient +from common.proto.context_pb2 import ( + Empty, + Event, EventTypeEnum, + Link, LinkEvent, LinkId, LinkIdList, LinkList, +) +from common.tools.object_factory.Context import json_context_id +from common.tools.object_factory.Topology import json_topology_id +from common.proto.context_pb2 import ContextId, TopologyId +import threading +from common.proto.context_pb2 import ( + ConnectionEvent, ContextEvent, DeviceEvent, EventTypeEnum, ServiceEvent, TopologyEvent) from context.client.ContextClient import ContextClient -from context.service.database.uuids.EndPoint import endpoint_get_uuid +from context.client.EventsCollector import EventsCollector +from common.tests.EventTools import EVENT_CREATE, EVENT_UPDATE, check_events +from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME +from typing import Any, Dict, Set +from common.proto.dlt_gateway_pb2 import DltRecordEvent, DltRecordOperationEnum, DltRecordTypeEnum +from common.tools.grpc.Tools import grpc_message_to_json_string LOGGER = logging.getLogger(__name__) @@ -33,63 +48,117 @@ METRICS_POOL = MetricsPool("VNTManager", "RPC") context_client: ContextClient = ContextClient() +JSON_ADMIN_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME) +ADMIN_CONTEXT_ID = ContextId(**JSON_ADMIN_CONTEXT_ID) +ADMIN_TOPOLOGY_ID = TopologyId(**json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id=JSON_ADMIN_CONTEXT_ID)) -class E2EOrchestratorServiceServicerImpl(VNTManagerServiceServicer): - def __init__(self): - LOGGER.debug("Creating Servicer...") - LOGGER.debug("Servicer Created") +GET_EVENT_TIMEOUT = 0.5 - """ - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def Compute(self, request: E2EOrchestratorRequest, context: grpc.ServicerContext) -> E2EOrchestratorReply: - endpoints_ids = [] - for endpoint_id in request.service.service_endpoint_ids: - endpoints_ids.append(endpoint_get_uuid(endpoint_id)[2]) - graph = nx.Graph() - devices = context_client.ListDevices(Empty()).devices +HOST = "10.1.1.83" +PORT = str(8765) + + + +class VNTMEventDispatcher(threading.Thread): + def __init__(self, host, port) -> None: + LOGGER.debug('Creating VTNM connector...') + self.host = host + self.port = port + super().__init__(name='VNTMEventDispatcher', daemon=True) + self._terminate = threading.Event() + LOGGER.debug('VNTM connector created') + + def start(self) -> None: + self._terminate.clear() + return super().start() + + def stop(self): + self._terminate.set() + + def run(self) -> None: + LOGGER.info('Thread running!') + events_collector = EventsCollector( + context_client, log_events_received=True, + activate_context_collector = True, + activate_topology_collector = True, + activate_device_collector = False, + activate_link_collector = False, + activate_service_collector = False, + activate_slice_collector = False, + activate_connection_collector = False,) + events_collector.start() + + while not self._terminate.is_set(): + event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) + if event is None: continue + + url = "ws://" + str(self.host) + ":" + str(self.port) + request = VNTSubscriptionRequest() + request.host = self.host + request.port = self.port + LOGGER.info("Sending event to {}".format(url)) + with connect(url, logger=LOGGER) as websocket: + send = grpc_message_to_json_string(request) + LOGGER.info("Sending {}".format(send)) + websocket.send(send) + message = websocket.recv() + LOGGER.info("Received ws: {}".format(message)) - for device in devices: - endpoints_uuids = [endpoint.endpoint_id.endpoint_uuid.uuid - for endpoint in device.device_endpoints] - for ep in endpoints_uuids: - graph.add_node(ep) + - for ep in endpoints_uuids: - for ep_i in endpoints_uuids: - if ep == ep_i: - continue - graph.add_edge(ep, ep_i) + events_collector.stop() - links = context_client.ListLinks(Empty()).links - for link in links: - eps = [] - for endpoint_id in link.link_endpoint_ids: - eps.append(endpoint_id.endpoint_uuid.uuid) - graph.add_edge(eps[0], eps[1]) - shortest = nx.shortest_path(graph, endpoints_ids[0], endpoints_ids[1]) - path = E2EOrchestratorReply() - path.services.append(copy.deepcopy(request.service)) - for i in range(0, int(len(shortest)/2)): - conn = Connection() - ep_a_uuid = str(shortest[i*2]) - ep_z_uuid = str(shortest[i*2+1]) +class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): + def __init__(self): + LOGGER.debug("Creating Servicer...") + LOGGER.debug("Servicer Created") + self.links = [] + + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def VNTSubscript(self, request: VNTSubscriptionRequest, context: grpc.ServicerContext) -> VNTSubscriptionReply: + LOGGER.info('----------------') + LOGGER.info(request) + LOGGER.info('----------------') + reply = VNTSubscriptionReply() + reply.subscription = "OK" + + event_dispatcher = VNTMEventDispatcher(request.host, int(request.port)) + event_dispatcher.start() - conn.connection_id.connection_uuid.uuid = str(ep_a_uuid) + '_->_' + str(ep_z_uuid) - ep_a_id = EndPointId() - ep_a_id.endpoint_uuid.uuid = ep_a_uuid - conn.path_hops_endpoint_ids.append(ep_a_id) + return reply - ep_z_id = EndPointId() - ep_z_id.endpoint_uuid.uuid = ep_z_uuid - conn.path_hops_endpoint_ids.append(ep_z_id) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def ListVirtualLinkIds(self, request : Empty, context : grpc.ServicerContext) -> LinkIdList: + return LinkIdList(link_ids=[link.link_id for link in self.links]) + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def ListVirtualLinks(self, request : Empty, context : grpc.ServicerContext) -> LinkList: + return LinkList(link=self.links) - path.connections.append(conn) + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def GetVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Link: + for link in self.links: + if link.link_uuid.uuid == request.uuid: + return link + return Empty() - return path - """ \ No newline at end of file + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def SetVirtualLink(self, request : Link, context : grpc.ServicerContext) -> LinkId: + self.links.append(request) + return request.linkd_id + + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def RemoveVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty: + for link in self.links: + if link.link_uuid.uuid == request.uuid: + self.links.remove(link) + return Empty() + return Empty() + diff --git a/src/vnt_manager/service/__main__.py b/src/vnt_manager/service/__main__.py index 03fb4dd5d..66d3e435c 100644 --- a/src/vnt_manager/service/__main__.py +++ b/src/vnt_manager/service/__main__.py @@ -43,12 +43,6 @@ def main(): logging.basicConfig(level=log_level) LOGGER = logging.getLogger(__name__) - wait_for_environment_variables( - [ - get_env_var_name(ServiceNameEnum.VNTMANAGER, ENVVAR_SUFIX_SERVICE_HOST), - get_env_var_name(ServiceNameEnum.VNTMANAGER, ENVVAR_SUFIX_SERVICE_PORT_GRPC), - ] - ) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) @@ -59,7 +53,7 @@ def main(): metrics_port = get_metrics_port() start_http_server(metrics_port) - # Starting CentralizedCybersecurity service + # Starting VNTManager service grpc_service = VNTManagerService() grpc_service.start() LOGGER.info("Started...") -- GitLab From f163a56c01d2f0a49d6af1293aedd77373182519 Mon Sep 17 00:00:00 2001 From: gifrerenom Date: Fri, 12 Apr 2024 14:04:43 +0000 Subject: [PATCH 05/13] Deployment hacks: - Deactivated linkerd - Deactivated service monitors - Added missing slice component - Enabled build of all components during deploy - Added missing symbolic link ecoc24 - Corrected paths in ecoc24/deploy.sh - Deactivated grafana dashboard - Adjusted compute request limits per component - Deactivated Horizontal Pod Autoscalers --- deploy/tfs.sh | 4 +- ecoc24 | 1 + manifests/contextservice.yaml | 46 ++++++++-------- manifests/deviceservice.yaml | 2 +- manifests/e2e_orchestratorservice.yaml | 25 +-------- manifests/pathcompservice.yaml | 46 ++++++++-------- manifests/serviceservice.yaml | 46 ++++++++-------- manifests/sliceservice.yaml | 46 ++++++++-------- manifests/vnt_managerservice.yaml | 32 +++-------- manifests/webuiservice.yaml | 76 +++++++++++++------------- src/tests/ecoc24/deploy.sh | 12 ++-- src/tests/ecoc24/deploy_specs_e2e.sh | 4 +- src/tests/ecoc24/deploy_specs_ip.sh | 8 +-- 13 files changed, 156 insertions(+), 192 deletions(-) create mode 120000 ecoc24 diff --git a/deploy/tfs.sh b/deploy/tfs.sh index fd49c9758..f1c7d5a77 100755 --- a/deploy/tfs.sh +++ b/deploy/tfs.sh @@ -279,8 +279,8 @@ for COMPONENT in $TFS_COMPONENTS; do echo " Adapting '$COMPONENT' manifest file..." MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml" - # cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" - cat ./manifests/"${COMPONENT}"service.yaml | linkerd inject - --proxy-cpu-request "10m" --proxy-cpu-limit "1" --proxy-memory-request "64Mi" --proxy-memory-limit "256Mi" > "$MANIFEST" + cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST" + #cat ./manifests/"${COMPONENT}"service.yaml | linkerd inject - --proxy-cpu-request "10m" --proxy-cpu-limit "1" --proxy-memory-request "64Mi" --proxy-memory-limit "256Mi" > "$MANIFEST" if [ "$COMPONENT" == "pathcomp" ]; then IMAGE_URL=$(echo "$TFS_REGISTRY_IMAGES/$COMPONENT-frontend:$TFS_IMAGE_TAG" | sed 's,//,/,g' | sed 's,http:/,,g') diff --git a/ecoc24 b/ecoc24 new file mode 120000 index 000000000..37c97d3a7 --- /dev/null +++ b/ecoc24 @@ -0,0 +1 @@ +src/tests/ecoc24/ \ No newline at end of file diff --git a/manifests/contextservice.yaml b/manifests/contextservice.yaml index c7dc59625..1e11ae135 100644 --- a/manifests/contextservice.yaml +++ b/manifests/contextservice.yaml @@ -58,7 +58,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:1010"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -83,25 +83,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: contextservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: contextservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 +#--- +#apiVersion: autoscaling/v2 +#kind: HorizontalPodAutoscaler +#metadata: +# name: contextservice-hpa +#spec: +# scaleTargetRef: +# apiVersion: apps/v1 +# kind: Deployment +# name: contextservice +# minReplicas: 1 +# maxReplicas: 20 +# metrics: +# - type: Resource +# resource: +# name: cpu +# target: +# type: Utilization +# averageUtilization: 80 +# #behavior: +# # scaleDown: +# # stabilizationWindowSeconds: 30 diff --git a/manifests/deviceservice.yaml b/manifests/deviceservice.yaml index fdc3cea02..06d5070bf 100644 --- a/manifests/deviceservice.yaml +++ b/manifests/deviceservice.yaml @@ -53,7 +53,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:2020"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index 11d7dc398..9763b7a56 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -20,6 +20,7 @@ spec: selector: matchLabels: app: e2e-orchestratorservice + replicas: 1 template: metadata: annotations: @@ -48,7 +49,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:10050"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -74,25 +75,3 @@ spec: - name: ws port: 8765 targetPort: 8765 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: e2e-orchestratorservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: e2e-orchestratorservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 diff --git a/manifests/pathcompservice.yaml b/manifests/pathcompservice.yaml index f017e6940..98b7e9af9 100644 --- a/manifests/pathcompservice.yaml +++ b/manifests/pathcompservice.yaml @@ -47,7 +47,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:10020"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -100,25 +100,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: pathcompservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: pathcompservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 +#--- +#apiVersion: autoscaling/v2 +#kind: HorizontalPodAutoscaler +#metadata: +# name: pathcompservice-hpa +#spec: +# scaleTargetRef: +# apiVersion: apps/v1 +# kind: Deployment +# name: pathcompservice +# minReplicas: 1 +# maxReplicas: 20 +# metrics: +# - type: Resource +# resource: +# name: cpu +# target: +# type: Utilization +# averageUtilization: 80 +# #behavior: +# # scaleDown: +# # stabilizationWindowSeconds: 30 diff --git a/manifests/serviceservice.yaml b/manifests/serviceservice.yaml index 2fb7ebb87..2f3e62332 100644 --- a/manifests/serviceservice.yaml +++ b/manifests/serviceservice.yaml @@ -45,7 +45,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:3030"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -70,25 +70,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: serviceservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: serviceservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 +#--- +#apiVersion: autoscaling/v2 +#kind: HorizontalPodAutoscaler +#metadata: +# name: serviceservice-hpa +#spec: +# scaleTargetRef: +# apiVersion: apps/v1 +# kind: Deployment +# name: serviceservice +# minReplicas: 1 +# maxReplicas: 20 +# metrics: +# - type: Resource +# resource: +# name: cpu +# target: +# type: Utilization +# averageUtilization: 80 +# #behavior: +# # scaleDown: +# # stabilizationWindowSeconds: 30 diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml index 0daa8e70f..cc3c33bca 100644 --- a/manifests/sliceservice.yaml +++ b/manifests/sliceservice.yaml @@ -50,7 +50,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:4040"] resources: requests: - cpu: 250m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -75,25 +75,25 @@ spec: protocol: TCP port: 9192 targetPort: 9192 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: sliceservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: sliceservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 +#--- +#apiVersion: autoscaling/v2 +#kind: HorizontalPodAutoscaler +#metadata: +# name: sliceservice-hpa +#spec: +# scaleTargetRef: +# apiVersion: apps/v1 +# kind: Deployment +# name: sliceservice +# minReplicas: 1 +# maxReplicas: 20 +# metrics: +# - type: Resource +# resource: +# name: cpu +# target: +# type: Utilization +# averageUtilization: 80 +# #behavior: +# # scaleDown: +# # stabilizationWindowSeconds: 30 diff --git a/manifests/vnt_managerservice.yaml b/manifests/vnt_managerservice.yaml index 95070564b..0aca37806 100644 --- a/manifests/vnt_managerservice.yaml +++ b/manifests/vnt_managerservice.yaml @@ -20,8 +20,12 @@ spec: selector: matchLabels: app: vnt-managerservice + replicas: 1 template: metadata: + annotations: + config.linkerd.io/skip-outbound-ports: "8765" + config.linkerd.io/skip-inbound-ports: "8765" labels: app: vnt-managerservice spec: @@ -33,6 +37,7 @@ spec: ports: - containerPort: 10070 - containerPort: 9192 + - containerPort: 8765 env: - name: LOG_LEVEL value: "INFO" @@ -44,7 +49,7 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:10070"] resources: requests: - cpu: 150m + cpu: 200m memory: 128Mi limits: cpu: 1000m @@ -67,25 +72,6 @@ spec: - name: metrics port: 9192 targetPort: 9192 ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: vnt-managerservice-hpa -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: vnt-managerservice - minReplicas: 1 - maxReplicas: 20 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 80 - #behavior: - # scaleDown: - # stabilizationWindowSeconds: 30 + - name: ws + port: 8765 + targetPort: 8765 diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml index bb2573c45..28cc42c78 100644 --- a/manifests/webuiservice.yaml +++ b/manifests/webuiservice.yaml @@ -61,44 +61,44 @@ spec: limits: cpu: 1000m memory: 1024Mi - - name: grafana - image: grafana/grafana:8.5.22 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 3000 - name: http-grafana - protocol: TCP - env: - - name: GF_SERVER_ROOT_URL - value: "http://0.0.0.0:3000/grafana/" - - name: GF_SERVER_SERVE_FROM_SUB_PATH - value: "true" - readinessProbe: - failureThreshold: 60 - httpGet: - #path: /robots.txt - path: /login - port: 3000 - scheme: HTTP - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - timeoutSeconds: 2 - livenessProbe: - failureThreshold: 60 - initialDelaySeconds: 1 - periodSeconds: 1 - successThreshold: 1 - tcpSocket: - port: 3000 - timeoutSeconds: 1 - resources: - requests: - cpu: 250m - memory: 512Mi - limits: - cpu: 500m - memory: 1024Mi +# - name: grafana +# image: grafana/grafana:8.5.22 +# imagePullPolicy: IfNotPresent +# ports: +# - containerPort: 3000 +# name: http-grafana +# protocol: TCP +# env: +# - name: GF_SERVER_ROOT_URL +# value: "http://0.0.0.0:3000/grafana/" +# - name: GF_SERVER_SERVE_FROM_SUB_PATH +# value: "true" +# readinessProbe: +# failureThreshold: 60 +# httpGet: +# #path: /robots.txt +# path: /login +# port: 3000 +# scheme: HTTP +# initialDelaySeconds: 1 +# periodSeconds: 1 +# successThreshold: 1 +# timeoutSeconds: 2 +# livenessProbe: +# failureThreshold: 60 +# initialDelaySeconds: 1 +# periodSeconds: 1 +# successThreshold: 1 +# tcpSocket: +# port: 3000 +# timeoutSeconds: 1 +# resources: +# requests: +# cpu: 250m +# memory: 512Mi +# limits: +# cpu: 500m +# memory: 1024Mi --- apiVersion: v1 kind: Service diff --git a/src/tests/ecoc24/deploy.sh b/src/tests/ecoc24/deploy.sh index 153e98b1a..10a31ebc3 100755 --- a/src/tests/ecoc24/deploy.sh +++ b/src/tests/ecoc24/deploy.sh @@ -18,19 +18,19 @@ kubectl delete namespace tfs-e2e tfs-ip # Delete secondary ingress controllers -kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml -kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml +kubectl delete -f ./src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +kubectl delete -f ./src/tests/ecoc24/nginx-ingress-controller-ip.yaml # Create secondary ingress controllers -kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml -kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml +kubectl apply -f ./src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +kubectl apply -f ./src/tests/ecoc24/nginx-ingress-controller-ip.yaml # Deploy TFS for e2e -source src/tests/ecoc24/deploy_specs_e2e.sh +source ./src/tests/ecoc24/deploy_specs_e2e.sh ./deploy/all.sh mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh # Deploy TFS for ip -source src/tests/ecoc24/deploy_specs_ip.sh +source ./src/tests/ecoc24/deploy_specs_ip.sh ./deploy/all.sh mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_ip.sh diff --git a/src/tests/ecoc24/deploy_specs_e2e.sh b/src/tests/ecoc24/deploy_specs_e2e.sh index f91933694..383a6b726 100755 --- a/src/tests/ecoc24/deploy_specs_e2e.sh +++ b/src/tests/ecoc24/deploy_specs_e2e.sh @@ -21,7 +21,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. # export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator" -export TFS_COMPONENTS="context device pathcomp service nbi webui" +export TFS_COMPONENTS="context device pathcomp service slice nbi webui" # Uncomment to activate Monitoring #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -51,7 +51,7 @@ export TFS_K8S_NAMESPACE="tfs-e2e" export TFS_EXTRA_MANIFESTS="src/tests/ecoc24/tfs-ingress-e2e.yaml" # Uncomment to monitor performance of components -export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" # Uncomment when deploying Optical CyberSecurity #export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" diff --git a/src/tests/ecoc24/deploy_specs_ip.sh b/src/tests/ecoc24/deploy_specs_ip.sh index 12c718330..36e298b65 100755 --- a/src/tests/ecoc24/deploy_specs_ip.sh +++ b/src/tests/ecoc24/deploy_specs_ip.sh @@ -21,8 +21,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. # export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_generator" -export TFS_COMPONENTS="context device pathcomp service nbi webui" - +export TFS_COMPONENTS="context device pathcomp service slice nbi webui" # Uncomment to activate Monitoring #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -42,7 +41,6 @@ export TFS_COMPONENTS="context device pathcomp service nbi webui" # Uncomment to activate VNT Manager export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" - # Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" @@ -53,7 +51,7 @@ export TFS_K8S_NAMESPACE="tfs-ip" export TFS_EXTRA_MANIFESTS="src/tests/ecoc24/tfs-ingress-ip.yaml" # Uncomment to monitor performance of components -export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" +#export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yaml" # Uncomment when deploying Optical CyberSecurity #export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/cachingservice.yaml" @@ -62,7 +60,7 @@ export TFS_EXTRA_MANIFESTS="${TFS_EXTRA_MANIFESTS} manifests/servicemonitors.yam export TFS_GRAFANA_PASSWORD="admin123+" # Disable skip-build flag to rebuild the Docker images. -export TFS_SKIP_BUILD="YES" +export TFS_SKIP_BUILD="" # ----- CockroachDB ------------------------------------------------------------ -- GitLab From 43844fc4830de45abe75081a1096e0e8b67cb656 Mon Sep 17 00:00:00 2001 From: mansoca Date: Wed, 17 Apr 2024 15:52:46 +0200 Subject: [PATCH 06/13] some fixes --- deploy/subscription_ws.sh | 19 ++++- manifests/e2e_orchestratorservice.yaml | 2 +- my_deploy.sh | 4 +- .../E2EOrchestratorServiceServicerImpl.py | 48 ++++++++---- .../nbi_plugins/tfs_api/Resources.py | 16 ++-- .../rest_server/nbi_plugins/tfs_api/Tools.py | 7 +- .../service/VNTManagerServiceServicerImpl.py | 77 +++++++++++++------ 7 files changed, 118 insertions(+), 55 deletions(-) diff --git a/deploy/subscription_ws.sh b/deploy/subscription_ws.sh index 133abd396..a3d2f939e 100755 --- a/deploy/subscription_ws.sh +++ b/deploy/subscription_ws.sh @@ -21,11 +21,11 @@ # If not already set, set the namespace where CockroackDB will be deployed. export SUBSCRIPTION_WS_NAMESPACE=${SUBSCRIPTION_WS_NAMESPACE:-"tfs"} -# If not already set, set the internal port interface will be exposed to. -export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8765"} - # If not already set, set the external port interface will be exposed to. export SUBSCRIPTION_WS_EXT_PORT=${SUBSCRIPTION_WS_EXT_PORT:-"8765"} + +# If not already set, set the external port interface will be exposed to. +export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8765"} ######################################################################################################################## # Automated steps start here ######################################################################################################################## @@ -43,3 +43,16 @@ kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress -- echo + +echo "Subscription WebSocket Port Mapping" +echo ">>> ExposeSubscription WebSocket port (${SUBSCRIPTION_WS_INT_PORT}->${SUBSCRIPTION_WS_INT_PORT})" +PATCH='{"data": {"'${SUBSCRIPTION_WS_INT_PORT}'": "'${SUBSCRIPTION_WS_NAMESPACE}'/nbiservice:'${SUBSCRIPTION_WS_INT_PORT}'"}}' +kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" + +PORT_MAP='{"containerPort": '${SUBSCRIPTION_WS_INT_PORT}', "hostPort": '${SUBSCRIPTION_WS_INT_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 + + diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index 9763b7a56..dfbfff816 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -40,7 +40,7 @@ spec: - containerPort: 8765 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:10050"] diff --git a/my_deploy.sh b/my_deploy.sh index deb0d8562..1c12f5b96 100755 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -57,10 +57,10 @@ export TFS_COMPONENTS="context device pathcomp service slice nbi webui load_gene #export TFS_COMPONENTS="${TFS_COMPONENTS} forecaster" # Uncomment to activate E2E Orchestrator -#export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" +export TFS_COMPONENTS="${TFS_COMPONENTS} e2e_orchestrator" # Uncomment to activate VNT Manager -#export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" +export TFS_COMPONENTS="${TFS_COMPONENTS} vnt_manager" # Set the tag you want to use for your images. export TFS_IMAGE_TAG="dev" diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index cf4475ad0..1fe4d0478 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -21,13 +21,14 @@ from websockets.sync.client import connect import time from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply -from common.proto.context_pb2 import Empty, Connection, EndPointId +from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from context.service.database.uuids.EndPoint import endpoint_get_uuid from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest, VNTSubscriptionReply from common.tools.grpc.Tools import grpc_message_to_json_string from websockets.sync.server import serve +import json LOGGER = logging.getLogger(__name__) @@ -36,10 +37,6 @@ METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") context_client: ContextClient = ContextClient() -def event_received(websocket): - for message in websocket: - LOGGER.info("Message received!!!: {}".format(message)) - websocket.send(message) class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): @@ -52,7 +49,7 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): LOGGER.info("Requesting subscription") self.RequestSubscription() except Exception as E: - LOGGER.info("Exception!: {}".format(E)) + LOGGER.info("Exception0!: {}".format(E)) @@ -108,13 +105,17 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): path.connections.append(conn) def RequestSubscription(self): - HOST = "10.1.1.83" - PORT = str(8765) + LOGGER.info("Trying to connect...!!!") + OWN_HOST = "10.1.1.83" + OWN_PORT = "8765" - url = "ws://" + str(HOST) + ":" + str(PORT) + EXT_HOST = "10.1.1.83" + EXT_PORT = "8765" + + url = "ws://" + EXT_HOST + ":" + EXT_PORT request = VNTSubscriptionRequest() - request.host = HOST - request.port = PORT + request.host = OWN_HOST + request.port = OWN_PORT LOGGER.info("Trying to connect... to {}".format(url)) with connect(url, logger=LOGGER) as websocket: send = grpc_message_to_json_string(request) @@ -132,13 +133,32 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): LOGGER.info('Exception2!: {}'.format(e)) - with serve(event_received, HOST, PORT, logger=LOGGER) as server: - LOGGER.info("Running subscription server...: {}:{}".format(HOST, str(PORT))) + with serve(self._event_received, "0.0.0.0", OWN_PORT, logger=LOGGER) as server: + LOGGER.info("Running subscription server...: {}:{}".format("0.0.0.0", OWN_PORT)) server.serve_forever() LOGGER.info("Exiting subscription server...") - + def _event_received(self, websocket): + for message in websocket: + LOGGER.info("Message received!!!: {}".format(message)) + message_json = json.loads(message) + if 'event_type' in message_json: + + pass + elif 'link_id' in message_json: + obj = Link(**message_json) + if self._check_policies(obj): + pass + elif 'link_uuid' in message_json: + obj = LinkId(**message_json) + + websocket.send(message) + + + def _check_policies(self, link): + return True + diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py index 876877c25..abf240fb7 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py @@ -22,7 +22,7 @@ from service.client.ServiceClient import ServiceClient from vnt_manager.client.VNTManagerClient import VNTManagerClient from .Tools import ( - format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link_id, grpc_policy_rule_id, + format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link, grpc_link_id, grpc_policy_rule_id, grpc_service_id, grpc_service, grpc_slice_id, grpc_topology_id) class _Resource(Resource): @@ -191,21 +191,21 @@ class Link(_Resource): class VirtualLinkIds(_Resource): def get(self): - return format_grpc_to_json(self.vntmanager_client.ListLinkIds(Empty())) + return format_grpc_to_json(self.vntmanager_client.ListVirtualLinkIds(Empty())) class VirtualLinks(_Resource): def get(self): - return format_grpc_to_json(self.vntmanager_client.ListLinks(Empty())) + return format_grpc_to_json(self.vntmanager_client.ListVirtualLinks(Empty())) class VirtualLink(_Resource): def get(self, link_uuid : str): - return format_grpc_to_json(self.vntmanager_client.GetLink(grpc_link_id(link_uuid))) - def post(self, link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.GetVirtualLink(grpc_link_id(link_uuid))) + def post(self): link = request.get_json() - return format_grpc_to_json(self.vntmanager_client.SetLink(grpc_link_id(link))) - def put(self, link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) + def put(self): link = request.get_json() - return format_grpc_to_json(self.vntmanager_client.SetLink(grpc_link_id(link))) + return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) def delete(self, link_uuid : str): return format_grpc_to_json(self.vntmanager_client.RemoveVirtualLink(grpc_link_id(link_uuid))) diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py index fd5eb2316..d101a6569 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py @@ -14,7 +14,7 @@ from flask.json import jsonify from common.proto.context_pb2 import ( - ConnectionId, ContextId, DeviceId, LinkId, ServiceId, SliceId, TopologyId, Service, ServiceStatusEnum + ConnectionId, ContextId, DeviceId, Link, LinkId, ServiceId, SliceId, TopologyId, Service, ServiceStatusEnum ) from common.proto.policy_pb2 import PolicyRuleId from common.tools.grpc.Tools import grpc_message_to_json @@ -24,7 +24,7 @@ from common.tools.object_factory.ConfigRule import json_config_rule from common.tools.object_factory.Constraint import json_constraint_custom from common.tools.object_factory.EndPoint import json_endpoint_id from common.tools.object_factory.Device import json_device_id -from common.tools.object_factory.Link import json_link_id +from common.tools.object_factory.Link import json_link_id, json_link from common.tools.object_factory.PolicyRule import json_policyrule_id from common.tools.object_factory.Service import json_service_id, json_service from common.tools.object_factory.Slice import json_slice_id @@ -46,6 +46,9 @@ def grpc_device_id(device_uuid): def grpc_link_id(link_uuid): return LinkId(**json_link_id(link_uuid)) +def grpc_link(link): + return Link(**json_link(link.link_id.uuid, link.link_endpoint_ids)) + def grpc_service_id(context_uuid, service_uuid): return ServiceId(**json_service_id(service_uuid, context_id=json_context_id(context_uuid))) diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index e2b110de0..9d2e8364a 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -60,6 +60,16 @@ HOST = "10.1.1.83" PORT = str(8765) +def send_msg(url, msg): + LOGGER.info("Sending event to {}".format(url)) + with connect(url, logger=LOGGER) as websocket: + send = grpc_message_to_json_string(msg) + LOGGER.info("Sending {}".format(send)) + websocket.send(send) + message = websocket.recv() + LOGGER.info("Received ws: {}".format(message)) + + class VNTMEventDispatcher(threading.Thread): def __init__(self, host, port) -> None: @@ -90,27 +100,24 @@ class VNTMEventDispatcher(threading.Thread): activate_connection_collector = False,) events_collector.start() - while not self._terminate.is_set(): - event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) - if event is None: continue - url = "ws://" + str(self.host) + ":" + str(self.port) - request = VNTSubscriptionRequest() - request.host = self.host - request.port = self.port - LOGGER.info("Sending event to {}".format(url)) - with connect(url, logger=LOGGER) as websocket: - send = grpc_message_to_json_string(request) - LOGGER.info("Sending {}".format(send)) - websocket.send(send) - message = websocket.recv() - LOGGER.info("Received ws: {}".format(message)) + url = "ws://" + str(self.host) + ":" + str(self.port) - - events_collector.stop() + request = VNTSubscriptionRequest() + request.host = str(self.host) + request.port = str(self.port) + + send_msg(url, request) + while not self._terminate.is_set(): + event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) + if event is None: continue + + send_msg(url, event) + + events_collector.stop() class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @@ -129,6 +136,8 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): reply.subscription = "OK" event_dispatcher = VNTMEventDispatcher(request.host, int(request.port)) + self.host = request.host + self.port = request.port event_dispatcher.start() @@ -144,21 +153,39 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Link: - for link in self.links: - if link.link_uuid.uuid == request.uuid: - return link + try: + url = "ws://" + str(self.host) + ":" + str(self.port) + send_msg(url, request) + except Exception as e: + LOGGER.error('Exection getting virtual link={}\n\t{}'.format(request.link_uuid.uuid, e)) + else: + for link in self.links: + if link.link_uuid.uuid == request.uuid: + return link return Empty() @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetVirtualLink(self, request : Link, context : grpc.ServicerContext) -> LinkId: - self.links.append(request) - return request.linkd_id + try: + url = "ws://" + str(self.host) + ":" + str(self.port) + send_msg(url, request) + except Exception as e: + LOGGER.error('Exection setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) + else: + self.links.append(request) + return request.linkd_id @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty: - for link in self.links: - if link.link_uuid.uuid == request.uuid: - self.links.remove(link) - return Empty() + try: + url = "ws://" + str(self.host) + ":" + str(self.port) + send_msg(url, request) + except Exception as e: + LOGGER.error('Exection removing virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) + else: + for link in self.links: + if link.link_uuid.uuid == request.uuid: + self.links.remove(link) + return Empty() return Empty() -- GitLab From 62d6c3d6f74dee3d06ac11b632e5d6d2ad78af9a Mon Sep 17 00:00:00 2001 From: mansoca Date: Fri, 19 Apr 2024 13:15:15 +0200 Subject: [PATCH 07/13] small fixes --- deploy/all.sh | 3 +- ...scription_ws.sh => subscription_ws_e2e.sh} | 23 +++------- deploy/subscription_ws_ip.sh | 45 +++++++++++++++++++ manifests/e2e_orchestratorservice.yaml | 9 ++-- manifests/nbiservice.yaml | 24 +++++++--- manifests/vnt_managerservice.yaml | 4 -- .../E2EOrchestratorServiceServicerImpl.py | 19 +++++--- .../context_subscription/__init__.py | 2 +- src/tests/ecoc24/.gitignore | 2 - src/tests/ecoc24/deploy.sh | 11 +++-- .../descriptors/emulated/dc-2-dc-service.json | 41 +++++++++++++++++ .../descriptors/emulated/descriptor_e2e.json | 20 +++++++++ .../descriptors/emulated/descriptor_ip.json | 40 +++++++++++++++++ src/tests/ecoc24/fast_redeploy.sh | 42 ++++++++--------- .../ecoc24/nginx-ingress-controller-e2e.yaml | 4 ++ .../ecoc24/nginx-ingress-controller-ip.yaml | 4 ++ 16 files changed, 224 insertions(+), 69 deletions(-) rename deploy/{subscription_ws.sh => subscription_ws_e2e.sh} (65%) create mode 100755 deploy/subscription_ws_ip.sh delete mode 100644 src/tests/ecoc24/.gitignore create mode 100644 src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json create mode 100644 src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json create mode 100644 src/tests/ecoc24/descriptors/emulated/descriptor_ip.json diff --git a/deploy/all.sh b/deploy/all.sh index d99ffa88c..e7aabff0c 100755 --- a/deploy/all.sh +++ b/deploy/all.sh @@ -176,7 +176,8 @@ export GRAF_EXT_PORT_HTTP=${GRAF_EXT_PORT_HTTP:-"3000"} ./deploy/tfs.sh #Configure Subscription WS -#./deploy/subscription_ws.sh +./deploy/subscription_ws_ip.sh +./deploy/subscription_ws_e2e.sh # Show deploy summary ./deploy/show.sh diff --git a/deploy/subscription_ws.sh b/deploy/subscription_ws_e2e.sh similarity index 65% rename from deploy/subscription_ws.sh rename to deploy/subscription_ws_e2e.sh index a3d2f939e..1aeb41965 100755 --- a/deploy/subscription_ws.sh +++ b/deploy/subscription_ws_e2e.sh @@ -19,13 +19,12 @@ ######################################################################################################################## # If not already set, set the namespace where CockroackDB will be deployed. -export SUBSCRIPTION_WS_NAMESPACE=${SUBSCRIPTION_WS_NAMESPACE:-"tfs"} +export SUBSCRIPTION_WS_NAMESPACE=${SUBSCRIPTION_WS_NAMESPACE:-"tfs-e2e"} # If not already set, set the external port interface will be exposed to. -export SUBSCRIPTION_WS_EXT_PORT=${SUBSCRIPTION_WS_EXT_PORT:-"8765"} +export SUBSCRIPTION_WS_EXT_PORT=${SUBSCRIPTION_WS_EXT_PORT:-"8761"} + -# If not already set, set the external port interface will be exposed to. -export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8765"} ######################################################################################################################## # Automated steps start here ######################################################################################################################## @@ -34,25 +33,13 @@ export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8765"} echo "Subscription WebSocket Port Mapping" echo ">>> ExposeSubscription WebSocket port (${SUBSCRIPTION_WS_EXT_PORT}->${SUBSCRIPTION_WS_EXT_PORT})" PATCH='{"data": {"'${SUBSCRIPTION_WS_EXT_PORT}'": "'${SUBSCRIPTION_WS_NAMESPACE}'/nbiservice:'${SUBSCRIPTION_WS_EXT_PORT}'"}}' -kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" +kubectl patch configmap nginx-ingress-tcp-microk8s-conf-e2e --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${SUBSCRIPTION_WS_EXT_PORT}', "hostPort": '${SUBSCRIPTION_WS_EXT_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}" +kubectl patch daemonset nginx-ingress-microk8s-controller-e2e --namespace ingress --patch "${PATCH}" echo -echo "Subscription WebSocket Port Mapping" -echo ">>> ExposeSubscription WebSocket port (${SUBSCRIPTION_WS_INT_PORT}->${SUBSCRIPTION_WS_INT_PORT})" -PATCH='{"data": {"'${SUBSCRIPTION_WS_INT_PORT}'": "'${SUBSCRIPTION_WS_NAMESPACE}'/nbiservice:'${SUBSCRIPTION_WS_INT_PORT}'"}}' -kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" - -PORT_MAP='{"containerPort": '${SUBSCRIPTION_WS_INT_PORT}', "hostPort": '${SUBSCRIPTION_WS_INT_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 - - diff --git a/deploy/subscription_ws_ip.sh b/deploy/subscription_ws_ip.sh new file mode 100755 index 000000000..77310ed09 --- /dev/null +++ b/deploy/subscription_ws_ip.sh @@ -0,0 +1,45 @@ +#!/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 SUBSCRIPTION_WS_NAMESPACE=${SUBSCRIPTION_WS_NAMESPACE:-"tfs-ip"} + +# If not already set, set the external port interface will be exposed to. +export SUBSCRIPTION_WS_INT_PORT=${SUBSCRIPTION_WS_INT_PORT:-"8762"} +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + + + + +echo "Subscription WebSocket Port Mapping" +echo ">>> ExposeSubscription WebSocket port (${SUBSCRIPTION_WS_INT_PORT}->${SUBSCRIPTION_WS_INT_PORT})" +PATCH='{"data": {"'${SUBSCRIPTION_WS_INT_PORT}'": "'${SUBSCRIPTION_WS_NAMESPACE}'/nbiservice:'${SUBSCRIPTION_WS_INT_PORT}'"}}' +kubectl patch configmap nginx-ingress-tcp-microk8s-conf-ip --namespace ingress --patch "${PATCH}" + +PORT_MAP='{"containerPort": '${SUBSCRIPTION_WS_INT_PORT}', "hostPort": '${SUBSCRIPTION_WS_INT_PORT}'}' +CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' +PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' +kubectl patch daemonset nginx-ingress-microk8s-controller-ip --namespace ingress --patch "${PATCH}" +echo + + + diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index dfbfff816..c02823c9f 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -24,8 +24,7 @@ spec: template: metadata: annotations: - config.linkerd.io/skip-outbound-ports: "8765" - config.linkerd.io/skip-inbound-ports: "8765" + config.linkerd.io/skip-outbound-ports: "8761" labels: app: e2e-orchestratorservice spec: @@ -37,7 +36,7 @@ spec: ports: - containerPort: 10050 - containerPort: 9192 - - containerPort: 8765 + - containerPort: 8761 env: - name: LOG_LEVEL value: "DEBUG" @@ -73,5 +72,5 @@ spec: port: 9192 targetPort: 9192 - name: ws - port: 8765 - targetPort: 8765 + port: 8761 + targetPort: 8761 diff --git a/manifests/nbiservice.yaml b/manifests/nbiservice.yaml index 1d0ffc1a1..df3bde883 100644 --- a/manifests/nbiservice.yaml +++ b/manifests/nbiservice.yaml @@ -24,8 +24,8 @@ spec: template: metadata: annotations: - config.linkerd.io/skip-outbound-ports: "8765" - config.linkerd.io/skip-inbound-ports: "8765" + config.linkerd.io/skip-inbound-ports: "8762" + config.linkerd.io/skip-outbound-ports: "8762" labels: app: nbiservice spec: @@ -38,7 +38,7 @@ spec: - containerPort: 8080 - containerPort: 9090 - containerPort: 9192 - - containerPort: 8765 + - containerPort: 8762 env: - name: LOG_LEVEL value: "INFO" @@ -79,7 +79,19 @@ spec: protocol: TCP port: 9192 targetPort: 9192 - - name: websocket + - name: ws protocol: TCP - port: 8765 - targetPort: 8765 + port: 8762 + targetPort: 8762 +--- +apiVersion: v1 +kind: Service +metadata: + name: remote-teraflow +spec: + type: ExternalName + externalName: nbiservice.asdf.svc.cluster.local + ports: + - name: ws + protocol: TCP + port: 8762 diff --git a/manifests/vnt_managerservice.yaml b/manifests/vnt_managerservice.yaml index 0aca37806..cb060a5b6 100644 --- a/manifests/vnt_managerservice.yaml +++ b/manifests/vnt_managerservice.yaml @@ -37,7 +37,6 @@ spec: ports: - containerPort: 10070 - containerPort: 9192 - - containerPort: 8765 env: - name: LOG_LEVEL value: "INFO" @@ -72,6 +71,3 @@ spec: - name: metrics port: 9192 targetPort: 9192 - - name: ws - port: 8765 - targetPort: 8765 diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index 1fe4d0478..b00bbb732 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -44,7 +44,7 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): LOGGER.debug("Creating Servicer...") LOGGER.debug("Servicer Created") - time.sleep(15) + time.sleep(5) try: LOGGER.info("Requesting subscription") self.RequestSubscription() @@ -106,18 +106,22 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): def RequestSubscription(self): LOGGER.info("Trying to connect...!!!") - OWN_HOST = "10.1.1.83" - OWN_PORT = "8765" - EXT_HOST = "10.1.1.83" - EXT_PORT = "8765" + EXT_HOST = "nbiservice.tfs-ip.svc.cluster.local" + EXT_PORT = "8762" + OWN_HOST = "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" + OWN_PORT = "8761" + + + url = "ws://" + EXT_HOST + ":" + EXT_PORT request = VNTSubscriptionRequest() request.host = OWN_HOST request.port = OWN_PORT LOGGER.info("Trying to connect... to {}".format(url)) - with connect(url, logger=LOGGER) as websocket: + with connect(url) as websocket: + LOGGER.info("CONNECTED!!! {}") send = grpc_message_to_json_string(request) LOGGER.info("Sending {}".format(send)) websocket.send(send) @@ -132,7 +136,8 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): except Exception as e: LOGGER.info('Exception2!: {}'.format(e)) - + + with serve(self._event_received, "0.0.0.0", OWN_PORT, logger=LOGGER) as server: LOGGER.info("Running subscription server...: {}:{}".format("0.0.0.0", OWN_PORT)) server.serve_forever() diff --git a/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py b/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py index d5deb9352..eb841cb7f 100644 --- a/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py +++ b/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py @@ -36,7 +36,7 @@ vnt_manager_client: VNTManagerClient = VNTManagerClient() context_client: ContextClient = ContextClient() HOST = "0.0.0.0" -PORT = 8765 +PORT = 8762 LOGGER = logging.getLogger(__name__) diff --git a/src/tests/ecoc24/.gitignore b/src/tests/ecoc24/.gitignore deleted file mode 100644 index 0a3f4400d..000000000 --- a/src/tests/ecoc24/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc. -descriptors_real.json diff --git a/src/tests/ecoc24/deploy.sh b/src/tests/ecoc24/deploy.sh index 10a31ebc3..7b65822aa 100755 --- a/src/tests/ecoc24/deploy.sh +++ b/src/tests/ecoc24/deploy.sh @@ -25,12 +25,15 @@ kubectl delete -f ./src/tests/ecoc24/nginx-ingress-controller-ip.yaml kubectl apply -f ./src/tests/ecoc24/nginx-ingress-controller-e2e.yaml kubectl apply -f ./src/tests/ecoc24/nginx-ingress-controller-ip.yaml -# Deploy TFS for e2e -source ./src/tests/ecoc24/deploy_specs_e2e.sh -./deploy/all.sh -mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh # Deploy TFS for ip source ./src/tests/ecoc24/deploy_specs_ip.sh ./deploy/all.sh mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_ip.sh + + +# Deploy TFS for e2e +source ./src/tests/ecoc24/deploy_specs_e2e.sh +./deploy/all.sh +mv tfs_runtime_env_vars.sh tfs_runtime_env_vars_e2e.sh + diff --git a/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json b/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json new file mode 100644 index 000000000..7c3be015d --- /dev/null +++ b/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json @@ -0,0 +1,41 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "dc-2-dc-svc"} + }, + "service_type": 2, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id":{"device_uuid":{"uuid":"DC1"}},"endpoint_uuid":{"uuid":"int"}}, + {"device_id":{"device_uuid":{"uuid":"DC2"}},"endpoint_uuid":{"uuid":"int"}} + ], + "service_constraints": [ + {"sla_capacity": {"capacity_gbps": 10.0}}, + {"sla_latency": {"e2e_latency_ms": 15.2}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], "bgp_as": 65000, "bgp_route_target": "65000:123", + "mtu": 1512, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE1]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.1", + "address_ip": "3.3.1.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE2]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.2", + "address_ip": "3.3.2.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE3]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.3", + "address_ip": "3.3.3.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}}, + {"action": 1, "custom": {"resource_key": "/device[PE4]/endpoint[1/1]/settings", "resource_value": { + "route_distinguisher": "65000:123", "router_id": "10.0.0.4", + "address_ip": "3.3.4.1", "address_prefix": 24, "sub_interface_index": 1, "vlan_id": 300 + }}} + ]} + } + ] +} diff --git a/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json b/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json new file mode 100644 index 000000000..93acb6faa --- /dev/null +++ b/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json @@ -0,0 +1,20 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "scheme": "http", "username": "admin", "password": "admin" + }}} + ]} + } + ] +} diff --git a/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json b/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json new file mode 100644 index 000000000..d0fd09350 --- /dev/null +++ b/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json @@ -0,0 +1,40 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "PE1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + }, + { + "device_id": {"device_uuid": {"uuid": "PE2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ + {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, + {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + ]}}} + ]} + } + ] +} diff --git a/src/tests/ecoc24/fast_redeploy.sh b/src/tests/ecoc24/fast_redeploy.sh index 0a6d9bf32..2b18e9a84 100755 --- a/src/tests/ecoc24/fast_redeploy.sh +++ b/src/tests/ecoc24/fast_redeploy.sh @@ -17,37 +17,37 @@ kubectl delete namespace tfs-e2e tfs-ip echo "Deploying tfs-e2e ..." -kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl create namespace tfs-e2e > ./tmp/logs/deploy-tfs-e2e.log -kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/e2eorchestratorservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-e2e.log -kubectl --namespace tfs-e2e apply -f ecoc24/tfs-ingress-e2e.yaml > ./tmp/logs/deploy-tfs-e2e.log +kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl create namespace tfs-e2e > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-e2e.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/contextservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/deviceservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/e2e_orchestratorservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/pathcompservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/serviceservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/sliceservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f ./tmp/tfs-e2e/manifests/webuiservice.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log +kubectl --namespace tfs-e2e apply -f src/tests/ecoc24/tfs-ingress-e2e.yaml > ./tmp/tfs-e2e/logs/deploy-tfs-e2e.log printf "\n" echo "Deploying tfs-ip ..." kubectl delete -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log kubectl create namespace tfs-ip > ./tmp/logs/deploy-tfs-ip.log kubectl apply -f src/tests/ecoc24/nginx-ingress-controller-ip.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/vntmanagerservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ./tmp/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-ip.log -kubectl --namespace tfs-ip apply -f ecoc24/tfs-ingress-ip.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/contextservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/deviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/pathcompservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/serviceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/sliceservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/vnt_managerservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f ./tmp/tfs-ip/manifests/webuiservice.yaml > ./tmp/logs/deploy-tfs-ip.log +kubectl --namespace tfs-ip apply -f src/tests/ecoc24/tfs-ingress-ip.yaml > ./tmp/logs/deploy-tfs-ip.log printf "\n" echo "Waiting tfs-e2e ..." kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/contextservice kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/deviceservice -kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/e2eorchestratorservice +kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/e2e-orchestratorservice kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/pathcompservice kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/serviceservice kubectl wait --namespace tfs-e2e --for='condition=available' --timeout=300s deployment/sliceservice @@ -60,7 +60,7 @@ kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deplo kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/pathcompservice kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/serviceservice kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/sliceservice -kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/vntmanagerservice +kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/vnt-managerservice kubectl wait --namespace tfs-ip --for='condition=available' --timeout=300s deployment/webuiservice printf "\n" diff --git a/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml index 2e7ca2ca4..aa41ad916 100644 --- a/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +++ b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml @@ -122,6 +122,10 @@ spec: containerPort: 10254 hostPort: 12541 protocol: TCP + - name: ws + containerPort: 8761 + hostPort: 8761 + protocol: TCP args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-e2e diff --git a/src/tests/ecoc24/nginx-ingress-controller-ip.yaml b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml index 0160b7bba..8969297d6 100644 --- a/src/tests/ecoc24/nginx-ingress-controller-ip.yaml +++ b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml @@ -122,6 +122,10 @@ spec: containerPort: 10254 hostPort: 12542 protocol: TCP + - name: ws + containerPort: 8762 + hostPort: 8762 + protocol: TCP args: - /nginx-ingress-controller - --configmap=$(POD_NAMESPACE)/nginx-load-balancer-microk8s-conf-ip -- GitLab From 6a7296e4eb977f501da1531377c28e1288aba376 Mon Sep 17 00:00:00 2001 From: mansoca Date: Mon, 22 Apr 2024 13:35:23 +0000 Subject: [PATCH 08/13] Fixes --- manifests/e2e_orchestratorservice.yaml | 3 + .../E2EOrchestratorServiceServicerImpl.py | 157 ++++++++++-------- src/nbi/Dockerfile | 5 +- src/nbi/service/__main__.py | 2 +- .../context_subscription/__init__.py | 16 +- .../service/VNTManagerServiceServicerImpl.py | 56 +++---- 6 files changed, 121 insertions(+), 118 deletions(-) rename src/nbi/service/{rest_server/nbi_plugins => }/context_subscription/__init__.py (86%) diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index c02823c9f..be2277408 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -25,6 +25,9 @@ spec: metadata: annotations: config.linkerd.io/skip-outbound-ports: "8761" + config.linkerd.io/skip-inbound-ports: "8761" + + labels: app: e2e-orchestratorservice spec: diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index b00bbb732..fe8d27fe5 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -12,23 +12,23 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging - -import networkx as nx -import grpc import copy -from websockets.sync.client import connect -import time from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from context.service.database.uuids.EndPoint import endpoint_get_uuid -from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest, VNTSubscriptionReply +from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest from common.tools.grpc.Tools import grpc_message_to_json_string -from websockets.sync.server import serve +import grpc import json +import logging +import networkx as nx +from threading import Thread +import time +from websockets.sync.client import connect +from websockets.sync.server import serve LOGGER = logging.getLogger(__name__) @@ -37,6 +37,78 @@ METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") context_client: ContextClient = ContextClient() +EXT_HOST = "nbiservice.tfs-ip.svc.cluster.local" +EXT_PORT = "8762" + +OWN_HOST = "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" +OWN_PORT = "8761" + + + +def _event_received(websocket): + for message in websocket: + LOGGER.info("Message received!!!: {}".format(message)) + message_json = json.loads(message) + + if 'event_type' in message_json: + pass + + elif 'link_id' in message_json: + obj = Link(**message_json) + if _check_policies(obj): + pass + + elif 'link_uuid' in message_json: + obj = LinkId(**message_json) + + websocket.send(message) + + +def _check_policies(link): + return True + + + +def requestSubscription(): + url = "ws://" + EXT_HOST + ":" + EXT_PORT + request = VNTSubscriptionRequest() + request.host = OWN_HOST + request.port = OWN_PORT + LOGGER.debug("Trying to connect to {}".format(url)) + try: + websocket = connect(url) + LOGGER.debug("Connected to {}".format(url)) + except Exception as ex: + LOGGER.error('Error connecting to {}'.format(url)) + else: + with websocket: + LOGGER.debug("Connected to {}".format(url)) + send = grpc_message_to_json_string(request) + LOGGER.debug("Sending {}".format(send)) + websocket.send(send) + try: + message = websocket.recv() + LOGGER.debug("Received message from WebSocket: {}".format(message)) + except Exception as ex: + LOGGER.info('Exception receiving from WebSocket: {}'.format(ex)) + + events_server() + LOGGER.info('Subscription requested') + + +def events_server(): + all_hosts = "0.0.0.0" + + try: + server = serve(_event_received, all_hosts, int(OWN_PORT)) + except Exception as ex: + LOGGER.error('Error starting server on {}:{}'.format(all_hosts, OWN_PORT)) + LOGGER.error('Exception: {}'.format(ex)) + with server: + LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) + server.serve_forever() + LOGGER.info("Exiting events server...") + class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): @@ -47,9 +119,10 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): time.sleep(5) try: LOGGER.info("Requesting subscription") - self.RequestSubscription() - except Exception as E: - LOGGER.info("Exception0!: {}".format(E)) + subscription_thread = Thread(target=requestSubscription) + subscription_thread.start() + except Exception as ex: + LOGGER.info("Exception!: {}".format(ex)) @@ -104,66 +177,4 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): path.connections.append(conn) - def RequestSubscription(self): - LOGGER.info("Trying to connect...!!!") - - EXT_HOST = "nbiservice.tfs-ip.svc.cluster.local" - EXT_PORT = "8762" - - OWN_HOST = "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" - OWN_PORT = "8761" - - - - url = "ws://" + EXT_HOST + ":" + EXT_PORT - request = VNTSubscriptionRequest() - request.host = OWN_HOST - request.port = OWN_PORT - LOGGER.info("Trying to connect... to {}".format(url)) - with connect(url) as websocket: - LOGGER.info("CONNECTED!!! {}") - send = grpc_message_to_json_string(request) - LOGGER.info("Sending {}".format(send)) - websocket.send(send) - - try: - message = websocket.recv() - except Exception as e: - LOGGER.info('Exception1!: {}'.format(e)) - - try: - LOGGER.info("Received ws: {}".format(message)) - except Exception as e: - LOGGER.info('Exception2!: {}'.format(e)) - - - - with serve(self._event_received, "0.0.0.0", OWN_PORT, logger=LOGGER) as server: - LOGGER.info("Running subscription server...: {}:{}".format("0.0.0.0", OWN_PORT)) - server.serve_forever() - LOGGER.info("Exiting subscription server...") - - - - - def _event_received(self, websocket): - for message in websocket: - LOGGER.info("Message received!!!: {}".format(message)) - message_json = json.loads(message) - if 'event_type' in message_json: - - pass - elif 'link_id' in message_json: - obj = Link(**message_json) - if self._check_policies(obj): - pass - elif 'link_uuid' in message_json: - obj = LinkId(**message_json) - - websocket.send(message) - - - def _check_policies(self, link): - return True - diff --git a/src/nbi/Dockerfile b/src/nbi/Dockerfile index 33f229534..06e8c21a6 100644 --- a/src/nbi/Dockerfile +++ b/src/nbi/Dockerfile @@ -89,9 +89,8 @@ COPY src/service/__init__.py service/__init__.py COPY src/service/client/. service/client/ COPY src/slice/__init__.py slice/__init__.py COPY src/slice/client/. slice/client/ -# COPY src/vnt_manager/__init__.py vnt_manager/__init__.py -# COPY src/vnt_manager/client/. vnt_manager/client/ -COPY --chown=teraflow:teraflow ./src/vnt_manager/. vnt_manager +COPY src/vnt_manager/__init__.py vnt_manager/__init__.py +COPY src/vnt_manager/client/. vnt_manager/client/ RUN mkdir -p /var/teraflow/tests/tools COPY src/tests/tools/mock_osm/. tests/tools/mock_osm/ diff --git a/src/nbi/service/__main__.py b/src/nbi/service/__main__.py index 67bf06267..9fb439e16 100644 --- a/src/nbi/service/__main__.py +++ b/src/nbi/service/__main__.py @@ -26,7 +26,7 @@ from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn from .rest_server.nbi_plugins.ietf_network import register_ietf_network from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss from .rest_server.nbi_plugins.tfs_api import register_tfs_api -from .rest_server.nbi_plugins.context_subscription import register_context_subscription +from .context_subscription import register_context_subscription terminate = threading.Event() LOGGER = None diff --git a/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py b/src/nbi/service/context_subscription/__init__.py similarity index 86% rename from src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py rename to src/nbi/service/context_subscription/__init__.py index eb841cb7f..33451e2fb 100644 --- a/src/nbi/service/rest_server/nbi_plugins/context_subscription/__init__.py +++ b/src/nbi/service/context_subscription/__init__.py @@ -50,25 +50,17 @@ def register_context_subscription(): def subcript_to_vnt_manager(websocket): for message in websocket: - LOGGER.info("Message received: {}".format(message)) + LOGGER.debug("Message received: {}".format(message)) message_json = json.loads(message) request = VNTSubscriptionRequest() request.host = message_json['host'] request.port = message_json['port'] - LOGGER.info("Received gRPC from ws: {}".format(request)) + LOGGER.debug("Received gRPC from ws: {}".format(request)) - reply = VNTSubscriptionReply() try: vntm_reply = vnt_manager_client.VNTSubscript(request) - LOGGER.info("Received gRPC from vntm: {}".format(vntm_reply)) + LOGGER.debug("Received gRPC from vntm: {}".format(vntm_reply)) except Exception as e: LOGGER.error('Could not subscript to VTNManager: {}'.format(e)) - reply.subscription = "NOT OK" - else: - reply.subscription = "OK" - - - websocket.send(reply.subscription) - - + websocket.send(vntm_reply.subscription) diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index 9d2e8364a..c4d3388df 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -40,7 +40,8 @@ from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERD from typing import Any, Dict, Set from common.proto.dlt_gateway_pb2 import DltRecordEvent, DltRecordOperationEnum, DltRecordTypeEnum from common.tools.grpc.Tools import grpc_message_to_json_string - +from common.tools.grpc.Tools import grpc_message_to_json +import time LOGGER = logging.getLogger(__name__) @@ -60,14 +61,10 @@ HOST = "10.1.1.83" PORT = str(8765) -def send_msg(url, msg): - LOGGER.info("Sending event to {}".format(url)) - with connect(url, logger=LOGGER) as websocket: - send = grpc_message_to_json_string(msg) - LOGGER.info("Sending {}".format(send)) - websocket.send(send) - message = websocket.recv() - LOGGER.info("Received ws: {}".format(message)) +def send_msg(websocket, msg): + send = grpc_message_to_json_string(msg) + websocket.send(send) + message = websocket.recv() @@ -88,7 +85,7 @@ class VNTMEventDispatcher(threading.Thread): self._terminate.set() def run(self) -> None: - LOGGER.info('Thread running!') + time.sleep(10) events_collector = EventsCollector( context_client, log_events_received=True, activate_context_collector = True, @@ -102,22 +99,24 @@ class VNTMEventDispatcher(threading.Thread): url = "ws://" + str(self.host) + ":" + str(self.port) + LOGGER.debug('Connecting to {}'.format(url)) + try: + websocket = connect(url) + except Exception as ex: + LOGGER.error('Error connecting to {}'.format(url)) + else: + LOGGER.debug('Connected to {}'.format(url)) + with websocket: + send_msg(websocket, "HOLA") - request = VNTSubscriptionRequest() - request.host = str(self.host) - request.port = str(self.port) - - - send_msg(url, request) - - while not self._terminate.is_set(): - event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) - if event is None: continue + while not self._terminate.is_set(): + event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) + if event is None: continue - send_msg(url, event) - - events_collector.stop() + send_msg(websocket, event) + + events_collector.stop() class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @@ -129,13 +128,12 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def VNTSubscript(self, request: VNTSubscriptionRequest, context: grpc.ServicerContext) -> VNTSubscriptionReply: - LOGGER.info('----------------') - LOGGER.info(request) - LOGGER.info('----------------') + LOGGER.info("Subscript request: {:s}".format(str(grpc_message_to_json(request)))) reply = VNTSubscriptionReply() reply.subscription = "OK" event_dispatcher = VNTMEventDispatcher(request.host, int(request.port)) + self.host = request.host self.port = request.port event_dispatcher.start() @@ -157,7 +155,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): url = "ws://" + str(self.host) + ":" + str(self.port) send_msg(url, request) except Exception as e: - LOGGER.error('Exection getting virtual link={}\n\t{}'.format(request.link_uuid.uuid, e)) + LOGGER.error('Exception getting virtual link={}\n\t{}'.format(request.link_uuid.uuid, e)) else: for link in self.links: if link.link_uuid.uuid == request.uuid: @@ -170,7 +168,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): url = "ws://" + str(self.host) + ":" + str(self.port) send_msg(url, request) except Exception as e: - LOGGER.error('Exection setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) + LOGGER.error('Exception setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) else: self.links.append(request) return request.linkd_id @@ -181,7 +179,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): url = "ws://" + str(self.host) + ":" + str(self.port) send_msg(url, request) except Exception as e: - LOGGER.error('Exection removing virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) + LOGGER.error('Exception removing virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) else: for link in self.links: if link.link_uuid.uuid == request.uuid: -- GitLab From aa273225711a44e9430a84326ec2366a7b23cb7a Mon Sep 17 00:00:00 2001 From: mansoca Date: Tue, 23 Apr 2024 14:14:55 +0000 Subject: [PATCH 09/13] Topology events loads in e2e --- manifests/e2e_orchestratorservice.yaml | 2 +- .../E2EOrchestratorServiceServicerImpl.py | 38 ++++++++---- .../service/VNTManagerServiceServicerImpl.py | 60 ++++++++++++------- 3 files changed, 64 insertions(+), 36 deletions(-) diff --git a/manifests/e2e_orchestratorservice.yaml b/manifests/e2e_orchestratorservice.yaml index be2277408..2c2fbdd08 100644 --- a/manifests/e2e_orchestratorservice.yaml +++ b/manifests/e2e_orchestratorservice.yaml @@ -42,7 +42,7 @@ spec: - containerPort: 8761 env: - name: LOG_LEVEL - value: "DEBUG" + value: "INFO" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:10050"] diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index fe8d27fe5..fb285e50f 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -15,7 +15,7 @@ import copy from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply -from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId +from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from context.service.database.uuids.EndPoint import endpoint_get_uuid @@ -31,9 +31,11 @@ from websockets.sync.client import connect from websockets.sync.server import serve LOGGER = logging.getLogger(__name__) +logging.getLogger("websockets").propagate = False METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") + context_client: ContextClient = ContextClient() @@ -44,16 +46,11 @@ OWN_HOST = "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" OWN_PORT = "8761" - def _event_received(websocket): for message in websocket: - LOGGER.info("Message received!!!: {}".format(message)) message_json = json.loads(message) - if 'event_type' in message_json: - pass - - elif 'link_id' in message_json: + if 'link_id' in message_json: obj = Link(**message_json) if _check_policies(obj): pass @@ -61,7 +58,25 @@ def _event_received(websocket): elif 'link_uuid' in message_json: obj = LinkId(**message_json) - websocket.send(message) + else: + topology_details = TopologyDetails(**message_json) + + context_id = topology_details.topology_id.context_id + context = Context() + context.context_id.CopyFrom(context_id) + context_client.SetContext(context) + + topology_id = topology_details.topology_id + topology = Topology() + topology.topology_id.CopyFrom(topology_id) + context_client.SetTopology(topology) + + for device in topology_details.devices: + context_client.SetDevice(device) + + for link in topology_details.links: + context_client.SetLink(link) + def _check_policies(link): @@ -69,6 +84,7 @@ def _check_policies(link): + def requestSubscription(): url = "ws://" + EXT_HOST + ":" + EXT_PORT request = VNTSubscriptionRequest() @@ -77,15 +93,14 @@ def requestSubscription(): LOGGER.debug("Trying to connect to {}".format(url)) try: websocket = connect(url) - LOGGER.debug("Connected to {}".format(url)) except Exception as ex: LOGGER.error('Error connecting to {}'.format(url)) else: with websocket: LOGGER.debug("Connected to {}".format(url)) send = grpc_message_to_json_string(request) - LOGGER.debug("Sending {}".format(send)) websocket.send(send) + LOGGER.debug("Sent: {}".format(send)) try: message = websocket.recv() LOGGER.debug("Received message from WebSocket: {}".format(message)) @@ -103,7 +118,7 @@ def events_server(): server = serve(_event_received, all_hosts, int(OWN_PORT)) except Exception as ex: LOGGER.error('Error starting server on {}:{}'.format(all_hosts, OWN_PORT)) - LOGGER.error('Exception: {}'.format(ex)) + LOGGER.error('Exception!: {}'.format(ex)) with server: LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) server.serve_forever() @@ -116,7 +131,6 @@ class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): LOGGER.debug("Creating Servicer...") LOGGER.debug("Servicer Created") - time.sleep(5) try: LOGGER.info("Requesting subscription") subscription_thread = Thread(target=requestSubscription) diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index c4d3388df..a4e84be6c 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -61,10 +61,14 @@ HOST = "10.1.1.83" PORT = str(8765) -def send_msg(websocket, msg): - send = grpc_message_to_json_string(msg) - websocket.send(send) - message = websocket.recv() +WEBSOCKET = None + +def send_msg(msg): + LOGGER.info('-------------------------SENDING------------------------------') + LOGGER.info(msg) + LOGGER.info('-------------------------------------------------------') + WEBSOCKET.send(msg) + message = WEBSOCKET.recv() @@ -85,10 +89,12 @@ class VNTMEventDispatcher(threading.Thread): self._terminate.set() def run(self) -> None: - time.sleep(10) + global WEBSOCKET + + time.sleep(5) events_collector = EventsCollector( context_client, log_events_received=True, - activate_context_collector = True, + activate_context_collector = False, activate_topology_collector = True, activate_device_collector = False, activate_link_collector = False, @@ -102,21 +108,33 @@ class VNTMEventDispatcher(threading.Thread): LOGGER.debug('Connecting to {}'.format(url)) try: - websocket = connect(url) + WEBSOCKET = connect(url) except Exception as ex: LOGGER.error('Error connecting to {}'.format(url)) else: - LOGGER.debug('Connected to {}'.format(url)) - with websocket: - send_msg(websocket, "HOLA") + LOGGER.info('Connected to {}'.format(url)) + context_id = json_context_id(DEFAULT_CONTEXT_NAME) + topology_id = json_topology_id(DEFAULT_TOPOLOGY_NAME, context_id) + + try: + topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id)) + except Exception as ex: + LOGGER.warning('No topology found') + else: + send_msg(grpc_message_to_json_string(topology_details)) - while not self._terminate.is_set(): - event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) - if event is None: continue + LOGGER.info('aaaaaaaaaaaaaaaaa') + while not self._terminate.is_set(): + event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) + if event is None: continue + LOGGER.info('event!: {}'.format(event)) + topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id)) - send_msg(websocket, event) - - events_collector.stop() + to_send = grpc_message_to_json_string(topology_details) + + send_msg(to_send) + + events_collector.stop() class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @@ -138,7 +156,6 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): self.port = request.port event_dispatcher.start() - return reply @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) @@ -152,8 +169,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Link: try: - url = "ws://" + str(self.host) + ":" + str(self.port) - send_msg(url, request) + send_msg(request) except Exception as e: LOGGER.error('Exception getting virtual link={}\n\t{}'.format(request.link_uuid.uuid, e)) else: @@ -165,8 +181,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetVirtualLink(self, request : Link, context : grpc.ServicerContext) -> LinkId: try: - url = "ws://" + str(self.host) + ":" + str(self.port) - send_msg(url, request) + send_msg(request) except Exception as e: LOGGER.error('Exception setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) else: @@ -176,8 +191,7 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty: try: - url = "ws://" + str(self.host) + ":" + str(self.port) - send_msg(url, request) + send_msg(request) except Exception as e: LOGGER.error('Exception removing virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) else: -- GitLab From c98b136b3f8449cc219ce6fd9d09efa219eda9af Mon Sep 17 00:00:00 2001 From: mansoca Date: Tue, 30 Apr 2024 16:10:51 +0000 Subject: [PATCH 10/13] update --- manifests/nbiservice.yaml | 14 +----- proto/context.proto | 1 + src/e2e_orchestrator/Dockerfile | 1 + .../E2EOrchestratorServiceServicerImpl.py | 22 +++++--- .../nbi_plugins/tfs_api/Resources.py | 28 ++++++++--- .../rest_server/nbi_plugins/tfs_api/Tools.py | 2 +- .../descriptors/emulated/dc-2-dc-service.json | 9 +++- .../descriptors/emulated/descriptor_e2e.json | 20 -------- .../descriptors/emulated/descriptor_ip.json | 22 +++----- .../descriptors/emulated/link_mapping.json | 34 +++++++++++++ src/tests/ecoc24/tfs-ingress-e2e.yaml | 7 +++ src/tests/ecoc24/tfs-ingress-ip.yaml | 7 +++ .../service/VNTManagerServiceServicerImpl.py | 50 ++++++++----------- 13 files changed, 127 insertions(+), 90 deletions(-) delete mode 100644 src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json create mode 100644 src/tests/ecoc24/descriptors/emulated/link_mapping.json diff --git a/manifests/nbiservice.yaml b/manifests/nbiservice.yaml index df3bde883..e77cb35c7 100644 --- a/manifests/nbiservice.yaml +++ b/manifests/nbiservice.yaml @@ -41,7 +41,7 @@ spec: - containerPort: 8762 env: - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:9090"] @@ -83,15 +83,3 @@ spec: protocol: TCP port: 8762 targetPort: 8762 ---- -apiVersion: v1 -kind: Service -metadata: - name: remote-teraflow -spec: - type: ExternalName - externalName: nbiservice.asdf.svc.cluster.local - ports: - - name: ws - protocol: TCP - port: 8762 diff --git a/proto/context.proto b/proto/context.proto index a4cc4c6a7..ae5d77c67 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -259,6 +259,7 @@ message Link { string name = 2; repeated EndPointId link_endpoint_ids = 3; LinkAttributes attributes = 4; + bool virtual = 5; } message LinkIdList { diff --git a/src/e2e_orchestrator/Dockerfile b/src/e2e_orchestrator/Dockerfile index 85b7f1666..382424694 100644 --- a/src/e2e_orchestrator/Dockerfile +++ b/src/e2e_orchestrator/Dockerfile @@ -79,6 +79,7 @@ RUN python3 -m pip install -r e2e_orchestrator/requirements.txt # Add component files into working directory COPY --chown=teraflow:teraflow ./src/context/. context COPY --chown=teraflow:teraflow ./src/e2e_orchestrator/. e2e_orchestrator +COPY --chown=teraflow:teraflow ./src/service/. service # Start the service ENTRYPOINT ["python", "-m", "e2e_orchestrator.service"] diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index fb285e50f..991ad149a 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -15,9 +15,10 @@ import copy from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply -from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context +from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context, Service from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient +from service.client.ServiceClient import ServiceClient from context.service.database.uuids.EndPoint import endpoint_get_uuid from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest from common.tools.grpc.Tools import grpc_message_to_json_string @@ -37,7 +38,7 @@ METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") context_client: ContextClient = ContextClient() - +service_client: ServiceClient = ServiceClient() EXT_HOST = "nbiservice.tfs-ip.svc.cluster.local" EXT_PORT = "8762" @@ -51,12 +52,17 @@ def _event_received(websocket): message_json = json.loads(message) if 'link_id' in message_json: - obj = Link(**message_json) - if _check_policies(obj): - pass + link = Link(**message_json) + + service = Service() + service.service_id = link.link_id.link_uuid + service.serivice_type = 2 # Optical + service.service_status = 1 + + # service_client.CreateService(service) + + websocket.send(message) - elif 'link_uuid' in message_json: - obj = LinkId(**message_json) else: topology_details = TopologyDetails(**message_json) @@ -72,9 +78,11 @@ def _event_received(websocket): context_client.SetTopology(topology) for device in topology_details.devices: + LOGGER.info('Setting Device: {}'.format(device)) context_client.SetDevice(device) for link in topology_details.links: + LOGGER.info('Setting Link: {}'.format(link)) context_client.SetLink(link) diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py index abf240fb7..126885e70 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py @@ -20,11 +20,17 @@ from common.tools.grpc.Tools import grpc_message_to_json from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient from vnt_manager.client.VNTManagerClient import VNTManagerClient +import logging + + from .Tools import ( format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link, grpc_link_id, grpc_policy_rule_id, grpc_service_id, grpc_service, grpc_slice_id, grpc_topology_id) +LOGGER = logging.getLogger(__name__) + + class _Resource(Resource): def __init__(self) -> None: super().__init__() @@ -198,16 +204,26 @@ class VirtualLinks(_Resource): return format_grpc_to_json(self.vntmanager_client.ListVirtualLinks(Empty())) class VirtualLink(_Resource): - def get(self, link_uuid : str): - return format_grpc_to_json(self.vntmanager_client.GetVirtualLink(grpc_link_id(link_uuid))) - def post(self): + def get(self, virtual_link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.GetVirtualLink(grpc_link_id(virtual_link_uuid))) + def post(self, virtual_link_uuid : str): # pylint: disable=unused-argument link = request.get_json() + LOGGER.info('---------------------------LINK received------------------------------') + LOGGER.info(link) + LOGGER.info('----------------------------------------------------------------------') + LOGGER.info(link['link_id']) + LOGGER.info('type: {}'.format(type(link['link_id']))) + LOGGER.info('---------------------------LINK received------------------------------') + link = grpc_link(link) + + + return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) - def put(self): + def put(self, virtual_link_uuid : str): # pylint: disable=unused-argument link = request.get_json() return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) - def delete(self, link_uuid : str): - return format_grpc_to_json(self.vntmanager_client.RemoveVirtualLink(grpc_link_id(link_uuid))) + def delete(self, virtual_link_uuid : str): + return format_grpc_to_json(self.vntmanager_client.RemoveVirtualLink(grpc_link_id(virtual_link_uuid))) class ConnectionIds(_Resource): def get(self, context_uuid : str, service_uuid : str): diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py index d101a6569..773c31636 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Tools.py @@ -47,7 +47,7 @@ def grpc_link_id(link_uuid): return LinkId(**json_link_id(link_uuid)) def grpc_link(link): - return Link(**json_link(link.link_id.uuid, link.link_endpoint_ids)) + return Link(**json_link(link['link_id']['link_uuid']['uuid'], link['link_endpoint_ids'])) def grpc_service_id(context_uuid, service_uuid): return ServiceId(**json_service_id(service_uuid, context_id=json_context_id(context_uuid))) diff --git a/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json b/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json index 7c3be015d..44c80ad46 100644 --- a/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json +++ b/src/tests/ecoc24/descriptors/emulated/dc-2-dc-service.json @@ -2,7 +2,14 @@ "services": [ { "service_id": { - "context_id": {"context_uuid": {"uuid": "admin"}}, "service_uuid": {"uuid": "dc-2-dc-svc"} + "context_id": { + "context_uuid": { + "uuid": "admin" + } + }, + "service_uuid": { + "uuid": "dc-2-dc-svc" + } }, "service_type": 2, "service_status": {"service_status": 1}, diff --git a/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json b/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json deleted file mode 100644 index 93acb6faa..000000000 --- a/src/tests/ecoc24/descriptors/emulated/descriptor_e2e.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "contexts": [ - {"context_id": {"context_uuid": {"uuid": "admin"}}} - ], - "topologies": [ - {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} - ], - "devices": [ - { - "device_id": {"device_uuid": {"uuid": "TFS-IP"}}, "device_type": "teraflowsdn", "device_drivers": [7], - "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ - {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, - {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8002"}}, - {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { - "scheme": "http", "username": "admin", "password": "admin" - }}} - ]} - } - ] -} diff --git a/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json b/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json index d0fd09350..516a8bdeb 100644 --- a/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json +++ b/src/tests/ecoc24/descriptors/emulated/descriptor_ip.json @@ -7,32 +7,26 @@ ], "devices": [ { - "device_id": {"device_uuid": {"uuid": "PE1"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_id": {"device_uuid": {"uuid": "IP1"}}, "device_type": "emu-packet-router", "device_drivers": [0], "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ - {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, - {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + {"sample_types": [], "type": "copper/internal", "uuid": "CTP1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "CTP2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "CTP3"} ]}}} ]} }, { - "device_id": {"device_uuid": {"uuid": "PE2"}}, "device_type": "emu-packet-router", "device_drivers": [0], + "device_id": {"device_uuid": {"uuid": "IP2"}}, "device_type": "emu-packet-router", "device_drivers": [0], "device_endpoints": [], "device_operational_status": 0, "device_config": {"config_rules": [ {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "127.0.0.1"}}, {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "0"}}, {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"endpoints": [ - {"sample_types": [], "type": "copper/internal", "uuid": "1/1"}, - {"sample_types": [], "type": "copper/internal", "uuid": "1/2"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/1"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/2"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/3"}, - {"sample_types": [], "type": "copper/internal", "uuid": "2/4"} + {"sample_types": [], "type": "copper/internal", "uuid": "CTP1"}, + {"sample_types": [], "type": "copper/internal", "uuid": "CTP2"}, + {"sample_types": [], "type": "copper/internal", "uuid": "CTP3"} ]}}} ]} } diff --git a/src/tests/ecoc24/descriptors/emulated/link_mapping.json b/src/tests/ecoc24/descriptors/emulated/link_mapping.json new file mode 100644 index 000000000..9ac5a2599 --- /dev/null +++ b/src/tests/ecoc24/descriptors/emulated/link_mapping.json @@ -0,0 +1,34 @@ +{ + "contexts": [ + {"context_id": {"context_uuid": {"uuid": "admin"}}} + ], + "topologies": [ + {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}} + ], + "links": [ + {"link_id": {"link_uuid": {"uuid": "IP1_CTP1-MGON1_OTP1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP1"}}, "endpoint_uuid": {"uuid": "CTP1"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON1"}}, "endpoint_uuid": {"uuid": "OTP1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "IP1_CTP2-MGON1_OTP2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP1"}}, "endpoint_uuid": {"uuid": "CTP2"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON1"}}, "endpoint_uuid": {"uuid": "OTP2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "IP1CTP3-MGON1_OTP3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP1"}}, "endpoint_uuid": {"uuid": "CTP3"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON1"}}, "endpoint_uuid": {"uuid": "OTP3"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "IP2_CTP1-MGON3_OTP1"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP2"}}, "endpoint_uuid": {"uuid": "CTP1"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON3"}}, "endpoint_uuid": {"uuid": "OTP1"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "IP2_CTP2-MGON3_OTP2"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP2"}}, "endpoint_uuid": {"uuid": "CTP2"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON3"}}, "endpoint_uuid": {"uuid": "OTP2"}} + ]}, + {"link_id": {"link_uuid": {"uuid": "IP2_CTP3-MGON3_OTP3"}}, "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "IP2"}}, "endpoint_uuid": {"uuid": "CTP3"}}, + {"device_id": {"device_uuid": {"uuid": "MG-ON3"}}, "endpoint_uuid": {"uuid": "OTP3"}} + ]} + ] +} diff --git a/src/tests/ecoc24/tfs-ingress-e2e.yaml b/src/tests/ecoc24/tfs-ingress-e2e.yaml index 0ba8a08d5..352d5effc 100644 --- a/src/tests/ecoc24/tfs-ingress-e2e.yaml +++ b/src/tests/ecoc24/tfs-ingress-e2e.yaml @@ -51,3 +51,10 @@ spec: name: nbiservice port: number: 8080 + - path: /()(tfs-api/.*) + pathType: Prefix + backend: + service: + name: nbiservice + port: + number: 8080 diff --git a/src/tests/ecoc24/tfs-ingress-ip.yaml b/src/tests/ecoc24/tfs-ingress-ip.yaml index 56cec1360..2e8d30778 100644 --- a/src/tests/ecoc24/tfs-ingress-ip.yaml +++ b/src/tests/ecoc24/tfs-ingress-ip.yaml @@ -51,3 +51,10 @@ spec: name: nbiservice port: number: 8080 + - path: /()(tfs-api/.*) + pathType: Prefix + backend: + service: + name: nbiservice + port: + number: 8080 \ No newline at end of file diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index a4e84be6c..ce77bc9ee 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -42,6 +42,8 @@ from common.proto.dlt_gateway_pb2 import DltRecordEvent, DltRecordOperationEnum, from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json import time +import json + LOGGER = logging.getLogger(__name__) @@ -68,7 +70,6 @@ def send_msg(msg): LOGGER.info(msg) LOGGER.info('-------------------------------------------------------') WEBSOCKET.send(msg) - message = WEBSOCKET.recv() @@ -123,17 +124,19 @@ class VNTMEventDispatcher(threading.Thread): else: send_msg(grpc_message_to_json_string(topology_details)) - LOGGER.info('aaaaaaaaaaaaaaaaa') while not self._terminate.is_set(): + event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) if event is None: continue - LOGGER.info('event!: {}'.format(event)) + LOGGER.info('event!!!!!!!!!!!!!!!!!!!!!!: {}'.format(event)) topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id)) + LOGGER.info('topodetails..................................... ') to_send = grpc_message_to_json_string(topology_details) send_msg(to_send) + LOGGER.info('Exiting') events_collector.stop() @@ -158,46 +161,37 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): return reply - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) - def ListVirtualLinkIds(self, request : Empty, context : grpc.ServicerContext) -> LinkIdList: - return LinkIdList(link_ids=[link.link_id for link in self.links]) + """ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) + def ListVirtualLinkIds(self, request : Empty, context : grpc.ServicerContext) -> LinkIdList: + return [link for link in context_client.ListLinks(Empty()) if link.virtual] + return LinkIdList(link_ids=[link.link_id for link in self.links]) + """ @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ListVirtualLinks(self, request : Empty, context : grpc.ServicerContext) -> LinkList: - return LinkList(link=self.links) + return [link for link in context_client.ListLinks(Empty()).links if link.virtual] @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Link: - try: - send_msg(request) - except Exception as e: - LOGGER.error('Exception getting virtual link={}\n\t{}'.format(request.link_uuid.uuid, e)) - else: - for link in self.links: - if link.link_uuid.uuid == request.uuid: - return link - return Empty() + link = context_client.GetLink(request) + return link if link.virtual else Empty() + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetVirtualLink(self, request : Link, context : grpc.ServicerContext) -> LinkId: try: send_msg(request) + message = WEBSOCKET.recv() + message_json = json.loads(message) + link = Link(**message_json) + context_client.SetLink(link) + except Exception as e: LOGGER.error('Exception setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) - else: - self.links.append(request) - return request.linkd_id + return request.linkd_id @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty: - try: - send_msg(request) - except Exception as e: - LOGGER.error('Exception removing virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) - else: - for link in self.links: - if link.link_uuid.uuid == request.uuid: - self.links.remove(link) - return Empty() + # TODO return Empty() -- GitLab From 8b07c76ac2517f69df8fb1f811c24062be817043 Mon Sep 17 00:00:00 2001 From: mansoca Date: Wed, 8 May 2024 09:11:38 +0000 Subject: [PATCH 11/13] update --- .../E2EOrchestratorServiceServicerImpl.py | 75 ++++++++++++------- .../service/context_subscription/__init__.py | 3 +- .../nbi_plugins/tfs_api/Resources.py | 15 +--- .../service/VNTManagerServiceServicerImpl.py | 27 ++++--- 4 files changed, 67 insertions(+), 53 deletions(-) diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index 991ad149a..2a303851c 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -15,11 +15,12 @@ import copy from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply -from common.proto.context_pb2 import Empty, Connection, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context, Service +from common.proto.context_pb2 import Empty, Connection, ContextId, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context, Service, ServiceStatus, DeviceId, ServiceTypeEnum, ServiceStatusEnum from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient from context.service.database.uuids.EndPoint import endpoint_get_uuid +from context.service.database.uuids.Device import device_get_uuid from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest from common.tools.grpc.Tools import grpc_message_to_json_string import grpc @@ -27,9 +28,10 @@ import json import logging import networkx as nx from threading import Thread -import time from websockets.sync.client import connect from websockets.sync.server import serve +from common.Constants import DEFAULT_CONTEXT_NAME + LOGGER = logging.getLogger(__name__) logging.getLogger("websockets").propagate = False @@ -55,50 +57,61 @@ def _event_received(websocket): link = Link(**message_json) service = Service() - service.service_id = link.link_id.link_uuid - service.serivice_type = 2 # Optical - service.service_status = 1 - - # service_client.CreateService(service) + service.service_id.service_uuid.uuid = link.link_id.link_uuid.uuid + service.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + service.service_type = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY + service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + service_client.CreateService(service) + + links = context_client.ListLinks(Empty()).links + a_device_uuid = device_get_uuid(link.link_endpoint_ids[0].device_id) + a_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[0])[2] + z_device_uuid = device_get_uuid(link.link_endpoint_ids[1].device_id) + z_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[1])[2] + + + for _link in links: + for _endpoint_id in _link.link_endpoint_ids: + if _endpoint_id.device_id.device_uuid.uuid == a_device_uuid and \ + _endpoint_id.endpoint_uuid.uuid == a_endpoint_uuid: + a_ep_id = _endpoint_id + elif _endpoint_id.device_id.device_uuid.uuid == z_device_uuid and \ + _endpoint_id.endpoint_uuid.uuid == z_endpoint_uuid: + z_ep_id = _endpoint_id - websocket.send(message) + service.service_endpoint_ids.append(copy.deepcopy(a_ep_id)) + service.service_endpoint_ids.append(copy.deepcopy(z_ep_id)) + + service_client.UpdateService(service) + websocket.send(grpc_message_to_json_string(link)) else: topology_details = TopologyDetails(**message_json) - context_id = topology_details.topology_id.context_id context = Context() - context.context_id.CopyFrom(context_id) + context.context_id.context_uuid.uuid = topology_details.topology_id.context_id.context_uuid.uuid context_client.SetContext(context) - topology_id = topology_details.topology_id topology = Topology() - topology.topology_id.CopyFrom(topology_id) + topology.topology_id.topology_uuid.uuid = topology_details.topology_id.topology_uuid.uuid context_client.SetTopology(topology) for device in topology_details.devices: - LOGGER.info('Setting Device: {}'.format(device)) context_client.SetDevice(device) for link in topology_details.links: - LOGGER.info('Setting Link: {}'.format(link)) context_client.SetLink(link) -def _check_policies(link): - return True - - - def requestSubscription(): url = "ws://" + EXT_HOST + ":" + EXT_PORT request = VNTSubscriptionRequest() request.host = OWN_HOST request.port = OWN_PORT - LOGGER.debug("Trying to connect to {}".format(url)) + LOGGER.debug("Connecting to {}".format(url)) try: websocket = connect(url) except Exception as ex: @@ -108,12 +121,11 @@ def requestSubscription(): LOGGER.debug("Connected to {}".format(url)) send = grpc_message_to_json_string(request) websocket.send(send) - LOGGER.debug("Sent: {}".format(send)) try: message = websocket.recv() LOGGER.debug("Received message from WebSocket: {}".format(message)) except Exception as ex: - LOGGER.info('Exception receiving from WebSocket: {}'.format(ex)) + LOGGER.error('Exception receiving from WebSocket: {}'.format(ex)) events_server() LOGGER.info('Subscription requested') @@ -127,22 +139,31 @@ def events_server(): except Exception as ex: LOGGER.error('Error starting server on {}:{}'.format(all_hosts, OWN_PORT)) LOGGER.error('Exception!: {}'.format(ex)) - with server: - LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) - server.serve_forever() - LOGGER.info("Exiting events server...") + else: + with server: + LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) + server.serve_forever() + LOGGER.info("Exiting events server...") + +class SubscriptionServer(): + class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): def __init__(self): LOGGER.debug("Creating Servicer...") LOGGER.debug("Servicer Created") try: - LOGGER.info("Requesting subscription") + LOGGER.debug("Requesting subscription") subscription_thread = Thread(target=requestSubscription) subscription_thread.start() + + + # import_optical() + + except Exception as ex: LOGGER.info("Exception!: {}".format(ex)) diff --git a/src/nbi/service/context_subscription/__init__.py b/src/nbi/service/context_subscription/__init__.py index 33451e2fb..17c8ccf5f 100644 --- a/src/nbi/service/context_subscription/__init__.py +++ b/src/nbi/service/context_subscription/__init__.py @@ -15,10 +15,9 @@ import logging from websockets.sync.server import serve -from common.proto.vnt_manager_pb2 import VNTSubscriptionReply, VNTSubscriptionRequest +from common.proto.vnt_manager_pb2 import VNTSubscriptionRequest from common.proto.context_pb2 import Empty -# from vnt_manager.client.VNTManagerClient import VNTManagerClient from context.client.ContextClient import ContextClient from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME from common.tools.object_factory.Topology import json_topology_id diff --git a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py index 126885e70..9f6b68962 100644 --- a/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py +++ b/src/nbi/service/rest_server/nbi_plugins/tfs_api/Resources.py @@ -207,18 +207,9 @@ class VirtualLink(_Resource): def get(self, virtual_link_uuid : str): return format_grpc_to_json(self.vntmanager_client.GetVirtualLink(grpc_link_id(virtual_link_uuid))) def post(self, virtual_link_uuid : str): # pylint: disable=unused-argument - link = request.get_json() - LOGGER.info('---------------------------LINK received------------------------------') - LOGGER.info(link) - LOGGER.info('----------------------------------------------------------------------') - LOGGER.info(link['link_id']) - LOGGER.info('type: {}'.format(type(link['link_id']))) - LOGGER.info('---------------------------LINK received------------------------------') - link = grpc_link(link) - - - - return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) + link_json = request.get_json() + link = grpc_link(link_json) + return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(link)) def put(self, virtual_link_uuid : str): # pylint: disable=unused-argument link = request.get_json() return format_grpc_to_json(self.vntmanager_client.SetVirtualLink(grpc_link(link))) diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index ce77bc9ee..74f233ad6 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -41,10 +41,8 @@ from typing import Any, Dict, Set from common.proto.dlt_gateway_pb2 import DltRecordEvent, DltRecordOperationEnum, DltRecordTypeEnum from common.tools.grpc.Tools import grpc_message_to_json_string from common.tools.grpc.Tools import grpc_message_to_json -import time import json - LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool("VNTManager", "RPC") @@ -66,11 +64,10 @@ PORT = str(8765) WEBSOCKET = None def send_msg(msg): - LOGGER.info('-------------------------SENDING------------------------------') - LOGGER.info(msg) - LOGGER.info('-------------------------------------------------------') - WEBSOCKET.send(msg) - + try: + WEBSOCKET.send(msg) + except Exception as e: + LOGGER.info(e) class VNTMEventDispatcher(threading.Thread): @@ -109,6 +106,7 @@ class VNTMEventDispatcher(threading.Thread): LOGGER.debug('Connecting to {}'.format(url)) try: + LOGGER.info("Connecting to events server...: {}".format(url)) WEBSOCKET = connect(url) except Exception as ex: LOGGER.error('Error connecting to {}'.format(url)) @@ -128,9 +126,7 @@ class VNTMEventDispatcher(threading.Thread): event = events_collector.get_event(block=True, timeout=GET_EVENT_TIMEOUT) if event is None: continue - LOGGER.info('event!!!!!!!!!!!!!!!!!!!!!!: {}'.format(event)) topology_details = context_client.GetTopologyDetails(TopologyId(**topology_id)) - LOGGER.info('topodetails..................................... ') to_send = grpc_message_to_json_string(topology_details) @@ -180,15 +176,22 @@ class VNTManagerServiceServicerImpl(VNTManagerServiceServicer): @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetVirtualLink(self, request : Link, context : grpc.ServicerContext) -> LinkId: try: - send_msg(request) + send_msg(grpc_message_to_json_string(request)) message = WEBSOCKET.recv() + + + + + + + + message_json = json.loads(message) link = Link(**message_json) context_client.SetLink(link) - except Exception as e: LOGGER.error('Exception setting virtual link={}\n\t{}'.format(request.link_id.link_uuid.uuid, e)) - return request.linkd_id + return request.link_id @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveVirtualLink(self, request : LinkId, context : grpc.ServicerContext) -> Empty: -- GitLab From afeea9f98bad59be647cb2a054165f3ac4e08685 Mon Sep 17 00:00:00 2001 From: mansoca Date: Wed, 8 May 2024 15:09:17 +0000 Subject: [PATCH 12/13] update --- .../E2EOrchestratorServiceServicerImpl.py | 174 +++++++++--------- 1 file changed, 85 insertions(+), 89 deletions(-) diff --git a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py index 2a303851c..afc62a686 100644 --- a/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py +++ b/src/e2e_orchestrator/service/E2EOrchestratorServiceServicerImpl.py @@ -15,7 +15,9 @@ import copy from common.method_wrappers.Decorator import MetricsPool, safe_and_metered_rpc_method from common.proto.e2eorchestrator_pb2 import E2EOrchestratorRequest, E2EOrchestratorReply -from common.proto.context_pb2 import Empty, Connection, ContextId, EndPointId, Link, LinkId, TopologyDetails, TopologyId, Device, Topology, Context, Service, ServiceStatus, DeviceId, ServiceTypeEnum, ServiceStatusEnum +from common.proto.context_pb2 import ( + Empty, Connection, EndPointId, Link, TopologyDetails, Topology, Context, Service, ServiceTypeEnum, + ServiceStatusEnum) from common.proto.e2eorchestrator_pb2_grpc import E2EOrchestratorServiceServicer from context.client.ContextClient import ContextClient from service.client.ServiceClient import ServiceClient @@ -34,7 +36,7 @@ from common.Constants import DEFAULT_CONTEXT_NAME LOGGER = logging.getLogger(__name__) -logging.getLogger("websockets").propagate = False +logging.getLogger("websockets").propagate = True METRICS_POOL = MetricsPool("E2EOrchestrator", "RPC") @@ -48,121 +50,115 @@ EXT_PORT = "8762" OWN_HOST = "e2e-orchestratorservice.tfs-e2e.svc.cluster.local" OWN_PORT = "8761" +ALL_HOSTS = "0.0.0.0" -def _event_received(websocket): - for message in websocket: - message_json = json.loads(message) - - if 'link_id' in message_json: - link = Link(**message_json) - - service = Service() - service.service_id.service_uuid.uuid = link.link_id.link_uuid.uuid - service.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME - service.service_type = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY - service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED - service_client.CreateService(service) - - links = context_client.ListLinks(Empty()).links - a_device_uuid = device_get_uuid(link.link_endpoint_ids[0].device_id) - a_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[0])[2] - z_device_uuid = device_get_uuid(link.link_endpoint_ids[1].device_id) - z_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[1])[2] - - - for _link in links: - for _endpoint_id in _link.link_endpoint_ids: - if _endpoint_id.device_id.device_uuid.uuid == a_device_uuid and \ - _endpoint_id.endpoint_uuid.uuid == a_endpoint_uuid: - a_ep_id = _endpoint_id - elif _endpoint_id.device_id.device_uuid.uuid == z_device_uuid and \ - _endpoint_id.endpoint_uuid.uuid == z_endpoint_uuid: - z_ep_id = _endpoint_id +class SubscriptionServer(Thread): + def __init__(self): + Thread.__init__(self) + + def run(self): + url = "ws://" + EXT_HOST + ":" + EXT_PORT + request = VNTSubscriptionRequest() + request.host = OWN_HOST + request.port = OWN_PORT + try: + LOGGER.debug("Trying to connect to {}".format(url)) + websocket = connect(url) + except Exception as ex: + LOGGER.error('Error connecting to {}'.format(url)) + else: + with websocket: + LOGGER.debug("Connected to {}".format(url)) + send = grpc_message_to_json_string(request) + websocket.send(send) + LOGGER.debug("Sent: {}".format(send)) + try: + message = websocket.recv() + LOGGER.debug("Received message from WebSocket: {}".format(message)) + except Exception as ex: + LOGGER.info('Exception receiving from WebSocket: {}'.format(ex)) + self._events_server() - service.service_endpoint_ids.append(copy.deepcopy(a_ep_id)) - service.service_endpoint_ids.append(copy.deepcopy(z_ep_id)) - service_client.UpdateService(service) - websocket.send(grpc_message_to_json_string(link)) + def _events_server(self): + all_hosts = "0.0.0.0" + try: + server = serve(self._event_received, all_hosts, int(OWN_PORT)) + except Exception as ex: + LOGGER.error('Error starting server on {}:{}'.format(all_hosts, OWN_PORT)) + LOGGER.error('Exception!: {}'.format(ex)) else: - topology_details = TopologyDetails(**message_json) + with server: + LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) + server.serve_forever() - context = Context() - context.context_id.context_uuid.uuid = topology_details.topology_id.context_id.context_uuid.uuid - context_client.SetContext(context) - topology = Topology() - topology.topology_id.topology_uuid.uuid = topology_details.topology_id.topology_uuid.uuid - context_client.SetTopology(topology) + def _event_received(self, connection): + for message in connection: + message_json = json.loads(message) - for device in topology_details.devices: - context_client.SetDevice(device) + if 'link_id' in message_json: + link = Link(**message_json) - for link in topology_details.links: - context_client.SetLink(link) + service = Service() + service.service_id.service_uuid.uuid = link.link_id.link_uuid.uuid + service.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME + service.service_type = ServiceTypeEnum.SERVICETYPE_OPTICAL_CONNECTIVITY + service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED + service_client.CreateService(service) + links = context_client.ListLinks(Empty()).links + a_device_uuid = device_get_uuid(link.link_endpoint_ids[0].device_id) + a_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[0])[2] + z_device_uuid = device_get_uuid(link.link_endpoint_ids[1].device_id) + z_endpoint_uuid = endpoint_get_uuid(link.link_endpoint_ids[1])[2] + for _link in links: + for _endpoint_id in _link.link_endpoint_ids: + if _endpoint_id.device_id.device_uuid.uuid == a_device_uuid and \ + _endpoint_id.endpoint_uuid.uuid == a_endpoint_uuid: + a_ep_id = _endpoint_id + elif _endpoint_id.device_id.device_uuid.uuid == z_device_uuid and \ + _endpoint_id.endpoint_uuid.uuid == z_endpoint_uuid: + z_ep_id = _endpoint_id -def requestSubscription(): - url = "ws://" + EXT_HOST + ":" + EXT_PORT - request = VNTSubscriptionRequest() - request.host = OWN_HOST - request.port = OWN_PORT - LOGGER.debug("Connecting to {}".format(url)) - try: - websocket = connect(url) - except Exception as ex: - LOGGER.error('Error connecting to {}'.format(url)) - else: - with websocket: - LOGGER.debug("Connected to {}".format(url)) - send = grpc_message_to_json_string(request) - websocket.send(send) - try: - message = websocket.recv() - LOGGER.debug("Received message from WebSocket: {}".format(message)) - except Exception as ex: - LOGGER.error('Exception receiving from WebSocket: {}'.format(ex)) - events_server() - LOGGER.info('Subscription requested') + service.service_endpoint_ids.append(copy.deepcopy(a_ep_id)) + service.service_endpoint_ids.append(copy.deepcopy(z_ep_id)) + service_client.UpdateService(service) + connection.send(grpc_message_to_json_string(link)) -def events_server(): - all_hosts = "0.0.0.0" + else: + topology_details = TopologyDetails(**message_json) - try: - server = serve(_event_received, all_hosts, int(OWN_PORT)) - except Exception as ex: - LOGGER.error('Error starting server on {}:{}'.format(all_hosts, OWN_PORT)) - LOGGER.error('Exception!: {}'.format(ex)) - else: - with server: - LOGGER.info("Running events server...: {}:{}".format(all_hosts, OWN_PORT)) - server.serve_forever() - LOGGER.info("Exiting events server...") + context = Context() + context.context_id.context_uuid.uuid = topology_details.topology_id.context_id.context_uuid.uuid + context_client.SetContext(context) + topology = Topology() + topology.topology_id.topology_uuid.uuid = topology_details.topology_id.topology_uuid.uuid + context_client.SetTopology(topology) + for device in topology_details.devices: + context_client.SetDevice(device) + + for link in topology_details.links: + context_client.SetLink(link) -class SubscriptionServer(): class E2EOrchestratorServiceServicerImpl(E2EOrchestratorServiceServicer): def __init__(self): LOGGER.debug("Creating Servicer...") - LOGGER.debug("Servicer Created") - try: LOGGER.debug("Requesting subscription") - subscription_thread = Thread(target=requestSubscription) - subscription_thread.start() - - - # import_optical() - + sub_server = SubscriptionServer() + sub_server.start() + LOGGER.debug("Servicer Created") except Exception as ex: LOGGER.info("Exception!: {}".format(ex)) -- GitLab From e85f38290dfbfb3f96bd65dc7743905d13ef2e4d Mon Sep 17 00:00:00 2001 From: mansoca Date: Wed, 8 May 2024 15:30:19 +0000 Subject: [PATCH 13/13] update license date --- deploy/subscription_ws_e2e.sh | 2 +- deploy/subscription_ws_ip.sh | 2 +- manifests/vnt_managerservice.yaml | 2 +- proto/vnt_manager.proto | 2 +- scripts/show_logs_vntmanager.sh | 2 +- src/nbi/service/context_subscription/__init__.py | 2 +- src/tests/ecoc24/__init__.py | 2 +- src/tests/ecoc24/delete.sh | 2 +- src/tests/ecoc24/deploy.sh | 2 +- src/tests/ecoc24/deploy_e2e.sh | 2 +- src/tests/ecoc24/deploy_ip.sh | 2 +- src/tests/ecoc24/deploy_specs_e2e.sh | 2 +- src/tests/ecoc24/deploy_specs_ip.sh | 2 +- src/tests/ecoc24/dump_logs.sh | 2 +- src/tests/ecoc24/fast_redeploy.sh | 2 +- src/tests/ecoc24/nginx-ingress-controller-e2e.yaml | 2 +- src/tests/ecoc24/nginx-ingress-controller-ip.yaml | 2 +- src/tests/ecoc24/show_deploy.sh | 2 +- src/tests/ecoc24/tfs-ingress-e2e.yaml | 2 +- src/tests/ecoc24/tfs-ingress-ip.yaml | 2 +- src/vnt_manager/.gitlab-ci.yml | 2 +- src/vnt_manager/Config.py | 2 +- src/vnt_manager/Dockerfile | 2 +- src/vnt_manager/__init__.py | 2 +- src/vnt_manager/client/VNTManagerClient.py | 2 +- src/vnt_manager/client/__init__.py | 2 +- src/vnt_manager/requirements.in | 2 +- src/vnt_manager/service/VNTManagerService.py | 2 +- src/vnt_manager/service/VNTManagerServiceServicerImpl.py | 2 +- src/vnt_manager/service/__init__.py | 2 +- src/vnt_manager/service/__main__.py | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/deploy/subscription_ws_e2e.sh b/deploy/subscription_ws_e2e.sh index 1aeb41965..6088871d1 100755 --- a/deploy/subscription_ws_e2e.sh +++ b/deploy/subscription_ws_e2e.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed 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/subscription_ws_ip.sh b/deploy/subscription_ws_ip.sh index 77310ed09..f5e775d45 100755 --- a/deploy/subscription_ws_ip.sh +++ b/deploy/subscription_ws_ip.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed 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/vnt_managerservice.yaml b/manifests/vnt_managerservice.yaml index cb060a5b6..f7a6213fe 100644 --- a/manifests/vnt_managerservice.yaml +++ b/manifests/vnt_managerservice.yaml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed 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/vnt_manager.proto b/proto/vnt_manager.proto index d56473522..39a52c405 100644 --- a/proto/vnt_manager.proto +++ b/proto/vnt_manager.proto @@ -1,4 +1,4 @@ -// Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +// Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) // // Licensed 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_vntmanager.sh b/scripts/show_logs_vntmanager.sh index aadc2c578..e39cb35c5 100755 --- a/scripts/show_logs_vntmanager.sh +++ b/scripts/show_logs_vntmanager.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/nbi/service/context_subscription/__init__.py b/src/nbi/service/context_subscription/__init__.py index 17c8ccf5f..a69e14e72 100644 --- a/src/nbi/service/context_subscription/__init__.py +++ b/src/nbi/service/context_subscription/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/__init__.py b/src/tests/ecoc24/__init__.py index 1549d9811..a5ccb6078 100644 --- a/src/tests/ecoc24/__init__.py +++ b/src/tests/ecoc24/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/delete.sh b/src/tests/ecoc24/delete.sh index 6ad12d15c..20b9ce9aa 100755 --- a/src/tests/ecoc24/delete.sh +++ b/src/tests/ecoc24/delete.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/deploy.sh b/src/tests/ecoc24/deploy.sh index 7b65822aa..06c54455d 100755 --- a/src/tests/ecoc24/deploy.sh +++ b/src/tests/ecoc24/deploy.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/deploy_e2e.sh b/src/tests/ecoc24/deploy_e2e.sh index 8e1041cf9..01800e043 100755 --- a/src/tests/ecoc24/deploy_e2e.sh +++ b/src/tests/ecoc24/deploy_e2e.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/deploy_ip.sh b/src/tests/ecoc24/deploy_ip.sh index f51e9762b..34e4e894e 100755 --- a/src/tests/ecoc24/deploy_ip.sh +++ b/src/tests/ecoc24/deploy_ip.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/deploy_specs_e2e.sh b/src/tests/ecoc24/deploy_specs_e2e.sh index 383a6b726..f50bc28db 100755 --- a/src/tests/ecoc24/deploy_specs_e2e.sh +++ b/src/tests/ecoc24/deploy_specs_e2e.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/deploy_specs_ip.sh b/src/tests/ecoc24/deploy_specs_ip.sh index 36e298b65..65e8db4ab 100755 --- a/src/tests/ecoc24/deploy_specs_ip.sh +++ b/src/tests/ecoc24/deploy_specs_ip.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/dump_logs.sh b/src/tests/ecoc24/dump_logs.sh index 2e41e90a4..0d8d517f1 100755 --- a/src/tests/ecoc24/dump_logs.sh +++ b/src/tests/ecoc24/dump_logs.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/fast_redeploy.sh b/src/tests/ecoc24/fast_redeploy.sh index 2b18e9a84..51f0a1a16 100755 --- a/src/tests/ecoc24/fast_redeploy.sh +++ b/src/tests/ecoc24/fast_redeploy.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/nginx-ingress-controller-e2e.yaml b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml index aa41ad916..c4fc966d1 100644 --- a/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml +++ b/src/tests/ecoc24/nginx-ingress-controller-e2e.yaml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/nginx-ingress-controller-ip.yaml b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml index 8969297d6..f8946a8a3 100644 --- a/src/tests/ecoc24/nginx-ingress-controller-ip.yaml +++ b/src/tests/ecoc24/nginx-ingress-controller-ip.yaml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/show_deploy.sh b/src/tests/ecoc24/show_deploy.sh index 63f8fae37..975047774 100755 --- a/src/tests/ecoc24/show_deploy.sh +++ b/src/tests/ecoc24/show_deploy.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/tfs-ingress-e2e.yaml b/src/tests/ecoc24/tfs-ingress-e2e.yaml index 352d5effc..c7d5551f0 100644 --- a/src/tests/ecoc24/tfs-ingress-e2e.yaml +++ b/src/tests/ecoc24/tfs-ingress-e2e.yaml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under 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/ecoc24/tfs-ingress-ip.yaml b/src/tests/ecoc24/tfs-ingress-ip.yaml index 2e8d30778..d6aa56e93 100644 --- a/src/tests/ecoc24/tfs-ingress-ip.yaml +++ b/src/tests/ecoc24/tfs-ingress-ip.yaml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/.gitlab-ci.yml b/src/vnt_manager/.gitlab-ci.yml index d1b9da495..85192054e 100644 --- a/src/vnt_manager/.gitlab-ci.yml +++ b/src/vnt_manager/.gitlab-ci.yml @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/Config.py b/src/vnt_manager/Config.py index 38d04994f..719815a42 100644 --- a/src/vnt_manager/Config.py +++ b/src/vnt_manager/Config.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/Dockerfile b/src/vnt_manager/Dockerfile index 8f40741ee..1c7137fbe 100644 --- a/src/vnt_manager/Dockerfile +++ b/src/vnt_manager/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/__init__.py b/src/vnt_manager/__init__.py index 38d04994f..719815a42 100644 --- a/src/vnt_manager/__init__.py +++ b/src/vnt_manager/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/client/VNTManagerClient.py b/src/vnt_manager/client/VNTManagerClient.py index 67850a602..74f4778ed 100644 --- a/src/vnt_manager/client/VNTManagerClient.py +++ b/src/vnt_manager/client/VNTManagerClient.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/client/__init__.py b/src/vnt_manager/client/__init__.py index 38d04994f..719815a42 100644 --- a/src/vnt_manager/client/__init__.py +++ b/src/vnt_manager/client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/requirements.in b/src/vnt_manager/requirements.in index 3f780913b..95d80d85c 100644 --- a/src/vnt_manager/requirements.in +++ b/src/vnt_manager/requirements.in @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/service/VNTManagerService.py b/src/vnt_manager/service/VNTManagerService.py index 0580d1c7f..d42e270f9 100644 --- a/src/vnt_manager/service/VNTManagerService.py +++ b/src/vnt_manager/service/VNTManagerService.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py index 74f233ad6..1b7b85f4c 100644 --- a/src/vnt_manager/service/VNTManagerServiceServicerImpl.py +++ b/src/vnt_manager/service/VNTManagerServiceServicerImpl.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/service/__init__.py b/src/vnt_manager/service/__init__.py index 38d04994f..719815a42 100644 --- a/src/vnt_manager/service/__init__.py +++ b/src/vnt_manager/service/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/vnt_manager/service/__main__.py b/src/vnt_manager/service/__main__.py index 66d3e435c..40918ecce 100644 --- a/src/vnt_manager/service/__main__.py +++ b/src/vnt_manager/service/__main__.py @@ -1,4 +1,4 @@ -# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) +# Copyright 2022-2024 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. -- GitLab