Fix Bug 2158 and Bug 2254 by arranging exception handling 47/13747/7
authorgatici <gulsum.atici@canonical.com>
Tue, 25 Jul 2023 21:34:04 +0000 (00:34 +0300)
committeraticig <gulsum.atici@canonical.com>
Thu, 10 Aug 2023 08:26:25 +0000 (10:26 +0200)
Change-Id: Id84e57944258536735eb114d4c77f471d700e1aa
Signed-off-by: gatici <gulsum.atici@canonical.com>
NG-RO/osm_ng_ro/ns_thread.py
RO-VIM-openstack/osm_rovim_openstack/tests/test_vimconn_openstack.py
RO-VIM-openstack/osm_rovim_openstack/vimconn_openstack.py
releasenotes/notes/fix_bug_2158_2254-86a20d2b2a6ca5a9.yaml [new file with mode: 0644]

index 42a8a59..e64db28 100644 (file)
@@ -644,7 +644,9 @@ class VimInteractionImage(VimInteractionBase):
             # FIND
             vim_image_id = ""
             if task.get("find_params"):
             # FIND
             vim_image_id = ""
             if task.get("find_params"):
-                vim_images = target_vim.get_image_list(**task["find_params"])
+                vim_images = target_vim.get_image_list(
+                    task["find_params"].get("filter_dict", {})
+                )
 
                 if not vim_images:
                     raise NsWorkerExceptionNotFound(
 
                 if not vim_images:
                     raise NsWorkerExceptionNotFound(
index a3da330..c287493 100644 (file)
@@ -27,15 +27,19 @@ from copy import deepcopy
 import logging
 import unittest
 
 import logging
 import unittest
 
+import cinderclient.exceptions as cExceptions
 from mock import MagicMock, patch
 from mock import MagicMock, patch
+from neutronclient.common import exceptions as neExceptions
 from novaclient import exceptions as nvExceptions
 from novaclient.exceptions import ClientException, Conflict
 from osm_ro_plugin.vimconn import (
     VimConnConnectionException,
     VimConnException,
     VimConnNotFoundException,
 from novaclient import exceptions as nvExceptions
 from novaclient.exceptions import ClientException, Conflict
 from osm_ro_plugin.vimconn import (
     VimConnConnectionException,
     VimConnException,
     VimConnNotFoundException,
+    VimConnUnexpectedResponse,
 )
 from osm_rovim_openstack.vimconn_openstack import vimconnector
 )
 from osm_rovim_openstack.vimconn_openstack import vimconnector
+from requests.exceptions import ConnectionError
 
 __author__ = "Igor D.C."
 __date__ = "$23-aug-2017 23:59:59$"
 
 __author__ = "Igor D.C."
 __date__ = "$23-aug-2017 23:59:59$"
@@ -1627,17 +1631,18 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "update_block_device_mapping")
     def test_new_shared_volumes(self, mock_update_block_device_mapping):
         """Create shared volume."""
     @patch.object(vimconnector, "update_block_device_mapping")
     def test_new_shared_volumes(self, mock_update_block_device_mapping):
         """Create shared volume."""
-        self.vimconn.cinder = CopyingMock()
-        self.vimconn.cinder.volumes.create.return_value.id = volume_id4
-        shared_volume_data = {"size": 10, "name": "shared-volume"}
-        self.vimconn.cinder.volumes.create.side_effect = [
-            Volume("avaible", "multiattach", "shared-volume", volume_id4)
-        ]
+
+        class MyVolume:
+            name = "my-shared-volume"
+            id = volume_id4
+
+        self.vimconn.cinder.volumes.create.return_value = MyVolume()
+        shared_volume_data = {"size": 10, "name": "my-shared-volume"}
         result = self.vimconn.new_shared_volumes(shared_volume_data)
         self.vimconn.cinder.volumes.create.assert_called_once_with(
         result = self.vimconn.new_shared_volumes(shared_volume_data)
         self.vimconn.cinder.volumes.create.assert_called_once_with(
-            size=10, name="shared-volume", volume_type="multiattach"
+            size=10, name="my-shared-volume", volume_type="multiattach"
         )
         )
-        self.assertEqual(result[0], "shared-volume")
+        self.assertEqual(result[0], "my-shared-volume")
         self.assertEqual(result[1], volume_id4)
 
     @patch.object(vimconnector, "update_block_device_mapping")
         self.assertEqual(result[1], volume_id4)
 
     @patch.object(vimconnector, "update_block_device_mapping")
@@ -3894,7 +3899,9 @@ class TestNewVmInstance(unittest.TestCase):
             },
         )
 
             },
         )
 
-    def test_delete_floating_ip_by_id_floating_ip_raises_nvexception(self):
+    def test_delete_floating_ip_by_id__delete_floating_ip_raises_client_exception__operation_is_successful(
+        self,
+    ):
         """netron delete floating ip raises nvExceptions.ClientException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
         """netron delete floating ip raises nvExceptions.ClientException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -3918,7 +3925,36 @@ class TestNewVmInstance(unittest.TestCase):
             "Error deleting floating ip: ClientException: Unknown Error (HTTP Client exception occurred.)"
         )
 
             "Error deleting floating ip: ClientException: Unknown Error (HTTP Client exception occurred.)"
         )
 
-    def test_delete_floating_ip_by_id_floating_ip_raises_vimconnexception(self):
+    def test_delete_floating_ip_by_id__delete_floating_ip_raises_connection_error__operation_fails(
+        self,
+    ):
+        """netron delete floating ip raises nvExceptions.ClientException."""
+        created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"port:{port_id}": True,
+        }
+        k_id = floating_network_vim_id
+        k = f"floating_ip:{floating_network_vim_id}"
+        self.vimconn.neutron.delete_floatingip.side_effect = ConnectionError(
+            "Connection exception occurred."
+        )
+        with self.assertRaises(VimConnConnectionException):
+            self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
+        self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
+        self.assertEqual(
+            created_items,
+            {
+                f"floating_ip:{floating_network_vim_id}": True,
+                f"port:{port_id}": True,
+            },
+        )
+        self.vimconn.logger.error.assert_called_once_with(
+            "Error deleting floating ip: ConnectionError: Connection exception occurred."
+        )
+
+    def test_delete_floating_ip_by_id_floating_ip_raises_vimconn_not_found_exception__operation_is_successful(
+        self,
+    ):
         """netron delete floating ip raises VimConnNotFoundException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
         """netron delete floating ip raises VimConnNotFoundException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -4053,7 +4089,9 @@ class TestNewVmInstance(unittest.TestCase):
         )
         self.assertEqual(created_items, expected_created_items)
 
         )
         self.assertEqual(created_items, expected_created_items)
 
-    def test_delete_volumes_by_id_with_cinder_delete_volume_raise_exception(self):
+    def test_delete_volumes_by_id_with_cinder__delete_volume_raise_client_exception__exception_is_not_raised(
+        self,
+    ):
         """cinder delete volume raises exception."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
         """cinder delete volume raises exception."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -4071,8 +4109,8 @@ class TestNewVmInstance(unittest.TestCase):
         k = f"volume:{volume_id}"
         k_id = volume_id
         self.vimconn.cinder.volumes.get.return_value.status = "available"
         k = f"volume:{volume_id}"
         k_id = volume_id
         self.vimconn.cinder.volumes.get.return_value.status = "available"
-        self.vimconn.cinder.volumes.delete.side_effect = nvExceptions.ClientException(
-            "Connection aborted."
+        self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ClientException(
+            403, "Connection aborted."
         )
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
         )
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
@@ -4081,7 +4119,42 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
         self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
         self.vimconn.logger.error.assert_called_once_with(
         self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
         self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
         self.vimconn.logger.error.assert_called_once_with(
-            "Error deleting volume: ClientException: Unknown Error (HTTP Connection aborted.)"
+            "Error deleting volume: ClientException: Connection aborted. (HTTP 403)"
+        )
+        self.assertEqual(created_items, expected_created_items)
+
+    def test_delete_volumes_by_id_with_cinder__delete_volume_raise_connection_exception__exception_is_raised(
+        self,
+    ):
+        """cinder delete volume raises exception."""
+        created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"volume:{volume_id2}": True,
+            f"volume:{volume_id}": True,
+            f"port:{port_id}": None,
+        }
+        expected_created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"volume:{volume_id2}": True,
+            f"volume:{volume_id}": True,
+            f"port:{port_id}": None,
+        }
+        volumes_to_hold = []
+        k = f"volume:{volume_id}"
+        k_id = volume_id
+        self.vimconn.cinder.volumes.get.return_value.status = "available"
+        self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ConnectionError(
+            "Connection failed."
+        )
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_volumes_by_id_wth_cinder(
+                k, k_id, volumes_to_hold, created_items
+            )
+            self.assertEqual(result, None)
+        self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
+        self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
+        self.vimconn.logger.error.assert_called_once_with(
+            "Error deleting volume: ConnectionError: Connection failed."
         )
         self.assertEqual(created_items, expected_created_items)
 
         )
         self.assertEqual(created_items, expected_created_items)
 
@@ -4105,7 +4178,7 @@ class TestNewVmInstance(unittest.TestCase):
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
         )
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
         )
-        self.assertEqual(result, None)
+        self.assertEqual(result, False)
         self.vimconn.cinder.volumes.get.assert_not_called()
         self.vimconn.cinder.volumes.delete.assert_not_called()
         self.vimconn.logger.error.assert_not_called()
         self.vimconn.cinder.volumes.get.assert_not_called()
         self.vimconn.cinder.volumes.delete.assert_not_called()
         self.vimconn.logger.error.assert_not_called()
@@ -4295,7 +4368,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_delete_vol_raises(
+    def test_delete_created_items__delete_vol_raises_connection_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4311,15 +4384,16 @@ class TestNewVmInstance(unittest.TestCase):
             ("floating_ip", f"{floating_network_vim_id}"),
             ("volume", f"{volume_id}"),
         ]
             ("floating_ip", f"{floating_network_vim_id}"),
             ("volume", f"{volume_id}"),
         ]
-        mock_delete_volumes_by_id_wth_cinder.side_effect = ConnectionError(
-            "Connection failed."
+        mock_delete_volumes_by_id_wth_cinder.side_effect = (
+            neExceptions.ConnectionFailed("Connection failed.")
         )
         volumes_to_hold = []
         keep_waiting = False
         )
         volumes_to_hold = []
         keep_waiting = False
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, False)
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
         self.assertEqual(mock_get_item_name_id.call_count, 2)
         mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
             f"volume:{volume_id}", f"{volume_id}", [], created_items
         self.assertEqual(mock_get_item_name_id.call_count, 2)
         mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
             f"volume:{volume_id}", f"{volume_id}", [], created_items
@@ -4336,7 +4410,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_delete_fip_raises(
+    def test_delete_created_items__delete_fip_raises_connection_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4358,14 +4432,13 @@ class TestNewVmInstance(unittest.TestCase):
         )
         volumes_to_hold = []
         keep_waiting = True
         )
         volumes_to_hold = []
         keep_waiting = True
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, True)
-        self.assertEqual(mock_get_item_name_id.call_count, 2)
-        mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
-            f"volume:{volume_id}", f"{volume_id}", [], created_items
-        )
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
+        self.assertEqual(mock_get_item_name_id.call_count, 1)
+        mock_delete_volumes_by_id_wth_cinder.assert_not_called()
         mock_delete_floating_ip_by_id.assert_called_once_with(
             f"floating_ip:{floating_network_vim_id}",
             f"{floating_network_vim_id}",
         mock_delete_floating_ip_by_id.assert_called_once_with(
             f"floating_ip:{floating_network_vim_id}",
             f"{floating_network_vim_id}",
@@ -4378,7 +4451,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_get_item_name_raises(
+    def test_delete_created_items_get_item_name_raises_type_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4396,19 +4469,16 @@ class TestNewVmInstance(unittest.TestCase):
         ]
         volumes_to_hold = []
         keep_waiting = False
         ]
         volumes_to_hold = []
         keep_waiting = False
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, False)
-        self.assertEqual(mock_get_item_name_id.call_count, 2)
+        with self.assertRaises(VimConnException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
+        self.assertEqual(mock_get_item_name_id.call_count, 1)
         mock_delete_volumes_by_id_wth_cinder.assert_not_called()
         mock_delete_floating_ip_by_id.assert_not_called()
         _call_logger = self.vimconn.logger.error.call_args_list
         self.assertEqual(_call_logger[0][0], ("Error deleting 3: Invalid Type",))
         mock_delete_volumes_by_id_wth_cinder.assert_not_called()
         mock_delete_floating_ip_by_id.assert_not_called()
         _call_logger = self.vimconn.logger.error.call_args_list
         self.assertEqual(_call_logger[0][0], ("Error deleting 3: Invalid Type",))
-        self.assertEqual(
-            _call_logger[1][0],
-            (f"Error deleting volume{volume_id}: Invalid attribute",),
-        )
 
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
 
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
@@ -4578,16 +4648,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_extract_items_wth_keep_raises(
+    def test_delete_vminstance__extract_items_wth_keep_raises_attributeerror__raise_vimconnexception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4603,7 +4671,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_extract_items_wth_keep_flag_from_created_items.side_effect = AttributeError
         volumes_to_hold = []
         mock_delete_created_items.return_value = False
         mock_extract_items_wth_keep_flag_from_created_items.side_effect = AttributeError
         volumes_to_hold = []
         mock_delete_created_items.return_value = False
-        with self.assertRaises(AttributeError):
+        with self.assertRaises(VimConnException):
             self.vimconn.delete_vminstance(
                 vm_id, initial_created_items, volumes_to_hold
             )
             self.vimconn.delete_vminstance(
                 vm_id, initial_created_items, volumes_to_hold
             )
@@ -4612,7 +4680,6 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn.nova.servers.delete.assert_not_called()
         mock_delete_created_items.assert_not_called()
         mock_sleep.assert_not_called()
         self.vimconn.nova.servers.delete.assert_not_called()
         mock_delete_created_items.assert_not_called()
         mock_sleep.assert_not_called()
-        mock_format_exception.assert_not_called()
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             initial_created_items
         )
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             initial_created_items
         )
@@ -4623,7 +4690,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_delete_created_items_raises(
+    def test_delete_vminstance__delete_created_items_returns_true__delete_created_items_called_several_times(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
@@ -4638,15 +4705,12 @@ class TestNewVmInstance(unittest.TestCase):
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         mock_sleep = MagicMock()
         volumes_to_hold = []
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         mock_sleep = MagicMock()
         volumes_to_hold = []
-        err = ConnectionError("ClientException occurred.")
-        mock_delete_created_items.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
-            self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
+        mock_delete_created_items.side_effect = [True, False]
+        self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
-        mock_delete_created_items.assert_called_once()
+        self.assertEqual(mock_delete_created_items.call_count, 2)
         mock_sleep.assert_not_called()
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             created_items
         mock_sleep.assert_not_called()
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             created_items
@@ -4654,16 +4718,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_delete_vm_ports_raises(
+    def test_delete_vminstance__delete_vm_ports_raises_connection_error__raise_vimconnconnectionexception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4674,10 +4736,9 @@ class TestNewVmInstance(unittest.TestCase):
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
         err = ConnectionError("ClientException occurred.")
         mock_delete_vm_ports_attached_to_network.side_effect = err
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
         err = ConnectionError("ClientException occurred.")
         mock_delete_vm_ports_attached_to_network.side_effect = err
-        mock_delete_created_items.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
+        mock_delete_created_items.return_value = False
+        with self.assertRaises(VimConnConnectionException):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_not_called()
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_not_called()
@@ -4689,16 +4750,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_nova_server_delete_raises(
+    def test_delete_vminstance__nova_server_delete_raises_clientexception__raise_vimconn_unexpected_response(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4707,12 +4766,11 @@ class TestNewVmInstance(unittest.TestCase):
         created_items = deepcopy(created_items_all_true)
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
         created_items = deepcopy(created_items_all_true)
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
-        err = VimConnConnectionException("ClientException occurred.")
+        err = nvExceptions.ClientException("ClientException occurred.")
         self.vimconn.nova.servers.delete.side_effect = err
         mock_delete_created_items.side_effect = err
         self.vimconn.nova.servers.delete.side_effect = err
         mock_delete_created_items.side_effect = err
-        with self.assertRaises(VimConnConnectionException) as err:
+        with self.assertRaises(VimConnUnexpectedResponse):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
@@ -4724,16 +4782,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_reload_connection_raises(
+    def test_delete_vminstance__reload_connection_raises_connection_error__raises_vimconnconnection_exception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4746,9 +4802,8 @@ class TestNewVmInstance(unittest.TestCase):
         err = ConnectionError("ClientException occurred.")
         mock_delete_created_items.return_value = False
         mock_reload_connection.side_effect = err
         err = ConnectionError("ClientException occurred.")
         mock_delete_created_items.return_value = False
         mock_reload_connection.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
+        with self.assertRaises(VimConnConnectionException):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_not_called()
         self.vimconn.nova.servers.delete.assert_not_called()
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_not_called()
         self.vimconn.nova.servers.delete.assert_not_called()
index 9d47437..bca9479 100644 (file)
@@ -41,6 +41,7 @@ import time
 from typing import Dict, List, Optional, Tuple
 
 from cinderclient import client as cClient
 from typing import Dict, List, Optional, Tuple
 
 from cinderclient import client as cClient
+import cinderclient.exceptions as cExceptions
 from glanceclient import client as glClient
 import glanceclient.exc as gl1Exceptions
 from keystoneauth1 import session
 from glanceclient import client as glClient
 import glanceclient.exc as gl1Exceptions
 from keystoneauth1 import session
@@ -85,6 +86,16 @@ volume_timeout = 1800
 server_timeout = 1800
 
 
 server_timeout = 1800
 
 
+def catch_any_exception(func):
+    def format_exception(*args, **kwargs):
+        try:
+            return func(*args, *kwargs)
+        except Exception as e:
+            vimconnector._format_exception(e)
+
+    return format_exception
+
+
 class SafeDumper(yaml.SafeDumper):
     def represent_data(self, data):
         # Openstack APIs use custom subclasses of dict and YAML safe dumper
 class SafeDumper(yaml.SafeDumper):
     def represent_data(self, data):
         # Openstack APIs use custom subclasses of dict and YAML safe dumper
@@ -525,7 +536,8 @@ class vimconnector(vimconn.VimConnector):
         # Types. Also, abstract vimconnector should call the validation
         # method before the implemented VIM connectors are called.
 
         # Types. Also, abstract vimconnector should call the validation
         # method before the implemented VIM connectors are called.
 
-    def _format_exception(self, exception):
+    @staticmethod
+    def _format_exception(exception):
         """Transform a keystone, nova, neutron  exception into a vimconn exception discovering the cause"""
         message_error = str(exception)
         tip = ""
         """Transform a keystone, nova, neutron  exception into a vimconn exception discovering the cause"""
         message_error = str(exception)
         tip = ""
@@ -535,8 +547,10 @@ class vimconnector(vimconn.VimConnector):
             (
                 neExceptions.NetworkNotFoundClient,
                 nvExceptions.NotFound,
             (
                 neExceptions.NetworkNotFoundClient,
                 nvExceptions.NotFound,
+                nvExceptions.ResourceNotFound,
                 ksExceptions.NotFound,
                 gl1Exceptions.HTTPNotFound,
                 ksExceptions.NotFound,
                 gl1Exceptions.HTTPNotFound,
+                cExceptions.NotFound,
             ),
         ):
             raise vimconn.VimConnNotFoundException(
             ),
         ):
             raise vimconn.VimConnNotFoundException(
@@ -551,6 +565,7 @@ class vimconnector(vimconn.VimConnector):
                 ConnectionError,
                 ksExceptions.ConnectionError,
                 neExceptions.ConnectionFailed,
                 ConnectionError,
                 ksExceptions.ConnectionError,
                 neExceptions.ConnectionFailed,
+                cExceptions.ConnectionError,
             ),
         ):
             if type(exception).__name__ == "SSLError":
             ),
         ):
             if type(exception).__name__ == "SSLError":
@@ -565,6 +580,8 @@ class vimconnector(vimconn.VimConnector):
                 KeyError,
                 nvExceptions.BadRequest,
                 ksExceptions.BadRequest,
                 KeyError,
                 nvExceptions.BadRequest,
                 ksExceptions.BadRequest,
+                gl1Exceptions.BadRequest,
+                cExceptions.BadRequest,
             ),
         ):
             if message_error == "OS-EXT-SRV-ATTR:host":
             ),
         ):
             if message_error == "OS-EXT-SRV-ATTR:host":
@@ -582,6 +599,7 @@ class vimconnector(vimconn.VimConnector):
                 nvExceptions.ClientException,
                 ksExceptions.ClientException,
                 neExceptions.NeutronException,
                 nvExceptions.ClientException,
                 ksExceptions.ClientException,
                 neExceptions.NeutronException,
+                cExceptions.ClientException,
             ),
         ):
             raise vimconn.VimConnUnexpectedResponse(
             ),
         ):
             raise vimconn.VimConnUnexpectedResponse(
@@ -594,9 +612,10 @@ class vimconnector(vimconn.VimConnector):
         elif isinstance(exception, vimconn.VimConnException):
             raise exception
         else:  # ()
         elif isinstance(exception, vimconn.VimConnException):
             raise exception
         else:  # ()
-            self.logger.error("General Exception " + message_error, exc_info=True)
+            logger = logging.getLogger("ro.vim.openstack")
+            logger.error("General Exception " + message_error, exc_info=True)
 
 
-            raise vimconn.VimConnConnectionException(
+            raise vimconn.VimConnException(
                 type(exception).__name__ + ": " + message_error
             )
 
                 type(exception).__name__ + ": " + message_error
             )
 
@@ -673,7 +692,6 @@ class vimconnector(vimconn.VimConnector):
         Returns the tenant list of dictionaries: [{'name':'<name>, 'id':'<id>, ...}, ...]
         """
         self.logger.debug("Getting tenants from VIM filter: '%s'", str(filter_dict))
         Returns the tenant list of dictionaries: [{'name':'<name>, 'id':'<id>, ...}, ...]
         """
         self.logger.debug("Getting tenants from VIM filter: '%s'", str(filter_dict))
-
         try:
             self._reload_connection()
 
         try:
             self._reload_connection()
 
@@ -703,7 +721,6 @@ class vimconnector(vimconn.VimConnector):
     def new_tenant(self, tenant_name, tenant_description):
         """Adds a new tenant to openstack VIM. Returns the tenant identifier"""
         self.logger.debug("Adding a new tenant name: %s", tenant_name)
     def new_tenant(self, tenant_name, tenant_description):
         """Adds a new tenant to openstack VIM. Returns the tenant identifier"""
         self.logger.debug("Adding a new tenant name: %s", tenant_name)
-
         try:
             self._reload_connection()
 
         try:
             self._reload_connection()
 
@@ -729,7 +746,6 @@ class vimconnector(vimconn.VimConnector):
     def delete_tenant(self, tenant_id):
         """Delete a tenant from openstack VIM. Returns the old tenant identifier"""
         self.logger.debug("Deleting tenant %s from VIM", tenant_id)
     def delete_tenant(self, tenant_id):
         """Delete a tenant from openstack VIM. Returns the old tenant identifier"""
         self.logger.debug("Deleting tenant %s from VIM", tenant_id)
-
         try:
             self._reload_connection()
 
         try:
             self._reload_connection()
 
@@ -739,6 +755,7 @@ class vimconnector(vimconn.VimConnector):
                 self.keystone.tenants.delete(tenant_id)
 
             return tenant_id
                 self.keystone.tenants.delete(tenant_id)
 
             return tenant_id
+
         except (
             ksExceptions.ConnectionError,
             ksExceptions.ClientException,
         except (
             ksExceptions.ConnectionError,
             ksExceptions.ClientException,
@@ -828,7 +845,7 @@ class vimconnector(vimconn.VimConnector):
                         "dataplane_physical_net"
                     )
 
                         "dataplane_physical_net"
                     )
 
-                    # if it is non empty list, use the first value. If it is a string use the value directly
+                    # if it is non-empty list, use the first value. If it is a string use the value directly
                     if (
                         isinstance(provider_physical_network, (tuple, list))
                         and provider_physical_network
                     if (
                         isinstance(provider_physical_network, (tuple, list))
                         and provider_physical_network
@@ -1007,6 +1024,14 @@ class vimconnector(vimconn.VimConnector):
 
                     if k_item == "l2gwconn":
                         self.neutron.delete_l2_gateway_connection(k_id)
 
                     if k_item == "l2gwconn":
                         self.neutron.delete_l2_gateway_connection(k_id)
+
+                except (neExceptions.ConnectionFailed, ConnectionError) as e2:
+                    self.logger.error(
+                        "Error deleting l2 gateway connection: {}: {}".format(
+                            type(e2).__name__, e2
+                        )
+                    )
+                    self._format_exception(e2)
                 except Exception as e2:
                     self.logger.error(
                         "Error deleting l2 gateway connection: {}: {}".format(
                 except Exception as e2:
                     self.logger.error(
                         "Error deleting l2 gateway connection: {}: {}".format(
@@ -1031,7 +1056,6 @@ class vimconnector(vimconn.VimConnector):
         Returns the network list of dictionaries
         """
         self.logger.debug("Getting network from VIM filter: '%s'", str(filter_dict))
         Returns the network list of dictionaries
         """
         self.logger.debug("Getting network from VIM filter: '%s'", str(filter_dict))
-
         try:
             self._reload_connection()
             filter_dict_os = filter_dict.copy()
         try:
             self._reload_connection()
             filter_dict_os = filter_dict.copy()
@@ -1091,6 +1115,7 @@ class vimconnector(vimconn.VimConnector):
 
         return net
 
 
         return net
 
+    @catch_any_exception
     def delete_network(self, net_id, created_items=None):
         """
         Removes a tenant network from VIM and its associated elements
     def delete_network(self, net_id, created_items=None):
         """
         Removes a tenant network from VIM and its associated elements
@@ -1114,6 +1139,14 @@ class vimconnector(vimconn.VimConnector):
                     k_item, _, k_id = k.partition(":")
                     if k_item == "l2gwconn":
                         self.neutron.delete_l2_gateway_connection(k_id)
                     k_item, _, k_id = k.partition(":")
                     if k_item == "l2gwconn":
                         self.neutron.delete_l2_gateway_connection(k_id)
+
+                except (neExceptions.ConnectionFailed, ConnectionError) as e:
+                    self.logger.error(
+                        "Error deleting l2 gateway connection: {}: {}".format(
+                            type(e).__name__, e
+                        )
+                    )
+                    self._format_exception(e)
                 except Exception as e:
                     self.logger.error(
                         "Error deleting l2 gateway connection: {}: {}".format(
                 except Exception as e:
                     self.logger.error(
                         "Error deleting l2 gateway connection: {}: {}".format(
@@ -1126,21 +1159,22 @@ class vimconnector(vimconn.VimConnector):
             for p in ports["ports"]:
                 try:
                     self.neutron.delete_port(p["id"])
             for p in ports["ports"]:
                 try:
                     self.neutron.delete_port(p["id"])
+
+                except (neExceptions.ConnectionFailed, ConnectionError) as e:
+                    self.logger.error("Error deleting port %s: %s", p["id"], str(e))
+                    # If there is connection error, it raises.
+                    self._format_exception(e)
                 except Exception as e:
                     self.logger.error("Error deleting port %s: %s", p["id"], str(e))
 
             self.neutron.delete_network(net_id)
 
             return net_id
                 except Exception as e:
                     self.logger.error("Error deleting port %s: %s", p["id"], str(e))
 
             self.neutron.delete_network(net_id)
 
             return net_id
-        except (
-            neExceptions.ConnectionFailed,
-            neExceptions.NetworkNotFoundClient,
-            neExceptions.NeutronException,
-            ksExceptions.ClientException,
-            neExceptions.NeutronException,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+        except (neExceptions.NetworkNotFoundClient, neExceptions.NotFound) as e:
+            # If network to be deleted is not found, it does not raise.
+            self.logger.warning(
+                f"Error deleting network: {net_id} is not found, {str(e)}"
+            )
 
     def refresh_nets_status(self, net_list):
         """Get the status of the networks
 
     def refresh_nets_status(self, net_list):
         """Get the status of the networks
@@ -1193,13 +1227,11 @@ class vimconnector(vimconn.VimConnector):
     def get_flavor(self, flavor_id):
         """Obtain flavor details from the  VIM. Returns the flavor dict details"""
         self.logger.debug("Getting flavor '%s'", flavor_id)
     def get_flavor(self, flavor_id):
         """Obtain flavor details from the  VIM. Returns the flavor dict details"""
         self.logger.debug("Getting flavor '%s'", flavor_id)
-
         try:
             self._reload_connection()
             flavor = self.nova.flavors.find(id=flavor_id)
         try:
             self._reload_connection()
             flavor = self.nova.flavors.find(id=flavor_id)
-            # TODO parse input and translate to VIM format (openmano_schemas.new_vminstance_response_schema)
-
             return flavor.to_dict()
             return flavor.to_dict()
+
         except (
             nvExceptions.NotFound,
             nvExceptions.ClientException,
         except (
             nvExceptions.NotFound,
             nvExceptions.ClientException,
@@ -1271,6 +1303,7 @@ class vimconnector(vimconn.VimConnector):
             )
         except (
             nvExceptions.NotFound,
             )
         except (
             nvExceptions.NotFound,
+            nvExceptions.BadRequest,
             nvExceptions.ClientException,
             ksExceptions.ClientException,
             ConnectionError,
             nvExceptions.ClientException,
             ksExceptions.ClientException,
             ConnectionError,
@@ -1541,6 +1574,7 @@ class vimconnector(vimconn.VimConnector):
             flavor_data.get("extended"),
         )
 
             flavor_data.get("extended"),
         )
 
+    @catch_any_exception
     def new_flavor(self, flavor_data: dict, change_name_if_used: bool = True) -> str:
         """Adds a tenant flavor to openstack VIM.
         if change_name_if_used is True, it will change name in case of conflict,
     def new_flavor(self, flavor_data: dict, change_name_if_used: bool = True) -> str:
         """Adds a tenant flavor to openstack VIM.
         if change_name_if_used is True, it will change name in case of conflict,
@@ -1558,70 +1592,58 @@ class vimconnector(vimconn.VimConnector):
         retry = 0
         max_retries = 3
         name_suffix = 0
         retry = 0
         max_retries = 3
         name_suffix = 0
+        name = flavor_data["name"]
+        while retry < max_retries:
+            retry += 1
+            try:
+                self._reload_connection()
 
 
-        try:
-            name = flavor_data["name"]
-            while retry < max_retries:
-                retry += 1
-                try:
-                    self._reload_connection()
+                if change_name_if_used:
+                    name = self._change_flavor_name(name, name_suffix, flavor_data)
 
 
-                    if change_name_if_used:
-                        name = self._change_flavor_name(name, name_suffix, flavor_data)
+                ram, vcpus, extra_specs, extended = self._get_flavor_details(
+                    flavor_data
+                )
+                if extended:
+                    self._process_extended_config_of_flavor(extended, extra_specs)
 
 
-                    ram, vcpus, extra_specs, extended = self._get_flavor_details(
-                        flavor_data
-                    )
-                    if extended:
-                        self._process_extended_config_of_flavor(extended, extra_specs)
-
-                    # Create flavor
-
-                    new_flavor = self.nova.flavors.create(
-                        name=name,
-                        ram=ram,
-                        vcpus=vcpus,
-                        disk=flavor_data.get("disk", 0),
-                        ephemeral=flavor_data.get("ephemeral", 0),
-                        swap=flavor_data.get("swap", 0),
-                        is_public=flavor_data.get("is_public", True),
-                    )
+                # Create flavor
 
 
-                    # Add metadata
-                    if extra_specs:
-                        new_flavor.set_keys(extra_specs)
+                new_flavor = self.nova.flavors.create(
+                    name=name,
+                    ram=ram,
+                    vcpus=vcpus,
+                    disk=flavor_data.get("disk", 0),
+                    ephemeral=flavor_data.get("ephemeral", 0),
+                    swap=flavor_data.get("swap", 0),
+                    is_public=flavor_data.get("is_public", True),
+                )
 
 
-                    return new_flavor.id
+                # Add metadata
+                if extra_specs:
+                    new_flavor.set_keys(extra_specs)
 
 
-                except nvExceptions.Conflict as e:
-                    if change_name_if_used and retry < max_retries:
-                        continue
+                return new_flavor.id
 
 
-                    self._format_exception(e)
+            except nvExceptions.Conflict as e:
+                if change_name_if_used and retry < max_retries:
+                    continue
 
 
-        except (
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            ConnectionError,
-            KeyError,
-        ) as e:
-            self._format_exception(e)
+                self._format_exception(e)
 
 
+    @catch_any_exception
     def delete_flavor(self, flavor_id):
         """Deletes a tenant flavor from openstack VIM. Returns the old flavor_id"""
         try:
             self._reload_connection()
             self.nova.flavors.delete(flavor_id)
     def delete_flavor(self, flavor_id):
         """Deletes a tenant flavor from openstack VIM. Returns the old flavor_id"""
         try:
             self._reload_connection()
             self.nova.flavors.delete(flavor_id)
-
             return flavor_id
             return flavor_id
-        # except nvExceptions.BadRequest as e:
-        except (
-            nvExceptions.NotFound,
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+
+        except (nvExceptions.NotFound, nvExceptions.ResourceNotFound) as e:
+            # If flavor is not found, it does not raise.
+            self.logger.warning(
+                f"Error deleting flavor: {flavor_id} is not found, {str(e.message)}"
+            )
 
     def new_image(self, image_dict):
         """
 
     def new_image(self, image_dict):
         """
@@ -1704,12 +1726,6 @@ class vimconnector(vimconn.VimConnector):
                 self.glance.images.update(new_image.id, **metadata_to_load)
 
                 return new_image.id
                 self.glance.images.update(new_image.id, **metadata_to_load)
 
                 return new_image.id
-            except (
-                nvExceptions.Conflict,
-                ksExceptions.ClientException,
-                nvExceptions.ClientException,
-            ) as e:
-                self._format_exception(e)
             except (
                 HTTPException,
                 gl1Exceptions.HTTPException,
             except (
                 HTTPException,
                 gl1Exceptions.HTTPException,
@@ -1725,7 +1741,10 @@ class vimconnector(vimconn.VimConnector):
                     "{}: {} for {}".format(type(e).__name__, e, image_dict["location"]),
                     http_code=vimconn.HTTP_Bad_Request,
                 )
                     "{}: {} for {}".format(type(e).__name__, e, image_dict["location"]),
                     http_code=vimconn.HTTP_Bad_Request,
                 )
+            except Exception as e:
+                self._format_exception(e)
 
 
+    @catch_any_exception
     def delete_image(self, image_id):
         """Deletes a tenant image from openstack VIM. Returns the old id"""
         try:
     def delete_image(self, image_id):
         """Deletes a tenant image from openstack VIM. Returns the old id"""
         try:
@@ -1733,36 +1752,25 @@ class vimconnector(vimconn.VimConnector):
             self.glance.images.delete(image_id)
 
             return image_id
             self.glance.images.delete(image_id)
 
             return image_id
-        except (
-            nvExceptions.NotFound,
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            gl1Exceptions.CommunicationError,
-            gl1Exceptions.HTTPNotFound,
-            ConnectionError,
-        ) as e:  # TODO remove
-            self._format_exception(e)
+        except gl1Exceptions.NotFound as e:
+            # If image is not found, it does not raise.
+            self.logger.warning(
+                f"Error deleting image: {image_id} is not found, {str(e)}"
+            )
 
 
+    @catch_any_exception
     def get_image_id_from_path(self, path):
         """Get the image id from image path in the VIM database. Returns the image_id"""
     def get_image_id_from_path(self, path):
         """Get the image id from image path in the VIM database. Returns the image_id"""
-        try:
-            self._reload_connection()
-            images = self.glance.images.list()
+        self._reload_connection()
+        images = self.glance.images.list()
 
 
-            for image in images:
-                if image.metadata.get("location") == path:
-                    return image.id
+        for image in images:
+            if image.metadata.get("location") == path:
+                return image.id
 
 
-            raise vimconn.VimConnNotFoundException(
-                "image with location '{}' not found".format(path)
-            )
-        except (
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            gl1Exceptions.CommunicationError,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+        raise vimconn.VimConnNotFoundException(
+            "image with location '{}' not found".format(path)
+        )
 
     def get_image_list(self, filter_dict={}):
         """Obtain tenant images from VIM
 
     def get_image_list(self, filter_dict={}):
         """Obtain tenant images from VIM
@@ -1775,7 +1783,6 @@ class vimconnector(vimconn.VimConnector):
             List can be empty
         """
         self.logger.debug("Getting image list from VIM filter: '%s'", str(filter_dict))
             List can be empty
         """
         self.logger.debug("Getting image list from VIM filter: '%s'", str(filter_dict))
-
         try:
             self._reload_connection()
             # filter_dict_os = filter_dict.copy()
         try:
             self._reload_connection()
             # filter_dict_os = filter_dict.copy()
@@ -1802,6 +1809,7 @@ class vimconnector(vimconn.VimConnector):
                     pass
 
             return filtered_list
                     pass
 
             return filtered_list
+
         except (
             ksExceptions.ClientException,
             nvExceptions.ClientException,
         except (
             ksExceptions.ClientException,
             nvExceptions.ClientException,
@@ -2185,16 +2193,14 @@ class vimconnector(vimconn.VimConnector):
             volume_txt += ":keep"
         created_items[volume_txt] = True
 
             volume_txt += ":keep"
         created_items[volume_txt] = True
 
+    @catch_any_exception
     def new_shared_volumes(self, shared_volume_data) -> (str, str):
     def new_shared_volumes(self, shared_volume_data) -> (str, str):
-        try:
-            volume = self.cinder.volumes.create(
-                size=shared_volume_data["size"],
-                name=shared_volume_data["name"],
-                volume_type="multiattach",
-            )
-            return (volume.name, volume.id)
-        except (ConnectionError, KeyError) as e:
-            self._format_exception(e)
+        volume = self.cinder.volumes.create(
+            size=shared_volume_data["size"],
+            name=shared_volume_data["name"],
+            volume_type="multiattach",
+        )
+        return volume.name, volume.id
 
     def _prepare_shared_volumes(
         self,
 
     def _prepare_shared_volumes(
         self,
@@ -2774,20 +2780,19 @@ class vimconnector(vimconn.VimConnector):
             flavor_id,
             str(net_list),
         )
             flavor_id,
             str(net_list),
         )
+        server = None
+        created_items = {}
+        net_list_vim = []
+        # list of external networks to be connected to instance, later on used to create floating_ip
+        external_network = []
+        # List of ports with port-security disabled
+        no_secured_ports = []
+        block_device_mapping = {}
+        existing_vim_volumes = []
+        server_group_id = None
+        scheduller_hints = {}
 
         try:
 
         try:
-            server = None
-            created_items = {}
-            net_list_vim = []
-            # list of external networks to be connected to instance, later on used to create floating_ip
-            external_network = []
-            # List of ports with port-security disabled
-            no_secured_ports = []
-            block_device_mapping = {}
-            existing_vim_volumes = []
-            server_group_id = None
-            scheduller_hints = {}
-
             # Check the Openstack Connection
             self._reload_connection()
 
             # Check the Openstack Connection
             self._reload_connection()
 
@@ -2907,6 +2912,7 @@ class vimconnector(vimconn.VimConnector):
         """Returns the VM instance information from VIM"""
         return self._find_nova_server(vm_id)
 
         """Returns the VM instance information from VIM"""
         return self._find_nova_server(vm_id)
 
+    @catch_any_exception
     def get_vminstance_console(self, vm_id, console_type="vnc"):
         """
         Get a console for the virtual machine
     def get_vminstance_console(self, vm_id, console_type="vnc"):
         """
         Get a console for the virtual machine
@@ -2922,66 +2928,56 @@ class vimconnector(vimconn.VimConnector):
                 suffix:   extra text, e.g. the http path and query string
         """
         self.logger.debug("Getting VM CONSOLE from VIM")
                 suffix:   extra text, e.g. the http path and query string
         """
         self.logger.debug("Getting VM CONSOLE from VIM")
+        self._reload_connection()
+        server = self.nova.servers.find(id=vm_id)
+
+        if console_type is None or console_type == "novnc":
+            console_dict = server.get_vnc_console("novnc")
+        elif console_type == "xvpvnc":
+            console_dict = server.get_vnc_console(console_type)
+        elif console_type == "rdp-html5":
+            console_dict = server.get_rdp_console(console_type)
+        elif console_type == "spice-html5":
+            console_dict = server.get_spice_console(console_type)
+        else:
+            raise vimconn.VimConnException(
+                "console type '{}' not allowed".format(console_type),
+                http_code=vimconn.HTTP_Bad_Request,
+            )
 
 
-        try:
-            self._reload_connection()
-            server = self.nova.servers.find(id=vm_id)
+        console_dict1 = console_dict.get("console")
 
 
-            if console_type is None or console_type == "novnc":
-                console_dict = server.get_vnc_console("novnc")
-            elif console_type == "xvpvnc":
-                console_dict = server.get_vnc_console(console_type)
-            elif console_type == "rdp-html5":
-                console_dict = server.get_rdp_console(console_type)
-            elif console_type == "spice-html5":
-                console_dict = server.get_spice_console(console_type)
-            else:
-                raise vimconn.VimConnException(
-                    "console type '{}' not allowed".format(console_type),
-                    http_code=vimconn.HTTP_Bad_Request,
-                )
-
-            console_dict1 = console_dict.get("console")
+        if console_dict1:
+            console_url = console_dict1.get("url")
 
 
-            if console_dict1:
-                console_url = console_dict1.get("url")
+            if console_url:
+                # parse console_url
+                protocol_index = console_url.find("//")
+                suffix_index = (
+                    console_url[protocol_index + 2 :].find("/") + protocol_index + 2
+                )
+                port_index = (
+                    console_url[protocol_index + 2 : suffix_index].find(":")
+                    + protocol_index
+                    + 2
+                )
 
 
-                if console_url:
-                    # parse console_url
-                    protocol_index = console_url.find("//")
-                    suffix_index = (
-                        console_url[protocol_index + 2 :].find("/") + protocol_index + 2
-                    )
-                    port_index = (
-                        console_url[protocol_index + 2 : suffix_index].find(":")
-                        + protocol_index
-                        + 2
+                if protocol_index < 0 or port_index < 0 or suffix_index < 0:
+                    return (
+                        -vimconn.HTTP_Internal_Server_Error,
+                        "Unexpected response from VIM",
                     )
 
                     )
 
-                    if protocol_index < 0 or port_index < 0 or suffix_index < 0:
-                        return (
-                            -vimconn.HTTP_Internal_Server_Error,
-                            "Unexpected response from VIM",
-                        )
-
-                    console_dict = {
-                        "protocol": console_url[0:protocol_index],
-                        "server": console_url[protocol_index + 2 : port_index],
-                        "port": console_url[port_index:suffix_index],
-                        "suffix": console_url[suffix_index + 1 :],
-                    }
-                    protocol_index += 2
+                console_dict = {
+                    "protocol": console_url[0:protocol_index],
+                    "server": console_url[protocol_index + 2 : port_index],
+                    "port": console_url[port_index:suffix_index],
+                    "suffix": console_url[suffix_index + 1 :],
+                }
+                protocol_index += 2
 
 
-                    return console_dict
-            raise vimconn.VimConnUnexpectedResponse("Unexpected response from VIM")
-        except (
-            nvExceptions.NotFound,
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            nvExceptions.BadRequest,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+                return console_dict
+        raise vimconn.VimConnUnexpectedResponse("Unexpected response from VIM")
 
     def _delete_ports_by_id_wth_neutron(self, k_id: str) -> None:
         """Neutron delete ports by id.
 
     def _delete_ports_by_id_wth_neutron(self, k_id: str) -> None:
         """Neutron delete ports by id.
@@ -2991,6 +2987,10 @@ class vimconnector(vimconn.VimConnector):
         try:
             self.neutron.delete_port(k_id)
 
         try:
             self.neutron.delete_port(k_id)
 
+        except (neExceptions.ConnectionFailed, ConnectionError) as e:
+            self.logger.error("Error deleting port: {}: {}".format(type(e).__name__, e))
+            # If there is connection error, raise.
+            self._format_exception(e)
         except Exception as e:
             self.logger.error("Error deleting port: {}: {}".format(type(e).__name__, e))
 
         except Exception as e:
             self.logger.error("Error deleting port: {}: {}".format(type(e).__name__, e))
 
@@ -3036,7 +3036,7 @@ class vimconnector(vimconn.VimConnector):
         """
         try:
             if k_id in volumes_to_hold:
         """
         try:
             if k_id in volumes_to_hold:
-                return
+                return False
 
             if self.cinder.volumes.get(k_id).status != "available":
                 return True
 
             if self.cinder.volumes.get(k_id).status != "available":
                 return True
@@ -3045,6 +3045,11 @@ class vimconnector(vimconn.VimConnector):
                 self.cinder.volumes.delete(k_id)
                 created_items[k] = None
 
                 self.cinder.volumes.delete(k_id)
                 created_items[k] = None
 
+        except (cExceptions.ConnectionError, ConnectionError) as e:
+            self.logger.error(
+                "Error deleting volume: {}: {}".format(type(e).__name__, e)
+            )
+            self._format_exception(e)
         except Exception as e:
             self.logger.error(
                 "Error deleting volume: {}: {}".format(type(e).__name__, e)
         except Exception as e:
             self.logger.error(
                 "Error deleting volume: {}: {}".format(type(e).__name__, e)
@@ -3061,6 +3066,11 @@ class vimconnector(vimconn.VimConnector):
             self.neutron.delete_floatingip(k_id)
             created_items[k] = None
 
             self.neutron.delete_floatingip(k_id)
             created_items[k] = None
 
+        except (neExceptions.ConnectionFailed, ConnectionError) as e:
+            self.logger.error(
+                "Error deleting floating ip: {}: {}".format(type(e).__name__, e)
+            )
+            self._format_exception(e)
         except Exception as e:
             self.logger.error(
                 "Error deleting floating ip: {}: {}".format(type(e).__name__, e)
         except Exception as e:
             self.logger.error(
                 "Error deleting floating ip: {}: {}".format(type(e).__name__, e)
@@ -3086,6 +3096,11 @@ class vimconnector(vimconn.VimConnector):
                 if k_item == "port":
                     self._delete_ports_by_id_wth_neutron(k_id)
 
                 if k_item == "port":
                     self._delete_ports_by_id_wth_neutron(k_id)
 
+            except (neExceptions.ConnectionFailed, ConnectionError) as e:
+                self.logger.error(
+                    "Error deleting port: {}: {}".format(type(e).__name__, e)
+                )
+                self._format_exception(e)
             except Exception as e:
                 self.logger.error(
                     "Error deleting port: {}: {}".format(type(e).__name__, e)
             except Exception as e:
                 self.logger.error(
                     "Error deleting port: {}: {}".format(type(e).__name__, e)
@@ -3112,6 +3127,16 @@ class vimconnector(vimconn.VimConnector):
                 elif k_item == "floating_ip":
                     self._delete_floating_ip_by_id(k, k_id, created_items)
 
                 elif k_item == "floating_ip":
                     self._delete_floating_ip_by_id(k, k_id, created_items)
 
+            except (
+                cExceptions.ConnectionError,
+                neExceptions.ConnectionFailed,
+                ConnectionError,
+                AttributeError,
+                TypeError,
+            ) as e:
+                self.logger.error("Error deleting {}: {}".format(k, e))
+                self._format_exception(e)
+
             except Exception as e:
                 self.logger.error("Error deleting {}: {}".format(k, e))
 
             except Exception as e:
                 self.logger.error("Error deleting {}: {}".format(k, e))
 
@@ -3133,6 +3158,7 @@ class vimconnector(vimconn.VimConnector):
             if len(key.split(":")) == 2
         }
 
             if len(key.split(":")) == 2
         }
 
+    @catch_any_exception
     def delete_vminstance(
         self, vm_id: str, created_items: dict = None, volumes_to_hold: list = None
     ) -> None:
     def delete_vminstance(
         self, vm_id: str, created_items: dict = None, volumes_to_hold: list = None
     ) -> None:
@@ -3177,14 +3203,9 @@ class vimconnector(vimconn.VimConnector):
                 if keep_waiting:
                     time.sleep(1)
                     elapsed_time += 1
                 if keep_waiting:
                     time.sleep(1)
                     elapsed_time += 1
-
-        except (
-            nvExceptions.NotFound,
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+        except (nvExceptions.NotFound, nvExceptions.ResourceNotFound) as e:
+            # If VM does not exist, it does not raise
+            self.logger.warning(f"Error deleting VM: {vm_id} is not found, {str(e)}")
 
     def refresh_vms_status(self, vm_list):
         """Get the status of the virtual machines and their interfaces/ports
 
     def refresh_vms_status(self, vm_list):
         """Get the status of the virtual machines and their interfaces/ports
@@ -3216,7 +3237,6 @@ class vimconnector(vimconn.VimConnector):
         self.logger.debug(
             "refresh_vms status: Getting tenant VM instance information from VIM"
         )
         self.logger.debug(
             "refresh_vms status: Getting tenant VM instance information from VIM"
         )
-
         for vm_id in vm_list:
             vm = {}
 
         for vm_id in vm_list:
             vm = {}
 
@@ -3329,122 +3349,111 @@ class vimconnector(vimconn.VimConnector):
 
         return vm_dict
 
 
         return vm_dict
 
+    @catch_any_exception
     def action_vminstance(self, vm_id, action_dict, created_items={}):
         """Send and action over a VM instance from VIM
         Returns None or the console dict if the action was successfully sent to the VIM
         """
         self.logger.debug("Action over VM '%s': %s", vm_id, str(action_dict))
     def action_vminstance(self, vm_id, action_dict, created_items={}):
         """Send and action over a VM instance from VIM
         Returns None or the console dict if the action was successfully sent to the VIM
         """
         self.logger.debug("Action over VM '%s': %s", vm_id, str(action_dict))
-
-        try:
-            self._reload_connection()
-            server = self.nova.servers.find(id=vm_id)
-
-            if "start" in action_dict:
-                if action_dict["start"] == "rebuild":
-                    server.rebuild()
-                else:
-                    if server.status == "PAUSED":
-                        server.unpause()
-                    elif server.status == "SUSPENDED":
-                        server.resume()
-                    elif server.status == "SHUTOFF":
-                        server.start()
-                    else:
-                        self.logger.debug(
-                            "ERROR : Instance is not in SHUTOFF/PAUSE/SUSPEND state"
-                        )
-                        raise vimconn.VimConnException(
-                            "Cannot 'start' instance while it is in active state",
-                            http_code=vimconn.HTTP_Bad_Request,
-                        )
-
-            elif "pause" in action_dict:
-                server.pause()
-            elif "resume" in action_dict:
-                server.resume()
-            elif "shutoff" in action_dict or "shutdown" in action_dict:
-                self.logger.debug("server status %s", server.status)
-                if server.status == "ACTIVE":
-                    server.stop()
+        self._reload_connection()
+        server = self.nova.servers.find(id=vm_id)
+        if "start" in action_dict:
+            if action_dict["start"] == "rebuild":
+                server.rebuild()
+            else:
+                if server.status == "PAUSED":
+                    server.unpause()
+                elif server.status == "SUSPENDED":
+                    server.resume()
+                elif server.status == "SHUTOFF":
+                    server.start()
                 else:
                 else:
-                    self.logger.debug("ERROR: VM is not in Active state")
-                    raise vimconn.VimConnException(
-                        "VM is not in active state, stop operation is not allowed",
-                        http_code=vimconn.HTTP_Bad_Request,
+                    self.logger.debug(
+                        "ERROR : Instance is not in SHUTOFF/PAUSE/SUSPEND state"
                     )
                     )
-            elif "forceOff" in action_dict:
-                server.stop()  # TODO
-            elif "terminate" in action_dict:
-                server.delete()
-            elif "createImage" in action_dict:
-                server.create_image()
-                # "path":path_schema,
-                # "description":description_schema,
-                # "name":name_schema,
-                # "metadata":metadata_schema,
-                # "imageRef": id_schema,
-                # "disk": {"oneOf":[{"type": "null"}, {"type":"string"}] },
-            elif "rebuild" in action_dict:
-                server.rebuild(server.image["id"])
-            elif "reboot" in action_dict:
-                server.reboot()  # reboot_type="SOFT"
-            elif "console" in action_dict:
-                console_type = action_dict["console"]
-
-                if console_type is None or console_type == "novnc":
-                    console_dict = server.get_vnc_console("novnc")
-                elif console_type == "xvpvnc":
-                    console_dict = server.get_vnc_console(console_type)
-                elif console_type == "rdp-html5":
-                    console_dict = server.get_rdp_console(console_type)
-                elif console_type == "spice-html5":
-                    console_dict = server.get_spice_console(console_type)
-                else:
                     raise vimconn.VimConnException(
                     raise vimconn.VimConnException(
-                        "console type '{}' not allowed".format(console_type),
+                        "Cannot 'start' instance while it is in active state",
                         http_code=vimconn.HTTP_Bad_Request,
                     )
                         http_code=vimconn.HTTP_Bad_Request,
                     )
+        elif "pause" in action_dict:
+            server.pause()
+        elif "resume" in action_dict:
+            server.resume()
+        elif "shutoff" in action_dict or "shutdown" in action_dict:
+            self.logger.debug("server status %s", server.status)
+            if server.status == "ACTIVE":
+                server.stop()
+            else:
+                self.logger.debug("ERROR: VM is not in Active state")
+                raise vimconn.VimConnException(
+                    "VM is not in active state, stop operation is not allowed",
+                    http_code=vimconn.HTTP_Bad_Request,
+                )
+        elif "forceOff" in action_dict:
+            server.stop()  # TODO
+        elif "terminate" in action_dict:
+            server.delete()
+        elif "createImage" in action_dict:
+            server.create_image()
+            # "path":path_schema,
+            # "description":description_schema,
+            # "name":name_schema,
+            # "metadata":metadata_schema,
+            # "imageRef": id_schema,
+            # "disk": {"oneOf":[{"type": "null"}, {"type":"string"}] },
+        elif "rebuild" in action_dict:
+            server.rebuild(server.image["id"])
+        elif "reboot" in action_dict:
+            server.reboot()  # reboot_type="SOFT"
+        elif "console" in action_dict:
+            console_type = action_dict["console"]
 
 
-                try:
-                    console_url = console_dict["console"]["url"]
-                    # parse console_url
-                    protocol_index = console_url.find("//")
-                    suffix_index = (
-                        console_url[protocol_index + 2 :].find("/") + protocol_index + 2
-                    )
-                    port_index = (
-                        console_url[protocol_index + 2 : suffix_index].find(":")
-                        + protocol_index
-                        + 2
-                    )
-
-                    if protocol_index < 0 or port_index < 0 or suffix_index < 0:
-                        raise vimconn.VimConnException(
-                            "Unexpected response from VIM " + str(console_dict)
-                        )
+            if console_type is None or console_type == "novnc":
+                console_dict = server.get_vnc_console("novnc")
+            elif console_type == "xvpvnc":
+                console_dict = server.get_vnc_console(console_type)
+            elif console_type == "rdp-html5":
+                console_dict = server.get_rdp_console(console_type)
+            elif console_type == "spice-html5":
+                console_dict = server.get_spice_console(console_type)
+            else:
+                raise vimconn.VimConnException(
+                    "console type '{}' not allowed".format(console_type),
+                    http_code=vimconn.HTTP_Bad_Request,
+                )
 
 
-                    console_dict2 = {
-                        "protocol": console_url[0:protocol_index],
-                        "server": console_url[protocol_index + 2 : port_index],
-                        "port": int(console_url[port_index + 1 : suffix_index]),
-                        "suffix": console_url[suffix_index + 1 :],
-                    }
+            try:
+                console_url = console_dict["console"]["url"]
+                # parse console_url
+                protocol_index = console_url.find("//")
+                suffix_index = (
+                    console_url[protocol_index + 2 :].find("/") + protocol_index + 2
+                )
+                port_index = (
+                    console_url[protocol_index + 2 : suffix_index].find(":")
+                    + protocol_index
+                    + 2
+                )
 
 
-                    return console_dict2
-                except Exception:
+                if protocol_index < 0 or port_index < 0 or suffix_index < 0:
                     raise vimconn.VimConnException(
                         "Unexpected response from VIM " + str(console_dict)
                     )
 
                     raise vimconn.VimConnException(
                         "Unexpected response from VIM " + str(console_dict)
                     )
 
-            return None
-        except (
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            nvExceptions.NotFound,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
-        # TODO insert exception vimconn.HTTP_Unauthorized
+                console_dict2 = {
+                    "protocol": console_url[0:protocol_index],
+                    "server": console_url[protocol_index + 2 : port_index],
+                    "port": int(console_url[port_index + 1 : suffix_index]),
+                    "suffix": console_url[suffix_index + 1 :],
+                }
+
+                return console_dict2
+            except Exception:
+                raise vimconn.VimConnException(
+                    "Unexpected response from VIM " + str(console_dict)
+                )
+
+        return None
 
     # ###### VIO Specific Changes #########
     def _generate_vlanID(self):
 
     # ###### VIO Specific Changes #########
     def _generate_vlanID(self):
@@ -3649,6 +3658,7 @@ class vimconnector(vimconn.VimConnector):
 
         return error_value, error_text
 
 
         return error_value, error_text
 
+    @catch_any_exception
     def new_affinity_group(self, affinity_group_data):
         """Adds a server group to VIM
             affinity_group_data contains a dictionary with information, keys:
     def new_affinity_group(self, affinity_group_data):
         """Adds a server group to VIM
             affinity_group_data contains a dictionary with information, keys:
@@ -3657,55 +3667,29 @@ class vimconnector(vimconn.VimConnector):
                 scope: Only nfvi-node allowed
         Returns the server group identifier"""
         self.logger.debug("Adding Server Group '%s'", str(affinity_group_data))
                 scope: Only nfvi-node allowed
         Returns the server group identifier"""
         self.logger.debug("Adding Server Group '%s'", str(affinity_group_data))
+        name = affinity_group_data["name"]
+        policy = affinity_group_data["type"]
+        self._reload_connection()
+        new_server_group = self.nova.server_groups.create(name, policy)
+        return new_server_group.id
 
 
-        try:
-            name = affinity_group_data["name"]
-            policy = affinity_group_data["type"]
-
-            self._reload_connection()
-            new_server_group = self.nova.server_groups.create(name, policy)
-
-            return new_server_group.id
-        except (
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            ConnectionError,
-            KeyError,
-        ) as e:
-            self._format_exception(e)
-
+    @catch_any_exception
     def get_affinity_group(self, affinity_group_id):
         """Obtain server group details from the VIM. Returns the server group detais as a dict"""
         self.logger.debug("Getting flavor '%s'", affinity_group_id)
     def get_affinity_group(self, affinity_group_id):
         """Obtain server group details from the VIM. Returns the server group detais as a dict"""
         self.logger.debug("Getting flavor '%s'", affinity_group_id)
-        try:
-            self._reload_connection()
-            server_group = self.nova.server_groups.find(id=affinity_group_id)
-
-            return server_group.to_dict()
-        except (
-            nvExceptions.NotFound,
-            nvExceptions.ClientException,
-            ksExceptions.ClientException,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+        self._reload_connection()
+        server_group = self.nova.server_groups.find(id=affinity_group_id)
+        return server_group.to_dict()
 
 
+    @catch_any_exception
     def delete_affinity_group(self, affinity_group_id):
         """Deletes a server group from the VIM. Returns the old affinity_group_id"""
         self.logger.debug("Getting server group '%s'", affinity_group_id)
     def delete_affinity_group(self, affinity_group_id):
         """Deletes a server group from the VIM. Returns the old affinity_group_id"""
         self.logger.debug("Getting server group '%s'", affinity_group_id)
-        try:
-            self._reload_connection()
-            self.nova.server_groups.delete(affinity_group_id)
-
-            return affinity_group_id
-        except (
-            nvExceptions.NotFound,
-            ksExceptions.ClientException,
-            nvExceptions.ClientException,
-            ConnectionError,
-        ) as e:
-            self._format_exception(e)
+        self._reload_connection()
+        self.nova.server_groups.delete(affinity_group_id)
+        return affinity_group_id
 
 
+    @catch_any_exception
     def get_vdu_state(self, vm_id, host_is_required=False) -> list:
         """Getting the state of a VDU.
         Args:
     def get_vdu_state(self, vm_id, host_is_required=False) -> list:
         """Getting the state of a VDU.
         Args:
@@ -3717,24 +3701,20 @@ class vimconnector(vimconn.VimConnector):
         """
         self.logger.debug("Getting the status of VM")
         self.logger.debug("VIM VM ID %s", vm_id)
         """
         self.logger.debug("Getting the status of VM")
         self.logger.debug("VIM VM ID %s", vm_id)
-        try:
-            self._reload_connection()
-            server_dict = self._find_nova_server(vm_id)
-            srv_attr = "OS-EXT-SRV-ATTR:host"
-            host_info = (
-                server_dict[srv_attr] if host_is_required else server_dict.get(srv_attr)
-            )
-            vdu_data = [
-                server_dict["status"],
-                server_dict["flavor"]["id"],
-                host_info,
-                server_dict["OS-EXT-AZ:availability_zone"],
-            ]
-            self.logger.debug("vdu_data %s", vdu_data)
-            return vdu_data
-
-        except Exception as e:
-            self._format_exception(e)
+        self._reload_connection()
+        server_dict = self._find_nova_server(vm_id)
+        srv_attr = "OS-EXT-SRV-ATTR:host"
+        host_info = (
+            server_dict[srv_attr] if host_is_required else server_dict.get(srv_attr)
+        )
+        vdu_data = [
+            server_dict["status"],
+            server_dict["flavor"]["id"],
+            host_info,
+            server_dict["OS-EXT-AZ:availability_zone"],
+        ]
+        self.logger.debug("vdu_data %s", vdu_data)
+        return vdu_data
 
     def check_compute_availability(self, host, server_flavor_details):
         self._reload_connection()
 
     def check_compute_availability(self, host, server_flavor_details):
         self._reload_connection()
@@ -3792,6 +3772,7 @@ class vimconnector(vimconn.VimConnector):
                         az_check["zone_check"] = True
         return az_check
 
                         az_check["zone_check"] = True
         return az_check
 
+    @catch_any_exception
     def migrate_instance(self, vm_id, compute_host=None):
         """
         Migrate a vdu
     def migrate_instance(self, vm_id, compute_host=None):
         """
         Migrate a vdu
@@ -3805,78 +3786,72 @@ class vimconnector(vimconn.VimConnector):
         server_flavor_id = instance_state[1]
         server_hypervisor_name = instance_state[2]
         server_availability_zone = instance_state[3]
         server_flavor_id = instance_state[1]
         server_hypervisor_name = instance_state[2]
         server_availability_zone = instance_state[3]
-        try:
-            server_flavor = self.nova.flavors.find(id=server_flavor_id).to_dict()
-            server_flavor_details = [
-                server_flavor["ram"],
-                server_flavor["disk"],
-                server_flavor["vcpus"],
-            ]
-            if compute_host == server_hypervisor_name:
-                raise vimconn.VimConnException(
-                    "Unable to migrate instance '{}' to the same host '{}'".format(
-                        vm_id, compute_host
-                    ),
-                    http_code=vimconn.HTTP_Bad_Request,
-                )
-            az_status = self.check_availability_zone(
-                server_availability_zone,
-                server_flavor_details,
-                server_hypervisor_name,
-                compute_host,
+        server_flavor = self.nova.flavors.find(id=server_flavor_id).to_dict()
+        server_flavor_details = [
+            server_flavor["ram"],
+            server_flavor["disk"],
+            server_flavor["vcpus"],
+        ]
+        if compute_host == server_hypervisor_name:
+            raise vimconn.VimConnException(
+                "Unable to migrate instance '{}' to the same host '{}'".format(
+                    vm_id, compute_host
+                ),
+                http_code=vimconn.HTTP_Bad_Request,
             )
             )
-            availability_zone_check = az_status["zone_check"]
-            available_compute_id = az_status.get("compute_availability")
+        az_status = self.check_availability_zone(
+            server_availability_zone,
+            server_flavor_details,
+            server_hypervisor_name,
+            compute_host,
+        )
+        availability_zone_check = az_status["zone_check"]
+        available_compute_id = az_status.get("compute_availability")
 
 
-            if availability_zone_check is False:
-                raise vimconn.VimConnException(
-                    "Unable to migrate instance '{}' to a different availability zone".format(
-                        vm_id
-                    ),
-                    http_code=vimconn.HTTP_Bad_Request,
-                )
-            if available_compute_id is not None:
-                # disk_over_commit parameter for live_migrate method is not valid for Nova API version >= 2.25
-                self.nova.servers.live_migrate(
-                    server=vm_id,
-                    host=available_compute_id,
-                    block_migration=True,
-                )
-                state = "MIGRATING"
-                changed_compute_host = ""
-                if state == "MIGRATING":
-                    vm_state = self.__wait_for_vm(vm_id, "ACTIVE")
-                    changed_compute_host = self.get_vdu_state(
-                        vm_id, host_is_required=True
-                    )[2]
-                if vm_state and changed_compute_host == available_compute_id:
-                    self.logger.debug(
-                        "Instance '{}' migrated to the new compute host '{}'".format(
-                            vm_id, changed_compute_host
-                        )
-                    )
-                    return state, available_compute_id
-                else:
-                    raise vimconn.VimConnException(
-                        "Migration Failed. Instance '{}' not moved to the new host {}".format(
-                            vm_id, available_compute_id
-                        ),
-                        http_code=vimconn.HTTP_Bad_Request,
+        if availability_zone_check is False:
+            raise vimconn.VimConnException(
+                "Unable to migrate instance '{}' to a different availability zone".format(
+                    vm_id
+                ),
+                http_code=vimconn.HTTP_Bad_Request,
+            )
+        if available_compute_id is not None:
+            # disk_over_commit parameter for live_migrate method is not valid for Nova API version >= 2.25
+            self.nova.servers.live_migrate(
+                server=vm_id,
+                host=available_compute_id,
+                block_migration=True,
+            )
+            state = "MIGRATING"
+            changed_compute_host = ""
+            if state == "MIGRATING":
+                vm_state = self.__wait_for_vm(vm_id, "ACTIVE")
+                changed_compute_host = self.get_vdu_state(vm_id, host_is_required=True)[
+                    2
+                ]
+            if vm_state and changed_compute_host == available_compute_id:
+                self.logger.debug(
+                    "Instance '{}' migrated to the new compute host '{}'".format(
+                        vm_id, changed_compute_host
                     )
                     )
+                )
+                return state, available_compute_id
             else:
                 raise vimconn.VimConnException(
             else:
                 raise vimconn.VimConnException(
-                    "Compute '{}' not available or does not have enough resources to migrate the instance".format(
-                        available_compute_id
+                    "Migration Failed. Instance '{}' not moved to the new host {}".format(
+                        vm_id, available_compute_id
                     ),
                     http_code=vimconn.HTTP_Bad_Request,
                 )
                     ),
                     http_code=vimconn.HTTP_Bad_Request,
                 )
-        except (
-            nvExceptions.BadRequest,
-            nvExceptions.ClientException,
-            nvExceptions.NotFound,
-        ) as e:
-            self._format_exception(e)
+        else:
+            raise vimconn.VimConnException(
+                "Compute '{}' not available or does not have enough resources to migrate the instance".format(
+                    available_compute_id
+                ),
+                http_code=vimconn.HTTP_Bad_Request,
+            )
 
 
+    @catch_any_exception
     def resize_instance(self, vm_id, new_flavor_id):
         """
         For resizing the vm based on the given
     def resize_instance(self, vm_id, new_flavor_id):
         """
         For resizing the vm based on the given
@@ -3891,37 +3866,30 @@ class vimconnector(vimconn.VimConnector):
         instance_status, old_flavor_id, compute_host, az = self.get_vdu_state(vm_id)
         old_flavor_disk = self.nova.flavors.find(id=old_flavor_id).to_dict()["disk"]
         new_flavor_disk = self.nova.flavors.find(id=new_flavor_id).to_dict()["disk"]
         instance_status, old_flavor_id, compute_host, az = self.get_vdu_state(vm_id)
         old_flavor_disk = self.nova.flavors.find(id=old_flavor_id).to_dict()["disk"]
         new_flavor_disk = self.nova.flavors.find(id=new_flavor_id).to_dict()["disk"]
-        try:
-            if instance_status == "ACTIVE" or instance_status == "SHUTOFF":
-                if old_flavor_disk > new_flavor_disk:
+        if instance_status == "ACTIVE" or instance_status == "SHUTOFF":
+            if old_flavor_disk > new_flavor_disk:
+                raise nvExceptions.BadRequest(
+                    400,
+                    message="Server disk resize failed. Resize to lower disk flavor is not allowed",
+                )
+            else:
+                self.nova.servers.resize(server=vm_id, flavor=new_flavor_id)
+                vm_state = self.__wait_for_vm(vm_id, "VERIFY_RESIZE")
+                if vm_state:
+                    instance_resized_status = self.confirm_resize(vm_id)
+                    return instance_resized_status
+                else:
                     raise nvExceptions.BadRequest(
                     raise nvExceptions.BadRequest(
-                        400,
-                        message="Server disk resize failed. Resize to lower disk flavor is not allowed",
+                        409,
+                        message="Cannot 'resize' vm_state is in ERROR",
                     )
                     )
-                else:
-                    self.nova.servers.resize(server=vm_id, flavor=new_flavor_id)
-                    vm_state = self.__wait_for_vm(vm_id, "VERIFY_RESIZE")
-                    if vm_state:
-                        instance_resized_status = self.confirm_resize(vm_id)
-                        return instance_resized_status
-                    else:
-                        raise nvExceptions.BadRequest(
-                            409,
-                            message="Cannot 'resize' vm_state is in ERROR",
-                        )
 
 
-            else:
-                self.logger.debug("ERROR : Instance is not in ACTIVE or SHUTOFF state")
-                raise nvExceptions.BadRequest(
-                    409,
-                    message="Cannot 'resize' instance while it is in vm_state resized",
-                )
-        except (
-            nvExceptions.BadRequest,
-            nvExceptions.ClientException,
-            nvExceptions.NotFound,
-        ) as e:
-            self._format_exception(e)
+        else:
+            self.logger.debug("ERROR : Instance is not in ACTIVE or SHUTOFF state")
+            raise nvExceptions.BadRequest(
+                409,
+                message="Cannot 'resize' instance while it is in vm_state resized",
+            )
 
     def confirm_resize(self, vm_id):
         """
 
     def confirm_resize(self, vm_id):
         """
@@ -3951,11 +3919,7 @@ class vimconnector(vimconn.VimConnector):
                 self.logger.warning(str(e.message))
             all_ports = self.neutron.list_ports()
             return all_servers, all_ports
                 self.logger.warning(str(e.message))
             all_ports = self.neutron.list_ports()
             return all_servers, all_ports
-        except (
-            vimconn.VimConnException,
-            vimconn.VimConnNotFoundException,
-            vimconn.VimConnConnectionException,
-        ) as e:
+        except Exception as e:
             raise vimconn.VimConnException(
                 f"Exception in monitoring while getting VMs and ports status: {str(e)}"
             )
             raise vimconn.VimConnException(
                 f"Exception in monitoring while getting VMs and ports status: {str(e)}"
             )
diff --git a/releasenotes/notes/fix_bug_2158_2254-86a20d2b2a6ca5a9.yaml b/releasenotes/notes/fix_bug_2158_2254-86a20d2b2a6ca5a9.yaml
new file mode 100644 (file)
index 0000000..95715d9
--- /dev/null
@@ -0,0 +1,23 @@
+#######################################################################################
+# 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.
+#######################################################################################
+---
+fixes:
+  - |
+    Fix Bug 2158 If VIM is not reachable NS delete operation should fail and Bug 2254
+    VNF scale up operation should fail if operation is not completed by arranging exceptions
+
+