Update from master part 2
Squashed commit of the following:
commit 364627c364a86a85696781766326dd690a362bc4
Author: vegall <lvega@whitestack.com>
Date: Fri Mar 17 15:09:50 2023 +0000
Feature 10972: Support of volume multi-attach
Change-Id: I6e88ee52e5e882dbb4ec7d66cf648fbe07d40509
Signed-off-by: vegall <lvega@whitestack.com>
commit 0e51779fd37dc5c12f3bd19d78f7341ed0a67b7a
Author: gifrerenom <lluis.gifre@cttc.es>
Date: Tue Apr 18 16:38:42 2023 +0000
Feature 10937: Transport API (TAPI) WIM connector for RO
Change-Id: If0dac9f8ba2d00945eb86a89fb0b2f174c672794
Signed-off-by: gifrerenom <lluis.gifre@cttc.es>
commit 370e36bafdcb90f212e289b87290f39be141b3d4
Author: elumalai <deepika.e@tataelxsi.co.in>
Date: Tue Apr 25 16:22:56 2023 +0530
Feature 10979: Static IPv6 Dual Stack Assignment
Added support for static dual stack IP assignment
Change-Id: Ief10ae955fb870a3417f68e1c5f7bda570cb6470
Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>
commit b1bc66933aa392b9d7518f7cebc711700335389c
Author: Gabriel Cuba <gcuba@whitestack.com>
Date: Fri Aug 19 18:23:00 2022 -0500
Fix Bug 2098: Get VDUs from VNFR when Heal op has no additionalPrameters
When Heal is requested without vdu or count-index parameters, RO will recreate all VDUs from VNFR
Change-Id: Idf2cf158bcb33e7b0c307298c14504cc7aa77e2a
Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
(cherry picked from commit 2fbb3a264e4117f4a6569fede6558836d67ac4a4)
commit aba1518f487b4b65861eb30f553c4edb72ad972e
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date: Mon May 15 11:55:13 2023 +0300
Fix VimAdminThread run method
The run_coroutine_threadsafe() function is used to schedule a coroutine object from a different thread and returns a concurrent.futures.Future.
run_coroutine_threadsafe is unnecessary to run the main task and replaced with asyncio.run().
Change-Id: I8ea31828a9798140d596165443bdf26659b4eef8
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
commit f17e5bb6b6da4432628dd65ce9ad633e6441f67c
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date: Wed May 10 22:52:57 2023 +0300
Minor updates in Dockerfile
Change-Id: I79b43654d181f6976a4e544d58fb92aa1b67e760
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
commit a264b7a460b28d7454fc95fe659da46f55b0c155
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date: Tue May 9 14:57:22 2023 +0300
Ubuntu 22.04 and Python 3.10 preparation
Change-Id: I87164827a8849c16b5e3a804d9673a578e5a5593
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
commit 1c89c08a0dd1c79b5adff3ac1cc123239762e06a
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date: Tue Apr 18 15:06:30 2023 +0200
Clean stage-archive.sh and use allowlist_extenals in tox.ini
Change-Id: I18f0bc3e263063b5b1d2cf211f028f6bb0e4bceb
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
commit 51e72a0f7479b3064b4b11891eb524d42f4738b0
Author: elumalai <deepika.e@tataelxsi.co.in>
Date: Fri Apr 28 19:41:49 2023 +0530
Coverity CWE 330: Use of Insufficiently Random Values
Added support to fix CWE 330: Use of Insufficiently Random Values
Coverity issue
Change-Id: Ib12ebeeb9b0cc10af9980fe8661eb6230c2f6d6d
Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>
commit e17cd946aed699b5feca83d37591d04f129a8f52
Author: elumalai <deepika.e@tataelxsi.co.in>
Date: Fri Apr 28 18:04:24 2023 +0530
Coverity CWE 688: Function Call With Incorrect Variable or Reference as Argument
Added fix for CWE 688 Typo in Identifier
Change-Id: I53b5142451b809be638d73626265531057722169
Signed-off-by: elumalai <deepika.e@tataelxsi.co.in>
commit 730cfaff466fb3c9b1446ecef5213916195ff861
Author: Gabriel Cuba <gcuba@whitestack.com>
Date: Mon Mar 13 22:26:38 2023 -0500
Feature 10975: get flavor-id from additionalParams if specified
Change-Id: I1c9b1ec43c80f3793b475187681f4c2005d77375
Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
commit 2d3f63b055e6a38e95bcff56a8ddef32767b11ef
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date: Tue Apr 11 10:08:26 2023 +0200
Update stage-build to run tox sequentially
Change-Id: I967f19a8c35700290e93c9d8bd863b63b7c2d239
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
(cherry picked from commit ea063c7a6ae6a5d7e11e8c22f9707d5c8f674ac7)
commit b3dbfcad6f4b2bebc9ebc20fd7129a18879cb20c
Author: Gabriel Cuba <gcuba@whitestack.com>
Date: Tue Mar 14 10:58:39 2023 -0500
Feature 10978: Add support of ipv6_address_mode and ipv6_ra_mode to openstack connector
Change-Id: I8ca741a215bd2c52999dee1ea301d4e02aafcb24
Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
commit 01619d5b596e01ac8cd6d27bf01a1174e6b3f97b
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date: Wed Mar 22 22:57:26 2023 +0300
Keep vim_details while reporting VM deletion
Change-Id: I27577b2fc93a585affc947abcec8352562f23f49
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
commit 98740c03567ff8c5a22f06fd3f049248a9e5f98d
Author: Pedro Escaleira <escaleira@av.it.pt>
Date: Wed Feb 22 10:48:52 2023 +0000
Bug 2217 fixed: modified the cloud-init merge configs and defined the default SSH keys within the system_info instead of users
Change-Id: I12e26a88fb9b50c4a78b9fa8ee2cb5d4b4bf6d00
Signed-off-by: Pedro Escaleira <escaleira@av.it.pt>
commit d586d89bde00acaf22debd7f657d605c9d095571
Author: Gulsum Atici <gulsum.atici@canonical.com>
Date: Mon Feb 13 18:40:03 2023 +0300
Feature 10960 Performance optimizations for the polling of VM status in RO
Change-Id: If785bbeaab66e0839541bf94184ce37114e67bd4
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
commit 4c1dd54ae02e82f11a60058a1b7c7b0137ac572e
Author: Gabriel Cuba <gcuba@whitestack.com>
Date: Tue Feb 14 12:43:32 2023 -0500
Refactor ns.py so that RO uses the IP profile as it comes from LCM
Change-Id: I36983c86d7c76ad8a9b93eb6eae254f844717e0e
Signed-off-by: Gabriel Cuba <gcuba@whitestack.com>
commit 3822010a26b2e21290b6acdf288db277c7f36605
Author: garciadeblas <gerardo.garciadeblas@telefonica.com>
Date: Mon Feb 13 17:48:32 2023 +0100
Fix bug 2216 to remove hardcoded numa affinity in VIO
Change-Id: I0912c2841e7c5c1febe056ba092afedaea77f6a1
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
commit 778f3cc8c052bd17d0da32f07b880616d25f935a
Author: Lovejeet Singh <lovejeet.singh@hsc.com>
Date: Mon Feb 13 16:15:40 2023 +0530
Bug 2202: Adding support for cinder V3 API with V2 API for persistent volumes.
Change-Id: I7034564b91b94e6be242cb2ce0f4a5b147b87d64
Signed-off-by: Lovejeet Singh <lovejeet.singh@hsc.com>
Change-Id: I7ac1bd1d9896788812f456c678b1f5222a1f1ad6
Signed-off-by: Dario Faccin <dario.faccin@canonical.com>
diff --git a/RO-SDN-tapi/osm_rosdn_tapi/tapi_client.py b/RO-SDN-tapi/osm_rosdn_tapi/tapi_client.py
new file mode 100644
index 0000000..ad5f9f3
--- /dev/null
+++ b/RO-SDN-tapi/osm_rosdn_tapi/tapi_client.py
@@ -0,0 +1,240 @@
+# -*- coding: utf-8 -*-
+
+#######################################################################################
+# This file is part of OSM RO module
+#
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#######################################################################################
+# This work has been performed in the context of the TeraFlow Project -
+# funded by the European Commission under Grant number 101015857 through the
+# Horizon 2020 program.
+# Contributors:
+# - Lluis Gifre <lluis.gifre@cttc.es>
+# - Ricard Vilalta <ricard.vilalta@cttc.es>
+#######################################################################################
+
+"""This file contains the TransportApiClient class used by the Transport API
+(TAPI) WIM connector to interact with the underlying WIM."""
+
+import requests
+
+from .exceptions import (
+ WimTapiConnectivityServiceCreateFailed,
+ WimTapiConnectivityServiceDeleteFailed,
+ WimTapiConnectivityServiceGetStatusFailed,
+ WimTapiServerNotAvailable,
+ WimTapiServerRequestFailed,
+)
+from .log_messages import (
+ LOG_MSG_CREATE_REPLY,
+ LOG_MSG_CREATE_REQUEST,
+ LOG_MSG_DELETE_REPLY,
+ LOG_MSG_DELETE_REQUEST,
+ LOG_MSG_GET_STATUS_REPLY,
+ LOG_MSG_GET_STATUS_REQUEST,
+)
+from .message_composers import (
+ compose_create_request,
+ compose_delete_request,
+)
+
+DEFAULT_TIMEOUT = 30
+
+SUCCESS_HTTP_CODES = {
+ requests.codes.ok, # pylint: disable=no-member
+ requests.codes.created, # pylint: disable=no-member
+ requests.codes.accepted, # pylint: disable=no-member
+ requests.codes.no_content, # pylint: disable=no-member
+}
+
+RESTCONF_DATA_URL = "{:s}/restconf/data"
+RESTCONF_OPER_URL = "{:s}/restconf/operations"
+
+CONTEXT_URL = RESTCONF_DATA_URL + "/tapi-common:context"
+CTX_SIPS_URL = CONTEXT_URL + "/service-interface-point"
+CONN_CTX_URL = CONTEXT_URL + "/tapi-connectivity:connectivity-context"
+CONN_SVC_URL = CONN_CTX_URL + "/connectivity-service"
+DELETE_URL = RESTCONF_OPER_URL + "/tapi-connectivity:delete-connectivity-service"
+
+
+class TransportApiClient:
+ def __init__(self, logger, wim, wim_account, config) -> None:
+ self.logger = logger
+ self.wim_url = wim["wim_url"]
+
+ user = wim_account.get("user")
+ password = wim_account.get("password")
+ self.auth = (
+ None
+ if user is None or user == "" or password is None or password == ""
+ else (user, password)
+ )
+
+ self.headers = {"Content-Type": "application/json"}
+ self.timeout = int(config.get("timeout", DEFAULT_TIMEOUT))
+
+ def get_root_context(self):
+ context_url = CONTEXT_URL.format(self.wim_url)
+
+ try:
+ response = requests.get(
+ context_url, auth=self.auth, headers=self.headers, timeout=self.timeout
+ )
+ http_code = response.status_code
+ except requests.exceptions.RequestException as e:
+ raise WimTapiServerNotAvailable(str(e))
+
+ if http_code != 200:
+ raise WimTapiServerRequestFailed(
+ "Unexpected status code", http_code=http_code
+ )
+
+ return response.json()
+
+ def get_service_interface_points(self):
+ get_sips_url = CTX_SIPS_URL.format(self.wim_url)
+
+ try:
+ response = requests.get(
+ get_sips_url, auth=self.auth, headers=self.headers, timeout=self.timeout
+ )
+ http_code = response.status_code
+ except requests.exceptions.RequestException as e:
+ raise WimTapiServerNotAvailable(str(e))
+
+ if http_code != 200:
+ raise WimTapiServerRequestFailed(
+ "Unexpected status code", http_code=http_code
+ )
+
+ response = response.json()
+ response = response.get("tapi-common:service-interface-point", [])
+ return {sip["uuid"]: sip for sip in response}
+
+ def get_service_status(self, name, service_uuid):
+ self.logger.debug(LOG_MSG_GET_STATUS_REQUEST.format(name, service_uuid))
+
+ try:
+ services_url = CONN_SVC_URL.format(self.wim_url)
+ response = requests.get(
+ services_url, auth=self.auth, headers=self.headers, timeout=self.timeout
+ )
+ self.logger.debug(
+ LOG_MSG_GET_STATUS_REPLY.format(
+ name, service_uuid, response.status_code, response.text
+ )
+ )
+ except requests.exceptions.ConnectionError as e:
+ status_code = e.response.status_code if e.response is not None else 500
+ content = e.response.text if e.response is not None else ""
+ raise WimTapiConnectivityServiceGetStatusFailed(
+ name, service_uuid, status_code, content
+ )
+
+ if response.status_code not in SUCCESS_HTTP_CODES:
+ raise WimTapiConnectivityServiceGetStatusFailed(
+ name, service_uuid, response.status_code, response.text
+ )
+
+ json_response = response.json()
+ connectivity_services = json_response.get(
+ "tapi-connectivity:connectivity-service", []
+ )
+ connectivity_service = next(
+ iter(
+ [
+ connectivity_service
+ for connectivity_service in connectivity_services
+ if connectivity_service.get("uuid") == service_uuid
+ ]
+ ),
+ None,
+ )
+
+ if connectivity_service is None:
+ service_status = {"sdn_status": "ERROR"}
+ else:
+ service_status = {"sdn_status": "ACTIVE"}
+ return service_status
+
+ def create_service(
+ self,
+ name,
+ service_uuid,
+ service_endpoints,
+ bidirectional=False,
+ requested_capacity=None,
+ vlan_constraint=None,
+ ):
+ request_create = compose_create_request(
+ service_uuid,
+ service_endpoints,
+ bidirectional=bidirectional,
+ requested_capacity=requested_capacity,
+ vlan_constraint=vlan_constraint,
+ )
+ self.logger.debug(
+ LOG_MSG_CREATE_REQUEST.format(name, service_uuid, str(request_create))
+ )
+
+ try:
+ create_url = CONN_CTX_URL.format(self.wim_url)
+ response = requests.post(
+ create_url, headers=self.headers, json=request_create, auth=self.auth
+ )
+ self.logger.debug(
+ LOG_MSG_CREATE_REPLY.format(
+ name, service_uuid, response.status_code, response.text
+ )
+ )
+ except requests.exceptions.ConnectionError as e:
+ status_code = e.response.status_code if e.response is not None else 500
+ content = e.response.text if e.response is not None else ""
+ raise WimTapiConnectivityServiceCreateFailed(
+ name, service_uuid, status_code, content
+ )
+
+ if response.status_code not in SUCCESS_HTTP_CODES:
+ raise WimTapiConnectivityServiceCreateFailed(
+ name, service_uuid, response.status_code, response.text
+ )
+
+ def delete_service(self, name, service_uuid):
+ request_delete = compose_delete_request(service_uuid)
+ self.logger.debug(
+ LOG_MSG_DELETE_REQUEST.format(name, service_uuid, str(request_delete))
+ )
+
+ try:
+ delete_url = DELETE_URL.format(self.wim_url)
+ response = requests.post(
+ delete_url, headers=self.headers, json=request_delete, auth=self.auth
+ )
+ self.logger.debug(
+ LOG_MSG_DELETE_REPLY.format(
+ name, service_uuid, response.status_code, response.text
+ )
+ )
+ except requests.exceptions.ConnectionError as e:
+ status_code = e.response.status_code if e.response is not None else 500
+ content = e.response.text if e.response is not None else ""
+ raise WimTapiConnectivityServiceDeleteFailed(
+ name, service_uuid, status_code, content
+ )
+
+ if response.status_code not in SUCCESS_HTTP_CODES:
+ raise WimTapiConnectivityServiceDeleteFailed(
+ name, service_uuid, response.status_code, response.text
+ )