diff --git a/manifests/nginx_ingress_http.yaml b/manifests/nginx_ingress_http.yaml index e45ca65f0cb63dedd1c9ff3cc22200f3bf1c9fa1..6cccec661f8e5f0e32baaa2e3164da2c78c56444 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 648fedb9071f521695c655e5134f0ab5f9a942d0..6c7bc97176fd495fdccb871d67ca36a8c9f361a4 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 662dc389b123daabe02bedf2f43232edde8f3bc3..1feb073e66430a5d006e16c9e201a920e3fe05ff 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 0000000000000000000000000000000000000000..e4a5361b3be97d7c1b588c238a8a5821bb77ecdf --- /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 63556432be46fae44552bb2ec191e3f7eab17a99..2d3dbf858bd7de72f3333b0fb5daa852814032d8 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 2d6102a3492a8e29bf88682d1ae0cec0e327b8de..cb0d84736348a2d2eb48a36bd4e6f1aa1ddfd0d7 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 0000000000000000000000000000000000000000..e4c91e36a0efc91251e7dd8f5817136dc788b1a2 --- /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 0000000000000000000000000000000000000000..aff7c4729da477b63129546e83f254565269f812 --- /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 0000000000000000000000000000000000000000..1c51d426a437c2e4c1e0b984aa50f4b3cba92f05 --- /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 12b1d098355e6c822c87b7afe0db44b616d02488..6d7dbcfca49b94f51d84fc99bafc2b793d3733ad 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 ee3fe12fb686b54db0ccc89dcfd6b83f871766d9..28ffc70013dafa1653006ca72301b1d5d4c3e15d 100644 --- a/src/osm_client/Dockerfile +++ b/src/osm_client/Dockerfile @@ -75,5 +75,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 3e4a14b7d6013c2668186191f4534dfe858fb6ea..224e32fa0750eeeb88761dcf884924c5ff7e3a37 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 d30b581d163e5a34bf5985e79e36bb99b7c84aec..1f8303aa8435f9d606e14c6e28d4bbb2d6b849b2 100644 --- a/src/osm_client/service/OsmClientServiceServicerImpl.py +++ b/src/osm_client/service/OsmClientServiceServicerImpl.py @@ -25,6 +25,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') @@ -36,7 +37,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: @@ -54,7 +55,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)