Merge "Add supported driver checks to Zone Manager"
This commit is contained in:
commit
29e00a3c63
@ -1014,6 +1014,10 @@ class FCSanLookupServiceException(CinderException):
|
||||
message = _("Fibre Channel SAN Lookup failure: %(reason)s")
|
||||
|
||||
|
||||
class ZoneManagerNotInitialized(CinderException):
|
||||
message = _("Fibre Channel Zone Manager not initialized")
|
||||
|
||||
|
||||
class BrocadeZoningCliException(CinderException):
|
||||
message = _("Brocade Fibre Channel Zoning CLI error: %(reason)s")
|
||||
|
||||
|
@ -49,11 +49,17 @@ class TestFCZoneManager(test.TestCase):
|
||||
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
|
||||
def setUp(self, opt_mock):
|
||||
super(TestFCZoneManager, self).setUp()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestFCZoneManager, self).__init__(*args, **kwargs)
|
||||
|
||||
def setup_fake_driver(self):
|
||||
config = conf.Configuration(None)
|
||||
config.fc_fabric_names = fabric_name
|
||||
|
||||
def fake_build_driver(self):
|
||||
self.driver = mock.Mock(fc_zone_driver.FCZoneDriver)
|
||||
self.set_initialized(True)
|
||||
|
||||
self.mock_object(fc_zone_manager.ZoneManager, '_build_driver',
|
||||
fake_build_driver)
|
||||
@ -61,13 +67,48 @@ class TestFCZoneManager(test.TestCase):
|
||||
self.zm = fc_zone_manager.ZoneManager(configuration=config)
|
||||
self.configuration = conf.Configuration(None)
|
||||
self.configuration.fc_fabric_names = fabric_name
|
||||
self.driver = mock.Mock(fc_zone_driver.FCZoneDriver)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TestFCZoneManager, self).__init__(*args, **kwargs)
|
||||
def test_unsupported_driver_disabled(self):
|
||||
config = conf.Configuration(fc_zone_manager.zone_manager_opts,
|
||||
'fc-zone-manager')
|
||||
config.fc_fabric_names = fabric_name
|
||||
config.enable_unsupported_driver = False
|
||||
|
||||
def fake_import(self, *args, **kwargs):
|
||||
fake_driver = mock.Mock(fc_zone_driver.FCZoneDriver)
|
||||
fake_driver.supported = False
|
||||
return fake_driver
|
||||
|
||||
self.patch('oslo_utils.importutils.import_object',
|
||||
fake_import)
|
||||
|
||||
zm = fc_zone_manager.ZoneManager(configuration=config)
|
||||
self.assertFalse(zm.driver.supported)
|
||||
self.assertFalse(zm.initialized)
|
||||
|
||||
def test_unsupported_driver_enabled(self):
|
||||
config = conf.Configuration(None)
|
||||
config.fc_fabric_names = fabric_name
|
||||
|
||||
def fake_import(self, *args, **kwargs):
|
||||
fake_driver = mock.Mock(fc_zone_driver.FCZoneDriver)
|
||||
fake_driver.supported = False
|
||||
return fake_driver
|
||||
|
||||
self.patch('oslo_utils.importutils.import_object',
|
||||
fake_import)
|
||||
|
||||
with mock.patch(
|
||||
'cinder.volume.configuration.Configuration') as mock_config:
|
||||
mock_config.return_value.zone_driver = 'test'
|
||||
mock_config.return_value.enable_unsupported_driver = True
|
||||
zm = fc_zone_manager.ZoneManager(configuration=config)
|
||||
self.assertFalse(zm.driver.supported)
|
||||
self.assertTrue(zm.initialized)
|
||||
|
||||
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
|
||||
def test_add_connection(self, opt_mock):
|
||||
self.setup_fake_driver()
|
||||
with mock.patch.object(self.zm.driver, 'add_connection')\
|
||||
as add_connection_mock:
|
||||
self.zm.driver.get_san_context.return_value = fabric_map
|
||||
@ -80,6 +121,7 @@ class TestFCZoneManager(test.TestCase):
|
||||
|
||||
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
|
||||
def test_add_connection_error(self, opt_mock):
|
||||
self.setup_fake_driver()
|
||||
with mock.patch.object(self.zm.driver, 'add_connection')\
|
||||
as add_connection_mock:
|
||||
add_connection_mock.side_effect = exception.FCZoneDriverException
|
||||
@ -88,6 +130,7 @@ class TestFCZoneManager(test.TestCase):
|
||||
|
||||
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
|
||||
def test_delete_connection(self, opt_mock):
|
||||
self.setup_fake_driver()
|
||||
with mock.patch.object(self.zm.driver, 'delete_connection')\
|
||||
as delete_connection_mock:
|
||||
self.zm.driver.get_san_context.return_value = fabric_map
|
||||
@ -100,6 +143,7 @@ class TestFCZoneManager(test.TestCase):
|
||||
|
||||
@mock.patch('oslo_config.cfg._is_opt_registered', return_value=False)
|
||||
def test_delete_connection_error(self, opt_mock):
|
||||
self.setup_fake_driver()
|
||||
with mock.patch.object(self.zm.driver, 'delete_connection')\
|
||||
as del_connection_mock:
|
||||
del_connection_mock.side_effect = exception.FCZoneDriverException
|
||||
|
@ -44,3 +44,13 @@ class FCZoneDriver(
|
||||
def __init__(self, **kwargs):
|
||||
super(FCZoneDriver, self).__init__(**kwargs)
|
||||
LOG.debug("Initializing FCZoneDriver")
|
||||
|
||||
# If a driver hasn't maintained their CI system, this will get set
|
||||
# to False, which prevents the driver from starting.
|
||||
# Add enable_unsupported_driver = True in cinder.conf to get the
|
||||
# unsupported driver started.
|
||||
self._supported = True
|
||||
|
||||
@property
|
||||
def supported(self):
|
||||
return self._supported
|
||||
|
@ -37,7 +37,7 @@ from oslo_utils import importutils
|
||||
import six
|
||||
|
||||
from cinder import exception
|
||||
from cinder.i18n import _, _LI
|
||||
from cinder.i18n import _, _LE, _LI, _LW
|
||||
from cinder.volume import configuration as config
|
||||
from cinder.zonemanager import fc_common
|
||||
import cinder.zonemanager.fczm_constants as zone_constant
|
||||
@ -61,7 +61,16 @@ zone_manager_opts = [
|
||||
cfg.StrOpt('fc_san_lookup_service',
|
||||
default='cinder.zonemanager.drivers.brocade'
|
||||
'.brcd_fc_san_lookup_service.BrcdFCSanLookupService',
|
||||
help='FC SAN Lookup Service')
|
||||
help='FC SAN Lookup Service'),
|
||||
cfg.BoolOpt('enable_unsupported_driver',
|
||||
default=False,
|
||||
help="Set this to True when you want to allow an unsupported "
|
||||
"zone manager driver to start. Drivers that haven't "
|
||||
"maintained a working CI system and testing are marked "
|
||||
"as unsupported until CI is working again. This also "
|
||||
"marks a driver as deprecated and may be removed in the "
|
||||
"next release."),
|
||||
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
@ -81,6 +90,7 @@ class ZoneManager(fc_common.FCCommon):
|
||||
|
||||
VERSION = "1.0.2"
|
||||
driver = None
|
||||
_initialized = False
|
||||
fabric_names = []
|
||||
|
||||
def __new__(class_, *args, **kwargs):
|
||||
@ -94,6 +104,7 @@ class ZoneManager(fc_common.FCCommon):
|
||||
|
||||
self.configuration = config.Configuration(zone_manager_opts,
|
||||
'fc-zone-manager')
|
||||
self.set_initialized(False)
|
||||
self._build_driver()
|
||||
|
||||
def _build_driver(self):
|
||||
@ -102,11 +113,52 @@ class ZoneManager(fc_common.FCCommon):
|
||||
{'driver': zone_driver})
|
||||
|
||||
zm_config = config.Configuration(zone_manager_opts, 'fc-zone-manager')
|
||||
# Initialize vendor specific implementation of FCZoneDriver
|
||||
# Initialize vendor specific implementation of FCZoneDriver
|
||||
self.driver = importutils.import_object(
|
||||
zone_driver,
|
||||
configuration=zm_config)
|
||||
|
||||
if not self.driver.supported:
|
||||
self._log_unsupported_driver_warning()
|
||||
|
||||
if not self.configuration.enable_unsupported_driver:
|
||||
LOG.error(_LE("Unsupported drivers are disabled."
|
||||
" You can re-enable by adding "
|
||||
"enable_unsupported_driver=True to the "
|
||||
"fc-zone-manager section in cinder.conf"),
|
||||
resource={'type': 'zone_manager',
|
||||
'id': self.__class__.__name__})
|
||||
return
|
||||
|
||||
self.set_initialized(True)
|
||||
|
||||
@property
|
||||
def initialized(self):
|
||||
return self._initialized
|
||||
|
||||
def set_initialized(self, value=True):
|
||||
self._initialized = value
|
||||
|
||||
def _require_initialized(self):
|
||||
"""Verifies that the zone manager has been properly initialized."""
|
||||
if not self.initialized:
|
||||
LOG.error(_LE("Fibre Channel Zone Manager is not initialized."""))
|
||||
raise exception.ZoneManagerNotInitialized()
|
||||
else:
|
||||
self._log_unsupported_driver_warning()
|
||||
|
||||
def _log_unsupported_driver_warning(self):
|
||||
"""Annoy the log about unsupported fczm drivers."""
|
||||
if not self.driver.supported:
|
||||
LOG.warning(_LW("Zone Manager driver (%(driver_name)s %(version)s)"
|
||||
" is currently unsupported and may be removed in "
|
||||
"the next release of OpenStack. Use at your own "
|
||||
"risk."),
|
||||
{'driver_name': self.driver.__class__.__name__,
|
||||
'version': self.driver.get_version()},
|
||||
resource={'type': 'zone_manager',
|
||||
'id': self.driver.__class__.__name__})
|
||||
|
||||
def get_zoning_state_ref_count(self, initiator_wwn, target_wwn):
|
||||
"""Zone management state check.
|
||||
|
||||
@ -136,6 +188,17 @@ class ZoneManager(fc_common.FCCommon):
|
||||
host_name = None
|
||||
storage_system = None
|
||||
|
||||
try:
|
||||
# Make sure the driver is loaded and we are initialized
|
||||
self._log_unsupported_driver_warning()
|
||||
self._require_initialized()
|
||||
except exception.ZoneManagerNotInitialized:
|
||||
LOG.error(_LE("Cannot add Fibre Channel Zone because the "
|
||||
"Zone Manager is not initialized properly."),
|
||||
resource={'type': 'zone_manager',
|
||||
'id': self.__class__.__name__})
|
||||
return
|
||||
|
||||
try:
|
||||
initiator_target_map = (
|
||||
conn_info[zone_constant.DATA][zone_constant.IT_MAP])
|
||||
@ -202,6 +265,17 @@ class ZoneManager(fc_common.FCCommon):
|
||||
host_name = None
|
||||
storage_system = None
|
||||
|
||||
try:
|
||||
# Make sure the driver is loaded and we are initialized
|
||||
self._log_unsupported_driver_warning()
|
||||
self._require_initialized()
|
||||
except exception.ZoneManagerNotInitialized:
|
||||
LOG.error(_LE("Cannot delete fibre channel zone because the "
|
||||
"Zone Manager is not initialized properly."),
|
||||
resource={'type': 'zone_manager',
|
||||
'id': self.__class__.__name__})
|
||||
return
|
||||
|
||||
try:
|
||||
initiator_target_map = (
|
||||
conn_info[zone_constant.DATA][zone_constant.IT_MAP])
|
||||
|
@ -35,12 +35,18 @@ def create_zone_manager():
|
||||
if config.safe_get('zoning_mode') == 'fabric':
|
||||
LOG.debug("FC Zone Manager enabled.")
|
||||
zm = fc_zone_manager.ZoneManager()
|
||||
LOG.info(_LI("Using FC Zone Manager %(zm_version)s,"
|
||||
" Driver %(drv_name)s %(drv_version)s."),
|
||||
{'zm_version': zm.get_version(),
|
||||
'drv_name': zm.driver.__class__.__name__,
|
||||
'drv_version': zm.driver.get_version()})
|
||||
return zm
|
||||
if zm.initialized:
|
||||
LOG.info(_LI("Using FC Zone Manager %(zm_version)s,"
|
||||
" Driver %(drv_name)s %(drv_version)s."),
|
||||
{'zm_version': zm.get_version(),
|
||||
'drv_name': zm.driver.__class__.__name__,
|
||||
'drv_version': zm.driver.get_version()})
|
||||
return zm
|
||||
else:
|
||||
LOG.debug("FC Zone Manager %(zm_version)s disabled",
|
||||
{"zm_version": zm.get_version()})
|
||||
return None
|
||||
|
||||
else:
|
||||
LOG.debug("FC Zone Manager not enabled in cinder.conf.")
|
||||
return None
|
||||
|
Loading…
Reference in New Issue
Block a user