From dc8f020d77787ecf214b8565026015533f57cc7c Mon Sep 17 00:00:00 2001 From: Amit Oren Date: Tue, 6 Feb 2018 15:49:54 +0200 Subject: [PATCH] INFINIDAT: set REST API client parameters Communicating with the INFINIDAT InfiniBox backend is done using a REST API through a client implemented by the infinisdk package. This change sets the number of retries in case of an erroneous API call and sets the User-Agent string for the client. Change-Id: I58dceebcfd088a0f584c3107b9f0545eb86bd5eb --- manila/share/drivers/infinidat/infinibox.py | 22 +++++++++++-- .../share/drivers/infinidat/test_infinidat.py | 32 ++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/manila/share/drivers/infinidat/infinibox.py b/manila/share/drivers/infinidat/infinibox.py index 9813d11d96..42e9a3e998 100644 --- a/manila/share/drivers/infinidat/infinibox.py +++ b/manila/share/drivers/infinidat/infinibox.py @@ -74,6 +74,12 @@ _MANILA_TO_INFINIDAT_ACCESS_LEVEL = { constants.ACCESS_LEVEL_RO: 'RO', } +# Max retries for the REST API client in case of a failure: +_API_MAX_RETRIES = 5 +# Identifier used as the REST API User-Agent string: +_INFINIDAT_MANILA_IDENTIFIER = ( + "manila/%s" % version.version_info.release_string()) + def infinisdk_to_manila_exceptions(func): @functools.wraps(func) @@ -98,6 +104,16 @@ class InfiniboxShareDriver(driver.ShareDriver): self.configuration.append_config_values(infinidat_auth_opts) self.configuration.append_config_values(infinidat_general_opts) + def _setup_and_get_system_object(self, management_address, auth): + system = infinisdk.InfiniBox(management_address, auth=auth) + system.api.add_auto_retry( + lambda e: isinstance( + e, infinisdk.core.exceptions.APITransportFailure) and + "Interrupted system call" in e.error_desc, _API_MAX_RETRIES) + system.api.set_source_identifier(_INFINIDAT_MANILA_IDENTIFIER) + system.login() + return system + def do_setup(self, context): """Driver initialization""" if infinisdk is None: @@ -110,7 +126,7 @@ class InfiniboxShareDriver(driver.ShareDriver): self._safe_get_from_config_or_fail('infinibox_password')) auth = (infinibox_login, infinibox_password) - self.management_address = ( + management_address = ( self._safe_get_from_config_or_fail('infinibox_hostname')) self._pool_name = ( @@ -120,8 +136,8 @@ class InfiniboxShareDriver(driver.ShareDriver): self._safe_get_from_config_or_fail( 'infinidat_nas_network_space_name')) - self._system = infinisdk.InfiniBox(self.management_address, auth=auth) - self._system.login() + self._system = ( + self._setup_and_get_system_object(management_address, auth)) backend_name = self.configuration.safe_get('share_backend_name') self._backend_name = backend_name or self.__class__.__name__ diff --git a/manila/tests/share/drivers/infinidat/test_infinidat.py b/manila/tests/share/drivers/infinidat/test_infinidat.py index b8cd6e03b4..2ef8421819 100644 --- a/manila/tests/share/drivers/infinidat/test_infinidat.py +++ b/manila/tests/share/drivers/infinidat/test_infinidat.py @@ -15,6 +15,7 @@ """Unit tests for INFINIDAT InfiniBox share driver.""" import copy +import functools import mock from oslo_utils import units @@ -50,6 +51,14 @@ original_test_clone = mock.Mock(id=_MOCK_CLONE_ID, size=test_share.size, original_test_clone.__getitem__ = _create_mock__getitem__(original_test_clone) +def skip_driver_setup(func): + @functools.wraps(func) + def f(*args, **kwargs): + return func(*args, **kwargs) + f.__skip_driver_setup = True + return f + + class FakeInfinisdkException(Exception): def __init__(self, message=None, error_code=None, *args): self.message = message @@ -70,6 +79,11 @@ class FakeInfinisdkPermission(object): class InfiniboxDriverTestCaseBase(test.TestCase): + def _test_skips_driver_setup(self): + test_method_name = self.id().split('.')[-1] + test_method = getattr(self, test_method_name) + return getattr(test_method, '__skip_driver_setup', False) + def setUp(self): super(InfiniboxDriverTestCaseBase, self).setUp() @@ -108,7 +122,8 @@ class InfiniboxDriverTestCaseBase(test.TestCase): infinisdk.core.exceptions.InfiniSDKException = FakeInfinisdkException infinisdk.InfiniBox.return_value = self._system - self.driver.do_setup(None) + if not self._test_skips_driver_setup(): + self.driver.do_setup(None) def _infinibox_mock(self): result = mock.Mock() @@ -185,6 +200,21 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): self.assertRaises(exception.BadConfigurationException, self.driver.do_setup, None) + @skip_driver_setup + def test__setup_and_get_system_object(self): + # This test should skip the driver setup, as it generates more calls to + # the add_auto_retry, set_source_identifier and login methods: + auth = (self.configuration.infinibox_login, + self.configuration.infinibox_password) + + self.driver._setup_and_get_system_object( + self.configuration.infinibox_hostname, auth) + + self._system.api.add_auto_retry.assert_called_once() + self._system.api.set_source_identifier.assert_called_once_with( + infinibox._INFINIDAT_MANILA_IDENTIFIER) + self._system.login.assert_called_once() + def test_get_share_stats_refreshes(self): self.driver._update_share_stats() result = self.driver.get_share_stats()