From ae6b3f1213f70e9ed145384268024d34bd73f29e Mon Sep 17 00:00:00 2001 From: rahhal Date: Mon, 25 Aug 2025 10:56:28 +0000 Subject: [PATCH] NBI component - NBI - Connector - OSM Client : - Added NBI requirements --- manifests/nginx_ingress_http.yaml | 7 +++ manifests/osm_clientservice.yaml | 22 ++++----- my_deploy.sh | 4 +- scripts/show_logs_osm_client.sh | 27 ++++++++++ src/nbi/Dockerfile | 2 + src/nbi/service/app.py | 4 ++ src/nbi/service/osm_nbi/Resources.py | 49 +++++++++++++++++++ src/nbi/service/osm_nbi/__init__.py | 36 ++++++++++++++ src/nbi/service/osm_nbi/tools.py | 33 +++++++++++++ src/osm_client/Config.py | 2 +- src/osm_client/Dockerfile | 3 ++ src/osm_client/client/OsmClient.py | 5 +- .../service/OsmClientServiceServicerImpl.py | 4 +- 13 files changed, 180 insertions(+), 18 deletions(-) create mode 100755 scripts/show_logs_osm_client.sh create mode 100644 src/nbi/service/osm_nbi/Resources.py create mode 100644 src/nbi/service/osm_nbi/__init__.py create mode 100644 src/nbi/service/osm_nbi/tools.py diff --git a/manifests/nginx_ingress_http.yaml b/manifests/nginx_ingress_http.yaml index e45ca65f0..6cccec661 100644 --- a/manifests/nginx_ingress_http.yaml +++ b/manifests/nginx_ingress_http.yaml @@ -106,3 +106,10 @@ spec: name: nbiservice port: number: 8080 + - path: /()(osm-api/.*) + pathType: Prefix + backend: + service: + name: nbiservice + port: + number: 8080 diff --git a/manifests/osm_clientservice.yaml b/manifests/osm_clientservice.yaml index 648fedb90..6c7bc9717 100644 --- a/manifests/osm_clientservice.yaml +++ b/manifests/osm_clientservice.yaml @@ -15,16 +15,16 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: osm_clientservice + name: osm-clientservice spec: selector: matchLabels: - app: osm_clientservice + app: osm-clientservice #replicas: 1 template: metadata: labels: - app: osm_clientservice + app: osm-clientservice spec: terminationGracePeriodSeconds: 5 containers: @@ -36,9 +36,9 @@ spec: - containerPort: 9192 env: - name: OSM_ADDRESS - value: "127.0.0.1" + value: "10.1.7.199:9999" - name: LOG_LEVEL - value: "INFO" + value: "DEBUG" readinessProbe: exec: command: ["/bin/grpc_health_probe", "-addr=:30210"] @@ -47,22 +47,22 @@ spec: command: ["/bin/grpc_health_probe", "-addr=:30210"] resources: requests: - cpu: 250m + cpu: 150m memory: 128Mi limits: - cpu: 1000m - memory: 1024Mi + cpu: 500m + memory: 512Mi --- apiVersion: v1 kind: Service metadata: - name: osm_clientservice + name: osm-clientservice labels: - app: osm_clientservice + app: osm-clientservice spec: type: ClusterIP selector: - app: osm_clientservice + app: osm-clientservice ports: - name: grpc protocol: TCP diff --git a/my_deploy.sh b/my_deploy.sh index 4d3820f41..76328a114 100644 --- a/my_deploy.sh +++ b/my_deploy.sh @@ -20,7 +20,7 @@ export TFS_REGISTRY_IMAGES="http://localhost:32000/tfs/" # Set the list of components, separated by spaces, you want to build images for, and deploy. -export TFS_COMPONENTS="context device pathcomp service slice nbi webui" +export TFS_COMPONENTS="context device pathcomp service slice nbi webui osm_client" # Uncomment to activate Monitoring (old) #export TFS_COMPONENTS="${TFS_COMPONENTS} monitoring" @@ -134,7 +134,7 @@ export CRDB_PASSWORD="tfs123" export CRDB_DEPLOY_MODE="single" # Disable flag for dropping database, if it exists. -export CRDB_DROP_DATABASE_IF_EXISTS="" +export CRDB_DROP_DATABASE_IF_EXISTS="YES" # Disable flag for re-deploying CockroachDB from scratch. export CRDB_REDEPLOY="" diff --git a/scripts/show_logs_osm_client.sh b/scripts/show_logs_osm_client.sh new file mode 100755 index 000000000..e4a5361b3 --- /dev/null +++ b/scripts/show_logs_osm_client.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +######################################################################################################################## +# Define your deployment settings here +######################################################################################################################## + +# If not already set, set the name of the Kubernetes namespace to deploy to. +export TFS_K8S_NAMESPACE=${TFS_K8S_NAMESPACE:-"tfs"} + +######################################################################################################################## +# Automated steps start here +######################################################################################################################## + +kubectl --namespace $TFS_K8S_NAMESPACE logs deployment/osm-clientservice -c server \ No newline at end of file diff --git a/src/nbi/Dockerfile b/src/nbi/Dockerfile index 63556432b..2d3dbf858 100644 --- a/src/nbi/Dockerfile +++ b/src/nbi/Dockerfile @@ -85,6 +85,8 @@ COPY src/qkd_app/__init__.py qkd_app/__init__.py COPY src/qkd_app/client/. qkd_app/client/ COPY src/qos_profile/__init__.py qos_profile/__init__.py COPY src/qos_profile/client/. qos_profile/client/ +COPY src/osm_client/__init__.py osm_client/__init__.py +COPY src/osm_client/client/. osm_client/client/ 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 diff --git a/src/nbi/service/app.py b/src/nbi/service/app.py index 2d6102a34..cb0d84736 100644 --- a/src/nbi/service/app.py +++ b/src/nbi/service/app.py @@ -41,11 +41,13 @@ from .ietf_network_slice import register_ietf_nss from .qkd_app import register_qkd_app from .restconf_root import register_restconf_root from .tfs_api import register_tfs_api +from .osm_nbi import register_osm_api #from .topology_updates import register_topology_updates from .vntm_recommend import register_vntm_recommend from .well_known_meta import register_well_known + LOG_LEVEL = get_log_level() logging.basicConfig( level=LOG_LEVEL, @@ -98,6 +100,8 @@ register_qkd_app (nbi_app) #register_topology_updates(nbi_app) # does not work; check if eventlet-grpc side effects register_vntm_recommend (nbi_app) register_camara_qod (nbi_app) +register_osm_api (nbi_app) + LOGGER.info('All connectors registered') nbi_app.dump_configuration() diff --git a/src/nbi/service/osm_nbi/Resources.py b/src/nbi/service/osm_nbi/Resources.py new file mode 100644 index 000000000..e4c91e36a --- /dev/null +++ b/src/nbi/service/osm_nbi/Resources.py @@ -0,0 +1,49 @@ +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import logging +from typing import Dict, List +from flask.json import jsonify +from flask_restful import Resource, request +from common.proto.context_pb2 import Empty +from common.tools.grpc.Tools import grpc_message_to_json +from .tools import format_grpc_to_json, grpc_create #, grpc_delete_id, grpc_service_id, +from osm_client.client.OsmClient import OsmClient + +LOGGER = logging.getLogger(__name__) + +class _Resource(Resource): + def __init__(self) -> None: + super().__init__() + self.osm_client = OsmClient() + +class NS_Services(_Resource): + def get(self): + #return {"debug": "I reached this point!"} + grpc_response = self.osm_client.NsiList(Empty()) + return format_grpc_to_json(grpc_response) + #return format_grpc_to_json(self.osm_client.NsiList((Empty()))) + + def post(self): + json_requests = request.get_json() + grpc_response = self.osm_client.NsiCreate(json_requests) + return format_grpc_to_json(grpc_response) + +#class NS_Service(_Resource): +# def get(self, ns_id: str): +# return format_grpc_to_json(self.osm_client.NsiGet(grpc_service_id(ns_id))) +# +# def delete(self, ns_id : str): +# return format_grpc_to_json(self.osm_client.NsiDelete(grpc_delete_id(ns_id))) \ No newline at end of file diff --git a/src/nbi/service/osm_nbi/__init__.py b/src/nbi/service/osm_nbi/__init__.py new file mode 100644 index 000000000..aff7c4729 --- /dev/null +++ b/src/nbi/service/osm_nbi/__init__.py @@ -0,0 +1,36 @@ +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +from nbi.service.NbiApplication import NbiApplication +from .Resources import NS_Services#, NS_Service + +LOGGER = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +ENDPOINT_PREFIX = 'osm_api.' +URL_PREFIX = '/osm-api' + +_RESOURCES = [ + ('api.NS Services', NS_Services, '/NS_Services'), +# ('api.NS_Service_id', NS_Service, '/NS_Service_id'), +] + +RESOURCES = [ + (ENDPOINT_PREFIX + endpoint_name, resource_class, URL_PREFIX + resource_url) + for endpoint_name, resource_class, resource_url in _RESOURCES +] + +def register_osm_api(nbi_app : NbiApplication): + nbi_app.add_rest_api_resources(RESOURCES) diff --git a/src/nbi/service/osm_nbi/tools.py b/src/nbi/service/osm_nbi/tools.py new file mode 100644 index 000000000..1c51d426a --- /dev/null +++ b/src/nbi/service/osm_nbi/tools.py @@ -0,0 +1,33 @@ +# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Dict +from flask.json import jsonify +from common.proto.context_pb2 import (Context) +from common.proto.policy_pb2 import PolicyRule, PolicyRuleId +from common.tools.grpc.Tools import grpc_message_to_json + + + +def format_grpc_to_json(grpc_reply): + return jsonify(grpc_message_to_json(grpc_reply)) + +def grpc_create(json_requests : Dict): + return Context(**json_requests) + +#def grpc_service_id(ns_id): +# return DeviceId(**json_device_id(ns_id)) +# +#def grpc_delete_id(ns_id): +# return DeviceId(**json_device_id(ns_id)) diff --git a/src/osm_client/Config.py b/src/osm_client/Config.py index 12b1d0983..6d7dbcfca 100644 --- a/src/osm_client/Config.py +++ b/src/osm_client/Config.py @@ -14,5 +14,5 @@ from common.Settings import get_setting -DEFAULT_OSM_ADDRESS = '127.0.0.1' +DEFAULT_OSM_ADDRESS = '10.1.7.199' OSM_ADDRESS = get_setting('OSM_ADDRESS', default=DEFAULT_OSM_ADDRESS) diff --git a/src/osm_client/Dockerfile b/src/osm_client/Dockerfile index 579972127..fed665a48 100644 --- a/src/osm_client/Dockerfile +++ b/src/osm_client/Dockerfile @@ -73,5 +73,8 @@ RUN python3 -m pip install ./osmclient WORKDIR /var/teraflow COPY src/osm_client/. osm_client/ +# Disable SSL verification for requests +ENV REQUESTS_CA_BUNDLE="" + # Start the service ENTRYPOINT ["python", "-m", "osm_client.service"] diff --git a/src/osm_client/client/OsmClient.py b/src/osm_client/client/OsmClient.py index 3e4a14b7d..224e32fa0 100644 --- a/src/osm_client/client/OsmClient.py +++ b/src/osm_client/client/OsmClient.py @@ -21,8 +21,9 @@ from common.proto.context_pb2 import (Empty) from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.grpc.Tools import grpc_message_to_json_string -from osmclient import client -from osmclient.common.exceptions import ClientException +#from osm_client.client.OsmClient import OsmClient +#from osmclient import client +#from osmclient.common.exceptions import ClientException LOGGER = logging.getLogger(__name__) diff --git a/src/osm_client/service/OsmClientServiceServicerImpl.py b/src/osm_client/service/OsmClientServiceServicerImpl.py index f6b33052c..bd2eda303 100644 --- a/src/osm_client/service/OsmClientServiceServicerImpl.py +++ b/src/osm_client/service/OsmClientServiceServicerImpl.py @@ -22,6 +22,7 @@ from osmclient import client from osmclient.common.exceptions import ClientException from osm_client.Config import OSM_ADDRESS + LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('OSMCLIENT', 'RPC') @@ -33,7 +34,7 @@ class OsmClientServiceServicerImpl(OsmServiceServicer): LOGGER.info('osmClient created') LOGGER.info('Servicer Created') - + @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def NsiCreate(self, request : CreateRequest, context : grpc.ServicerContext) -> CreateResponse: try: @@ -51,7 +52,6 @@ class OsmClientServiceServicerImpl(OsmServiceServicer): resp = NsiListResponse(id=nsiIDs) return resp - @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def NsiGet(self, request : GetRequest, context : grpc.ServicerContext) -> GetResponse: nsiObject = self.myclient.nsi.get(request.id) -- GitLab