[Infinidat] add support for TLS/SSL communication

Infinidat driver doesn't support TLS/SSL communication
and uses plain HTTP for storage management operations.

This patch adds support for SSL/TLS communication for
storage management operations. Use `infinidat_use_ssl`
under backend section to enable or disable TLS/SSL
communication between the Manila share service and the
storage backend. And `infinidat_suppress_ssl_warnings`
under backend section to suppress requests library SSL
certificate warnings.

Closes-Bug: #1986653
Signed-off-by: Alexander Deiter <adeiter@infinidat.com>
Change-Id: Ia6bbde9aa1702be83f737ab6876a522fa30381c7
This commit is contained in:
Alexander Deiter 2022-08-19 17:07:56 +03:00
parent 724510972c
commit 52dac76194
3 changed files with 67 additions and 9 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2017 Infinidat Ltd. # Copyright 2022 Infinidat Ltd.
# All Rights Reserved. # All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -22,6 +22,7 @@ import ipaddress
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import units from oslo_utils import units
import requests
from manila.common import constants from manila.common import constants
from manila import exception from manila import exception
@ -32,9 +33,12 @@ from manila import version
try: try:
import capacity import capacity
import infinisdk
except ImportError: except ImportError:
capacity = None capacity = None
try:
import infinisdk
except ImportError:
infinisdk = None infinisdk = None
@ -43,7 +47,14 @@ LOG = logging.getLogger(__name__)
infinidat_connection_opts = [ infinidat_connection_opts = [
cfg.HostAddressOpt('infinibox_hostname', cfg.HostAddressOpt('infinibox_hostname',
help='The name (or IP address) for the INFINIDAT ' help='The name (or IP address) for the INFINIDAT '
'Infinibox storage system.'), ] 'Infinibox storage system.'),
cfg.BoolOpt('infinidat_use_ssl',
help='Use SSL to connect to the INFINIDAT Infinibox storage '
'system.',
default=False),
cfg.BoolOpt('infinidat_suppress_ssl_warnings',
help='Suppress requests library SSL certificate warnings.',
default=False), ]
infinidat_auth_opts = [ infinidat_auth_opts = [
cfg.StrOpt('infinibox_login', cfg.StrOpt('infinibox_login',
@ -103,8 +114,9 @@ class InfiniboxShareDriver(driver.ShareDriver):
self.configuration.append_config_values(infinidat_auth_opts) self.configuration.append_config_values(infinidat_auth_opts)
self.configuration.append_config_values(infinidat_general_opts) self.configuration.append_config_values(infinidat_general_opts)
def _setup_and_get_system_object(self, management_address, auth): def _setup_and_get_system_object(self, management_address, auth, use_ssl):
system = infinisdk.InfiniBox(management_address, auth=auth) system = infinisdk.InfiniBox(management_address, auth=auth,
use_ssl=use_ssl)
system.api.add_auto_retry( system.api.add_auto_retry(
lambda e: isinstance( lambda e: isinstance(
e, infinisdk.core.exceptions.APITransportFailure) and e, infinisdk.core.exceptions.APITransportFailure) and
@ -115,11 +127,22 @@ class InfiniboxShareDriver(driver.ShareDriver):
def do_setup(self, context): def do_setup(self, context):
"""Driver initialization""" """Driver initialization"""
if capacity is None:
msg = _("Missing 'capacity' python module, ensure the library"
" is installed and available.")
raise exception.ManilaException(message=msg)
if infinisdk is None: if infinisdk is None:
msg = _("Missing 'infinisdk' python module, ensure the library" msg = _("Missing 'infinisdk' python module, ensure the library"
" is installed and available.") " is installed and available.")
raise exception.ManilaException(message=msg) raise exception.ManilaException(message=msg)
if self.configuration.safe_get('infinidat_suppress_ssl_warnings'):
LOG.warning('Suppressing requests library SSL Warnings')
rpu = requests.packages.urllib3 # pylint: disable=no-member
rpu.disable_warnings(rpu.exceptions.InsecureRequestWarning)
rpu.disable_warnings(rpu.exceptions.InsecurePlatformWarning)
use_ssl = self.configuration.safe_get('infinidat_use_ssl')
infinibox_login = self._safe_get_from_config_or_fail('infinibox_login') infinibox_login = self._safe_get_from_config_or_fail('infinibox_login')
infinibox_password = ( infinibox_password = (
self._safe_get_from_config_or_fail('infinibox_password')) self._safe_get_from_config_or_fail('infinibox_password'))
@ -135,8 +158,8 @@ class InfiniboxShareDriver(driver.ShareDriver):
self._safe_get_from_config_or_fail( self._safe_get_from_config_or_fail(
'infinidat_nas_network_space_name')) 'infinidat_nas_network_space_name'))
self._system = ( self._system = self._setup_and_get_system_object(management_address,
self._setup_and_get_system_object(management_address, auth)) auth, use_ssl)
backend_name = self.configuration.safe_get('share_backend_name') backend_name = self.configuration.safe_get('share_backend_name')
self._backend_name = backend_name or self.__class__.__name__ self._backend_name = backend_name or self.__class__.__name__

View File

@ -1,4 +1,4 @@
# Copyright 2017 Infinidat Ltd. # Copyright 2022 Infinidat Ltd.
# All Rights Reserved. # All Rights Reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may # Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -97,6 +97,8 @@ class InfiniboxDriverTestCaseBase(test.TestCase):
self.configuration.infinidat_thin_provision = True self.configuration.infinidat_thin_provision = True
self.configuration.infinibox_login = 'user' self.configuration.infinibox_login = 'user'
self.configuration.infinibox_password = 'pass' self.configuration.infinibox_password = 'pass'
self.configuration.infinidat_use_ssl = False
self.configuration.infinidat_suppress_ssl_warnings = False
self.configuration.network_config_group = 'test_network_config_group' self.configuration.network_config_group = 'test_network_config_group'
self.configuration.admin_network_config_group = ( self.configuration.admin_network_config_group = (
@ -205,6 +207,11 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase):
self.assertRaises(exception.ManilaException, self.assertRaises(exception.ManilaException,
self.driver.do_setup, None) self.driver.do_setup, None)
@mock.patch("manila.share.drivers.infinidat.infinibox.capacity", None)
def test_no_capacity_module(self):
self.assertRaises(exception.ManilaException,
self.driver.do_setup, None)
def test_no_auth_parameters(self): def test_no_auth_parameters(self):
self.configuration.infinibox_login = None self.configuration.infinibox_login = None
self.configuration.infinibox_password = None self.configuration.infinibox_password = None
@ -225,13 +232,32 @@ class InfiniboxDriverTestCase(InfiniboxDriverTestCaseBase):
self.configuration.infinibox_password) self.configuration.infinibox_password)
self.driver._setup_and_get_system_object( self.driver._setup_and_get_system_object(
self.configuration.infinibox_hostname, auth) self.configuration.infinibox_hostname, auth,
self.configuration.infinidat_use_ssl)
self._system.api.add_auto_retry.assert_called_once() self._system.api.add_auto_retry.assert_called_once()
self._system.api.set_source_identifier.assert_called_once_with( self._system.api.set_source_identifier.assert_called_once_with(
infinibox._INFINIDAT_MANILA_IDENTIFIER) infinibox._INFINIDAT_MANILA_IDENTIFIER)
self._system.login.assert_called_once() self._system.login.assert_called_once()
@skip_driver_setup
@mock.patch('manila.share.drivers.infinidat.infinibox.'
'infinisdk.InfiniBox')
@mock.patch('requests.packages.urllib3')
def test_do_setup_ssl_enabled(self, urllib3, infinibox):
auth = (self.configuration.infinibox_login,
self.configuration.infinibox_password)
self.configuration.infinidat_use_ssl = True
self.configuration.infinidat_suppress_ssl_warnings = True
self.driver.do_setup(None)
expected = [
mock.call(urllib3.exceptions.InsecureRequestWarning),
mock.call(urllib3.exceptions.InsecurePlatformWarning)]
urllib3.disable_warnings.assert_has_calls(expected)
infinibox.assert_called_once_with(
self.configuration.infinibox_hostname, auth=auth,
use_ssl=self.configuration.infinidat_use_ssl)
def test_get_share_stats_refreshes(self): def test_get_share_stats_refreshes(self):
self.driver._update_share_stats() self.driver._update_share_stats()
result = self.driver.get_share_stats() result = self.driver.get_share_stats()

View File

@ -0,0 +1,9 @@
---
fixes:
- |
Infinidat Driver `bug #1986653
<https://bugs.launchpad.net/manila/+bug/1986653>`_:
Fixed Infinidat driver to use TLS/SSL communication between the Manila
share service and the storage backend. Admin can set `True` or `False`
for the `infinidat_use_ssl` and `infinidat_suppress_ssl_warnings` options
in the driver section of manila.conf to enable or disable these features.