Fix Infinidat driver to use TLS/SSL communication

Use `driver_use_ssl` under backend section to enable or disable TLS/SSL
communication between the Cinder volume service and the storage backend.
And `suppress_requests_ssl_warnings` under backend section to suppress
requests library SSL certificate warnings.

Closes-bug: #1981982
Change-Id: I4b302ffd1d0bef673143cd7db427bb9aac27ba33
Signed-off-by: Alexander Deiter <adeiter@infinidat.com>
This commit is contained in:
Alexander Deiter 2022-05-23 14:42:06 +04:00
parent e7fa57d9ad
commit ee67921a72
4 changed files with 70 additions and 37 deletions

View File

@ -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 = [

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,9 @@
---
fixes:
- |
Infinidat Driver `bug #1981982
<https://bugs.launchpad.net/cinder/+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.