diff --git a/cinder/tests/unit/volume/drivers/test_infinidat.py b/cinder/tests/unit/volume/drivers/test_infinidat.py index 47c6e3f68d8..964f4033b96 100644 --- a/cinder/tests/unit/volume/drivers/test_infinidat.py +++ b/cinder/tests/unit/volume/drivers/test_infinidat.py @@ -89,25 +89,15 @@ class InfiniboxDriverTestCaseBase(test.TestCase): def setUp(self): super(InfiniboxDriverTestCaseBase, self).setUp() - # create mock configuration - self.configuration = mock.Mock(spec=configuration.Configuration) - self.configuration.infinidat_storage_protocol = TEST_FC_PROTOCOL - self.configuration.san_ip = 'mockbox' - self.configuration.infinidat_pool_name = 'mockpool' - self.configuration.san_thin_provision = True - self.configuration.san_login = 'user' - self.configuration.san_password = 'pass' - self.configuration.volume_backend_name = 'mock' - self.configuration.volume_dd_blocksize = '1M' - self.configuration.use_multipath_for_image_xfer = False - self.configuration.enforce_multipath_for_image_xfer = False - self.configuration.num_volume_device_scan_tries = 1 - self.configuration.san_is_local = False - self.configuration.chap_username = None - self.configuration.chap_password = None - self.configuration.infinidat_use_compression = None - self.configuration.max_over_subscription_ratio = 10.0 - + self.configuration = configuration.Configuration(None) + self.configuration.append_config_values(infinidat.infinidat_opts) + self.override_config('san_ip', 'infinibox', + configuration.SHARED_CONF_GROUP) + self.override_config('san_login', 'user', + configuration.SHARED_CONF_GROUP) + self.override_config('san_password', 'password', + configuration.SHARED_CONF_GROUP) + self.override_config('infinidat_pool_name', 'pool') self.driver = infinidat.InfiniboxVolumeDriver( configuration=self.configuration) self._system = self._infinibox_mock() @@ -217,6 +207,16 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): infinidat._INFINIDAT_CINDER_IDENTIFIER) self._system.login.assert_called_once() + @mock.patch('cinder.volume.drivers.infinidat.infinisdk.InfiniBox') + @ddt.data(True, False) + def test_ssl_options(self, use_ssl, infinibox): + auth = (self.configuration.san_login, + self.configuration.san_password) + self.override_config('driver_use_ssl', use_ssl) + self.driver.do_setup(None) + infinibox.assert_called_once_with(self.configuration.san_ip, + auth=auth, use_ssl=use_ssl) + def test_initialize_connection(self): self._system.hosts.safe_get.return_value = None result = self.driver.initialize_connection(test_volume, test_connector) @@ -299,9 +299,10 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): self.driver.get_volume_stats) def test_get_volume_stats_max_over_subscription_ratio(self): + self.override_config('san_thin_provision', True) + self.override_config('max_over_subscription_ratio', 10.0) result = self.driver.get_volume_stats() - # check the defaults defined in setUp - self.assertEqual(10.0, result['max_over_subscription_ratio']) + self.assertEqual('10.0', result['max_over_subscription_ratio']) self.assertTrue(result['thin_provisioning_support']) self.assertFalse(result['thick_provisioning_support']) @@ -326,7 +327,7 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): @mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs") def test_create_volume_compression_enabled(self, *mocks): - self.configuration.infinidat_use_compression = True + self.override_config('infinidat_use_compression', True) self.driver.create_volume(test_volume) self.assertTrue( self._system.volumes.create.call_args[1]["compression_enabled"] @@ -334,7 +335,7 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase): @mock.patch("cinder.volume.volume_types.get_volume_type_qos_specs") def test_create_volume_compression_not_enabled(self, *mocks): - self.configuration.infinidat_use_compression = False + self.override_config('infinidat_use_compression', False) self.driver.create_volume(test_volume) self.assertFalse( self._system.volumes.create.call_args[1]["compression_enabled"] @@ -875,13 +876,15 @@ class InfiniboxDriverTestCaseFC(InfiniboxDriverTestCaseBase): class InfiniboxDriverTestCaseISCSI(InfiniboxDriverTestCaseBase): def setUp(self): super(InfiniboxDriverTestCaseISCSI, self).setUp() - self.configuration.infinidat_storage_protocol = TEST_ISCSI_PROTOCOL - self.configuration.infinidat_iscsi_netspaces = [TEST_ISCSI_NAMESPACE1] - self.configuration.use_chap_auth = False + self.override_config('infinidat_storage_protocol', + TEST_ISCSI_PROTOCOL) + self.override_config('infinidat_iscsi_netspaces', + [TEST_ISCSI_NAMESPACE1]) + self.override_config('use_chap_auth', False) self.driver.do_setup(None) def test_setup_without_netspaces_configured(self): - self.configuration.infinidat_iscsi_netspaces = [] + self.override_config('infinidat_iscsi_netspaces', []) self.assertRaises(exception.VolumeDriverException, self.driver.do_setup, None) @@ -920,7 +923,7 @@ class InfiniboxDriverTestCaseISCSI(InfiniboxDriverTestCaseBase): test_volume, test_connector) def test_initialize_connection_with_chap(self): - self.configuration.use_chap_auth = True + self.override_config('use_chap_auth', True) result = self.driver.initialize_connection(test_volume, test_connector) self.assertEqual(1, result['data']['target_lun']) self.assertEqual('CHAP', result['data']['auth_method']) @@ -928,8 +931,8 @@ class InfiniboxDriverTestCaseISCSI(InfiniboxDriverTestCaseBase): self.assertIn('auth_password', result['data']) def test_initialize_connection_multiple_netspaces(self): - self.configuration.infinidat_iscsi_netspaces = [ - TEST_ISCSI_NAMESPACE1, TEST_ISCSI_NAMESPACE2] + self.override_config('infinidat_iscsi_netspaces', + [TEST_ISCSI_NAMESPACE1, TEST_ISCSI_NAMESPACE2]) self._system.network_spaces.safe_get.side_effect = [ self._mock_name_space1, self._mock_name_space2] result = self.driver.initialize_connection(test_volume, test_connector) @@ -957,8 +960,8 @@ class InfiniboxDriverTestCaseISCSI(InfiniboxDriverTestCaseBase): self.assertEqual(expected, result) def test_initialize_connection_multiple_netspaces_multipath(self): - self.configuration.infinidat_iscsi_netspaces = [ - TEST_ISCSI_NAMESPACE1, TEST_ISCSI_NAMESPACE2] + self.override_config('infinidat_iscsi_netspaces', + [TEST_ISCSI_NAMESPACE1, TEST_ISCSI_NAMESPACE2]) self._system.network_spaces.safe_get.side_effect = [ self._mock_name_space1, self._mock_name_space2] self._mock_name_space1.get_ips.return_value = [ diff --git a/cinder/volume/drivers/infinidat.py b/cinder/volume/drivers/infinidat.py index df1184735bb..009d0dc4a11 100644 --- a/cinder/volume/drivers/infinidat.py +++ b/cinder/volume/drivers/infinidat.py @@ -124,10 +124,11 @@ class InfiniboxVolumeDriver(san.SanISCSIDriver): 1.7 - fixed iSCSI to return all portals 1.8 - added revert to snapshot 1.9 - added manage/unmanage/manageable-list volume/snapshot + 1.10 - added support for TLS/SSL communication """ - VERSION = '1.9' + VERSION = '1.10' # ThirdPartySystems wiki page CI_WIKI_NAME = "INFINIDAT_CI" @@ -144,11 +145,14 @@ class InfiniboxVolumeDriver(san.SanISCSIDriver): 'chap_username', 'chap_password', 'san_thin_provision', 'use_multipath_for_image_xfer', 'enforce_multipath_for_image_xfer', 'num_volume_device_scan_tries', 'volume_dd_blocksize', + 'driver_use_ssl', 'suppress_requests_ssl_warnings', 'max_over_subscription_ratio') return infinidat_opts + additional_opts - def _setup_and_get_system_object(self, management_address, auth): - system = infinisdk.InfiniBox(management_address, auth=auth) + def _setup_and_get_system_object(self, management_address, auth, + use_ssl=False): + system = infinisdk.InfiniBox(management_address, auth=auth, + use_ssl=use_ssl) system.api.add_auto_retry( lambda e: isinstance( e, infinisdk.core.exceptions.APITransportFailure) and @@ -165,9 +169,10 @@ class InfiniboxVolumeDriver(san.SanISCSIDriver): raise exception.VolumeDriverException(message=msg) auth = (self.configuration.san_login, self.configuration.san_password) + use_ssl = self.configuration.driver_use_ssl self.management_address = self.configuration.san_ip - self._system = ( - self._setup_and_get_system_object(self.management_address, auth)) + self._system = self._setup_and_get_system_object( + self.management_address, auth, use_ssl=use_ssl) backend_name = self.configuration.safe_get('volume_backend_name') self._backend_name = backend_name or self.__class__.__name__ self._volume_stats = None diff --git a/doc/source/configuration/block-storage/drivers/infinidat-volume-driver.rst b/doc/source/configuration/block-storage/drivers/infinidat-volume-driver.rst index 7e1b26e9b92..65e58a94623 100644 --- a/doc/source/configuration/block-storage/drivers/infinidat-volume-driver.rst +++ b/doc/source/configuration/block-storage/drivers/infinidat-volume-driver.rst @@ -69,6 +69,20 @@ Configure the driver back-end section with the parameters below. san_ip = InfiniBox management IP +* Verify that the InfiniBox array can be managed via an HTTPS connection. + And the ``driver_use_ssl`` parameter should be set to ``true`` to enable + use of the HTTPS protocol. HTTP can also be used if ``driver_use_ssl`` + is set to (or defaults to) ``false``. To suppress requests library SSL + certificate warnings, set the ``suppress_requests_ssl_warnings`` parameter + to ``true``. + + .. code-block:: ini + + driver_use_ssl = true/false + suppress_requests_ssl_warnings = true/false + + These parameters defaults to ``false``. + * Configure user credentials. The driver requires an InfiniBox user with administrative privileges. @@ -178,6 +192,8 @@ Configuration example [infinidat-pool-a] volume_driver = cinder.volume.drivers.infinidat.InfiniboxVolumeDriver volume_backend_name = infinidat-pool-a + driver_use_ssl = true + suppress_requests_ssl_warnings = true san_ip = 10.1.2.3 san_login = openstackuser san_password = openstackpass diff --git a/releasenotes/notes/bug-1981982-infinidat-fix-ssl-options-6ddd852c24b16760.yaml b/releasenotes/notes/bug-1981982-infinidat-fix-ssl-options-6ddd852c24b16760.yaml new file mode 100644 index 00000000000..91da2d9656c --- /dev/null +++ b/releasenotes/notes/bug-1981982-infinidat-fix-ssl-options-6ddd852c24b16760.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Infinidat Driver `bug #1981982 + `_: + Fixed Infinidat driver to use TLS/SSL communication between the Cinder + volume service and the storage backend. Admin can set `True` or `False` + for the `driver_use_ssl` and `suppress_requests_ssl_warnings` options in + the driver section of cinder.conf to enable or disable these features.