Handle SSL from VNX driver

From python 2.7.9 on, the ssl verification is enabled by default,
This commit adds 2 options for VNX Manila driver, so user is able
to control the ssl verification.

Closes-bug: 1669202
Implements: blueprint vnx-ssl-verification-options
Change-Id: Iedad15e077c0537e133f81e6d537798482789160
This commit is contained in:
Peter Wang 2017-03-24 10:10:05 +08:00
parent ed19930c72
commit bf0f42858b
6 changed files with 74 additions and 4 deletions

View File

@ -43,7 +43,15 @@ EMC_NAS_OPTS = [
choices=['isilon', 'vnx', 'unity', 'vmax'], choices=['isilon', 'vnx', 'unity', 'vmax'],
help='Share backend.'), help='Share backend.'),
cfg.StrOpt('emc_nas_root_dir', cfg.StrOpt('emc_nas_root_dir',
help='The root directory where shares will be located.') help='The root directory where shares will be located.'),
cfg.BoolOpt('emc_ssl_cert_verify',
default=True,
help='If set to False the https client will not validate the '
'SSL certificate of the backend endpoint.'),
cfg.StrOpt('emc_ssl_cert_path',
help='Can be used to specify a non default path to a '
'CA_BUNDLE file or directory with certificates of trusted '
'CAs, which will be used to validate the backend.')
] ]
CONF = cfg.CONF CONF = cfg.CONF

View File

@ -27,6 +27,7 @@ from manila import exception
from manila.i18n import _ from manila.i18n import _
from manila.i18n import _LE from manila.i18n import _LE
from manila.share.drivers.dell_emc.plugins.vnx import constants from manila.share.drivers.dell_emc.plugins.vnx import constants
from manila.share.drivers.dell_emc.plugins.vnx import utils as vnx_utils
from manila import utils from manila import utils
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@ -40,8 +41,12 @@ class XMLAPIConnector(object):
self.password = configuration.emc_nas_password self.password = configuration.emc_nas_password
self.debug = debug self.debug = debug
self.auth_url = 'https://' + self.storage_ip + '/Login' self.auth_url = 'https://' + self.storage_ip + '/Login'
self._url = ('https://' + self.storage_ip self._url = 'https://{}/servlets/CelerraManagementServices'.format(
+ '/servlets/CelerraManagementServices') self.storage_ip)
context = vnx_utils.create_ssl_context(configuration)
if context:
https_handler = url_request.HTTPSHandler(context=context)
else:
https_handler = url_request.HTTPSHandler() https_handler = url_request.HTTPSHandler()
cookie_handler = url_request.HTTPCookieProcessor( cookie_handler = url_request.HTTPCookieProcessor(
http_cookiejar.CookieJar()) http_cookiejar.CookieJar())

View File

@ -15,10 +15,12 @@
import types import types
from manila.i18n import _LW
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
from oslo_utils import fnmatch from oslo_utils import fnmatch
from oslo_utils import timeutils from oslo_utils import timeutils
import ssl
CONF = cfg.CONF CONF = cfg.CONF
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@ -81,3 +83,24 @@ def do_match_any(full, matcher_list):
matched.add(item) matched.add(item)
not_matched = full - matched not_matched = full - matched
return matched, not_matched return matched, not_matched
def create_ssl_context(configuration):
"""Create context for ssl verification.
.. note:: starting from python 2.7.9 ssl adds create_default_context.
We need to keep compatibility with previous python as well.
"""
try:
if configuration.emc_ssl_cert_verify:
context = ssl.create_default_context(
capath=configuration.emc_ssl_cert_path)
else:
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
except AttributeError:
LOG.warning(_LW('Creating ssl context is not supported on this '
'version of Python, ssl verification is disabled.'))
context = None
return context

View File

@ -160,6 +160,8 @@ class CmdConnectorTest(test.TestCase):
self.configuration.emc_nas_login = fakes.FakeData.emc_nas_login self.configuration.emc_nas_login = fakes.FakeData.emc_nas_login
self.configuration.emc_nas_password = fakes.FakeData.emc_nas_password self.configuration.emc_nas_password = fakes.FakeData.emc_nas_password
self.configuration.emc_nas_server = fakes.FakeData.emc_nas_server self.configuration.emc_nas_server = fakes.FakeData.emc_nas_server
self.configuration.emc_ssl_cert_verify = False
self.configuration.emc_ssl_cert_path = None
self.sshpool = MockSSHPool() self.sshpool = MockSSHPool()
with mock.patch.object(utils, "SSHPool", with mock.patch.object(utils, "SSHPool",

View File

@ -14,6 +14,8 @@
# under the License. # under the License.
import ddt import ddt
import mock
import ssl
from manila.share.drivers.dell_emc.plugins.vnx import utils from manila.share.drivers.dell_emc.plugins.vnx import utils
from manila import test from manila import test
@ -42,3 +44,30 @@ class VNXUtilsTestCase(test.TestCase):
full, matchers) full, matchers)
self.assertEqual(matched, real_matched) self.assertEqual(matched, real_matched)
self.assertEqual(unmatched, real_unmatched) self.assertEqual(unmatched, real_unmatched)
class SslContextTestCase(test.TestCase):
def test_create_ssl_context(self):
configuration = mock.Mock()
configuration.emc_ssl_cert_verify = True
configuration.emc_ssl_cert_path = "./cert_path/"
self.mock_object(ssl, 'create_default_context')
context = utils.create_ssl_context(configuration)
self.assertIsNotNone(context)
def test_create_ssl_context_no_verify(self):
configuration = mock.Mock()
configuration.emc_ssl_cert_verify = False
self.mock_object(ssl, 'create_default_context')
context = utils.create_ssl_context(configuration)
self.assertFalse(context.check_hostname)
def test_no_create_default_context(self):
"""Test scenario of running on python 2.7.8 or earlier."""
configuration = mock.Mock()
configuration.emc_ssl_cert_verify = False
self.mock_object(ssl, 'create_default_context',
mock.Mock(side_effect=AttributeError))
context = utils.create_ssl_context(configuration)
self.assertIsNone(context)

View File

@ -0,0 +1,3 @@
upgrade:
- Added ``emc_ssl_cert_verify`` and ``emc_ssl_cert_path`` options for VNX SSL
verification. For more details, see OpenStack official documentation.