diff --git a/cinder/tests/zonemanager/__init__.py b/cinder/tests/zonemanager/__init__.py new file mode 100644 index 00000000000..31285c4fc21 --- /dev/null +++ b/cinder/tests/zonemanager/__init__.py @@ -0,0 +1,14 @@ +# Copyright 2011 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/cinder/tests/test_brcd_fc_san_lookup_service.py b/cinder/tests/zonemanager/test_brcd_fc_san_lookup_service.py old mode 100755 new mode 100644 similarity index 79% rename from cinder/tests/test_brcd_fc_san_lookup_service.py rename to cinder/tests/zonemanager/test_brcd_fc_san_lookup_service.py index f9f7ba968ce..52ba43fd6fd --- a/cinder/tests/test_brcd_fc_san_lookup_service.py +++ b/cinder/tests/zonemanager/test_brcd_fc_san_lookup_service.py @@ -28,10 +28,9 @@ from cinder import exception from cinder.openstack.common import log as logging from cinder import test from cinder.volume import configuration as conf -from cinder.zonemanager.drivers.brocade.brcd_fc_san_lookup_service \ - import BrcdFCSanLookupService -import cinder.zonemanager.drivers.brocade.fc_zone_constants as ZoneConstant -from mock import patch +import cinder.zonemanager.drivers.brocade.brcd_fc_san_lookup_service \ + as brcd_lookup +from cinder.zonemanager.drivers.brocade import fc_zone_constants LOG = logging.getLogger(__name__) @@ -45,13 +44,16 @@ _device_map_to_verify = { 'target_port_wwn_list': ['20240002ac000a50']}} -class TestBrcdFCSanLookupService(BrcdFCSanLookupService, test.TestCase): +class TestBrcdFCSanLookupService(brcd_lookup.BrcdFCSanLookupService, + test.TestCase): def setUp(self): super(TestBrcdFCSanLookupService, self).setUp() self.client = paramiko.SSHClient() self.configuration = conf.Configuration(None) - self.configuration.set_default('fc_fabric_names', 'BRCD_FAB_2') + self.configuration.set_default('fc_fabric_names', 'BRCD_FAB_2', + 'fc-zone-manager') + self.configuration.fc_fabric_names = 'BRCD_FAB_2' self.create_configuration() # override some of the functions @@ -60,31 +62,33 @@ class TestBrcdFCSanLookupService(BrcdFCSanLookupService, test.TestCase): def create_configuration(self): fc_fabric_opts = [] - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_address_BRCD_FAB_2', + fc_fabric_opts.append(cfg.StrOpt('fc_fabric_address', default='10.24.49.100', help='')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_user_BRCD_FAB_2', + fc_fabric_opts.append(cfg.StrOpt('fc_fabric_user', default='admin', help='')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_password_BRCD_FAB_2', + fc_fabric_opts.append(cfg.StrOpt('fc_fabric_password', default='password', help='', secret=True)) - fc_fabric_opts.append(cfg.IntOpt('fc_fabric_port_BRCD_FAB_2', + fc_fabric_opts.append(cfg.IntOpt('fc_fabric_port', default=22, help='')) - fc_fabric_opts.append(cfg.StrOpt('principal_switch_wwn_BRCD_FAB_2', + fc_fabric_opts.append(cfg.StrOpt('principal_switch_wwn', default='100000051e55a100', help='')) - self.configuration.append_config_values(fc_fabric_opts) + self.fabric_configs = {} + config = conf.Configuration(fc_fabric_opts, 'BRCD_FAB_2') + self.fabric_configs['BRCD_FAB_2'] = config - @patch.object(BrcdFCSanLookupService, 'get_nameserver_info') + @mock.patch.object(brcd_lookup.BrcdFCSanLookupService, + 'get_nameserver_info') def test_get_device_mapping_from_network(self, get_nameserver_info_mock): initiator_list = ['10008c7cff523b01'] target_list = ['20240002ac000a50', '20240002ac000a40'] - with mock.patch.object(self.client, 'connect') \ - as client_connect_mock: + with mock.patch.object(self.client, 'connect') as client_connect_mock: get_nameserver_info_mock.return_value = (nsshow_data) device_map = self.get_device_mapping_from_network( initiator_list, target_list) self.assertDictMatch(device_map, _device_map_to_verify) - @patch.object(BrcdFCSanLookupService, '_get_switch_data') + @mock.patch.object(brcd_lookup.BrcdFCSanLookupService, '_get_switch_data') def test_get_nameserver_info(self, get_switch_data_mock): ns_info_list = [] ns_info_list_expected = ['20:1a:00:05:1e:e8:e3:29', @@ -94,7 +98,7 @@ class TestBrcdFCSanLookupService(BrcdFCSanLookupService, test.TestCase): self.assertEqual(ns_info_list, ns_info_list_expected) def test__get_switch_data(self): - cmd = ZoneConstant.NS_SHOW + cmd = fc_zone_constants.NS_SHOW with mock.patch.object(self.client, 'exec_command') \ as exec_command_mock: diff --git a/cinder/tests/test_brcd_fc_zone_client_cli.py b/cinder/tests/zonemanager/test_brcd_fc_zone_client_cli.py similarity index 100% rename from cinder/tests/test_brcd_fc_zone_client_cli.py rename to cinder/tests/zonemanager/test_brcd_fc_zone_client_cli.py diff --git a/cinder/tests/test_brcd_fc_zone_driver.py b/cinder/tests/zonemanager/test_brcd_fc_zone_driver.py similarity index 96% rename from cinder/tests/test_brcd_fc_zone_driver.py rename to cinder/tests/zonemanager/test_brcd_fc_zone_driver.py index e175688e06c..2cf154be004 100644 --- a/cinder/tests/test_brcd_fc_zone_driver.py +++ b/cinder/tests/zonemanager/test_brcd_fc_zone_driver.py @@ -63,15 +63,16 @@ class BrcdFcZoneDriverBaseTest(object): configuration = conf.Configuration(fc_test_opts) # fill up config configuration.zoning_mode = 'fabric' - configuration.zone_driver = ('cinder.tests.test_brcd_fc_zone_driver' - '.FakeBrcdFCZoneDriver') - configuration.brcd_sb_connector = ('cinder.tests.' + configuration.zone_driver = ('cinder.tests.zonemanager.' + 'test_brcd_fc_zone_driver.' + 'FakeBrcdFCZoneDriver') + configuration.brcd_sb_connector = ('cinder.tests.zonemanager.' 'test_brcd_fc_zone_driver' '.FakeBrcdFCZoneClientCLI') configuration.zoning_policy = 'initiator-target' configuration.zone_activate = True configuration.zone_name_prefix = 'openstack' - configuration.fc_san_lookup_service = ('cinder.tests.' + configuration.fc_san_lookup_service = ('cinder.tests.zonemanager.' 'test_brcd_fc_zone_driver.' 'FakeBrcdFCSanLookupService') diff --git a/cinder/tests/test_brcd_lookup_service.py b/cinder/tests/zonemanager/test_brcd_lookup_service.py similarity index 97% rename from cinder/tests/test_brcd_lookup_service.py rename to cinder/tests/zonemanager/test_brcd_lookup_service.py index 8a44b6d4d70..49a3b0cabac 100644 --- a/cinder/tests/test_brcd_lookup_service.py +++ b/cinder/tests/zonemanager/test_brcd_lookup_service.py @@ -50,7 +50,8 @@ class TestFCSanLookupService(FCSanLookupService, test.TestCase): configuration = conf.Configuration(None) # fill up config configuration.fc_san_lookup_service = ( - 'cinder.tests.test_brcd_lookup_service.FakeBrcdFCSanLookupService') + 'cinder.tests.zonemanager.test_brcd_lookup_service.' + 'FakeBrcdFCSanLookupService') return configuration def test_get_device_mapping_from_network(self): diff --git a/cinder/tests/test_fc_zone_manager.py b/cinder/tests/zonemanager/test_fc_zone_manager.py similarity index 100% rename from cinder/tests/test_fc_zone_manager.py rename to cinder/tests/zonemanager/test_fc_zone_manager.py diff --git a/cinder/tests/test_volume_manager_fc.py b/cinder/tests/zonemanager/test_volume_manager_fc.py similarity index 73% rename from cinder/tests/test_volume_manager_fc.py rename to cinder/tests/zonemanager/test_volume_manager_fc.py index c55939465c7..d44a4a7e50f 100644 --- a/cinder/tests/test_volume_manager_fc.py +++ b/cinder/tests/zonemanager/test_volume_manager_fc.py @@ -25,11 +25,9 @@ from cinder import exception from cinder import test from cinder import utils from cinder.volume import configuration as conf -from cinder.volume.driver import VolumeDriver -from cinder.volume.manager import VolumeManager -from cinder.zonemanager.fc_zone_manager import ZoneManager -from mock import Mock -from mock import patch +from cinder.volume import driver +from cinder.volume import manager +from cinder.zonemanager import fc_zone_manager init_target_map = {'10008c7cff523b01': ['20240002ac000a50']} conn_info = { @@ -53,95 +51,106 @@ conn_info_no_init_target_map = { } -class TestVolumeManager(VolumeManager, test.TestCase): +class TestVolumeManager(manager.VolumeManager, test.TestCase): def setUp(self): super(TestVolumeManager, self).setUp() self.configuration = conf.Configuration(None) - self.configuration.set_default('fc_fabric_names', 'BRCD_FAB_4') + self.configuration.set_default('fc_fabric_names', 'BRCD_FAB_4', + 'fc-zone-manager') self.configuration.zoning_mode = 'fabric' - self.driver = Mock(VolumeDriver) + self.driver = mock.Mock(driver.VolumeDriver) self.driver.initialize_connection.return_value = conn_info self.driver.terminate_connection.return_value = conn_info self.driver.create_export.return_value = None - self.db = Mock() + self.db = mock.Mock() self.db.volume_get.return_value = {'volume_type_id': None} self.db.volume_admin_metadata_get.return_value = {} - self.context_mock = Mock() + self.context_mock = mock.Mock() self.context_mock.elevated.return_value = None + self.zonemanager = fc_zone_manager.ZoneManager( + configuration=self.configuration) def __init__(self, *args, **kwargs): test.TestCase.__init__(self, *args, **kwargs) - @patch.object(utils, 'require_driver_initialized') + @mock.patch.object(utils, 'require_driver_initialized') def test_initialize_connection_voltype_fc_mode_fabric(self, utils_mock): utils_mock.return_value = True - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: self.initialize_connection(self.context_mock, None, None) add_del_conn_mock.assert_called_once_with(conn_info, 1) - @patch.object(utils, 'require_driver_initialized') + @mock.patch.object(utils, 'require_driver_initialized') def test_initialize_connection_voltype_fc_mode_none(self, utils_mock): utils_mock.return_value = True - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: self.configuration.zoning_mode = 'none' + self.zonemanager = None self.initialize_connection(self.context_mock, None, None) assert not add_del_conn_mock.called def test_terminate_connection_exception(self): - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: add_del_conn_mock.side_effect = exception.ZoneManagerException self.assertRaises(exception.VolumeBackendAPIException, self.terminate_connection, None, None, None, False) - @patch.object(utils, 'require_driver_initialized') + @mock.patch.object(utils, 'require_driver_initialized') def test_terminate_connection_voltype_fc_mode_fabric(self, utils_mock): utils_mock.return_value = True - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: self.terminate_connection(None, None, None, False) add_del_conn_mock.assert_called_once_with(conn_info, 0) - @patch.object(utils, 'require_driver_initialized') + @mock.patch.object(utils, 'require_driver_initialized') def test_terminate_connection_mode_none(self, utils_mock): utils_mock.return_value = True - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: self.configuration.zoning_mode = 'none' + self.zonemanager = None self.terminate_connection(None, None, None, False) assert not add_del_conn_mock.called - @patch.object(utils, 'require_driver_initialized') + @mock.patch.object(utils, 'require_driver_initialized') def test_terminate_connection_conn_info_none(self, utils_mock): utils_mock.return_value = True self.driver.terminate_connection.return_value = None - with mock.patch.object(VolumeManager, '_add_or_delete_fc_connection')\ + with mock.patch.object(manager.VolumeManager, + '_add_or_delete_fc_connection')\ as add_del_conn_mock: self.terminate_connection(None, None, None, False) assert not add_del_conn_mock.called - @patch.object(ZoneManager, 'add_connection') + @mock.patch.object(fc_zone_manager.ZoneManager, 'add_connection') def test__add_or_delete_connection_add(self, add_connection_mock): self._add_or_delete_fc_connection(conn_info, 1) add_connection_mock.assert_called_once_with(init_target_map) - @patch.object(ZoneManager, 'delete_connection') + @mock.patch.object(fc_zone_manager.ZoneManager, 'delete_connection') def test__add_or_delete_connection_delete(self, delete_connection_mock): self._add_or_delete_fc_connection(conn_info, 0) delete_connection_mock.assert_called_once_with(init_target_map) - @patch.object(ZoneManager, 'delete_connection') + @mock.patch.object(fc_zone_manager.ZoneManager, 'delete_connection') def test__add_or_delete_connection_no_init_target_map(self, del_conn_mock): self._add_or_delete_fc_connection(conn_info_no_init_target_map, 0) diff --git a/cinder/zonemanager/drivers/brocade/brcd_fabric_opts.py b/cinder/zonemanager/drivers/brocade/brcd_fabric_opts.py new file mode 100644 index 00000000000..1461ea061c2 --- /dev/null +++ b/cinder/zonemanager/drivers/brocade/brcd_fabric_opts.py @@ -0,0 +1,63 @@ +# (c) Copyright 2014 Brocade Communications Systems Inc. +# All Rights Reserved. +# +# Copyright 2014 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +from oslo.config import cfg + +from cinder.openstack.common import log as logging +from cinder.volume.configuration import Configuration + +brcd_zone_opts = [ + cfg.StrOpt('fc_fabric_address', + default='', + help='Management IP of fabric'), + cfg.StrOpt('fc_fabric_user', + default='', + help='Fabric user ID'), + cfg.StrOpt('fc_fabric_password', + default='', + help='Password for user', + secret=True), + cfg.IntOpt('fc_fabric_port', + default=22, + help='Connecting port'), + cfg.StrOpt('zoning_policy', + default='initiator-target', + help='overridden zoning policy'), + cfg.BoolOpt('zone_activate', + default=True, + help='overridden zoning activation state'), + cfg.StrOpt('zone_name_prefix', + default=None, + help='overridden zone name prefix'), + cfg.StrOpt('principal_switch_wwn', + default=None, + help='Principal switch WWN of the fabric'), +] + +CONF = cfg.CONF +CONF.register_opts(brcd_zone_opts, 'BRCD_FABRIC_EXAMPLE') +LOG = logging.getLogger(__name__) + + +def load_fabric_configurations(fabric_names): + fabric_configs = {} + for fabric_name in fabric_names: + config = Configuration(brcd_zone_opts, fabric_name) + LOG.debug("Loaded FC fabric config %s" % fabric_name) + fabric_configs[fabric_name] = config + + return fabric_configs diff --git a/cinder/zonemanager/drivers/brocade/brcd_fc_san_lookup_service.py b/cinder/zonemanager/drivers/brocade/brcd_fc_san_lookup_service.py index 211eaf5c6b9..032adb18d98 100644 --- a/cinder/zonemanager/drivers/brocade/brcd_fc_san_lookup_service.py +++ b/cinder/zonemanager/drivers/brocade/brcd_fc_san_lookup_service.py @@ -19,22 +19,17 @@ import paramiko -from oslo.config import cfg - from cinder import exception from cinder.openstack.common import excutils from cinder.openstack.common import log as logging from cinder import utils +from cinder.zonemanager.drivers.brocade import brcd_fabric_opts as fabric_opts import cinder.zonemanager.drivers.brocade.fc_zone_constants as ZoneConstant from cinder.zonemanager.drivers.fc_common import FCCommon LOG = logging.getLogger(__name__) -CONF = cfg.CONF -CONF.import_opt('fc_fabric_names', 'cinder.zonemanager.drivers.fc_common') - - class BrcdFCSanLookupService(FCCommon): def __init__(self, **kwargs): @@ -50,37 +45,14 @@ class BrcdFCSanLookupService(FCCommon): """Configuration specific to SAN context values.""" config = self.configuration - fc_fabric_opts = [] fabric_names = config.fc_fabric_names.split(',') LOG.debug(_('Fabric Names: %s'), fabric_names) # There can be more than one SAN in the network and we need to # get credentials for each for SAN context lookup later. if len(fabric_names) > 0: - for fabric_name in fabric_names: - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_address_' - + fabric_name, - default='', - help='Management IP ' - 'of fabric')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_user_' - + fabric_name, - default='', - help='Fabric user ID')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_password_' - + fabric_name, - default='', - help='Password for user', - secret=True)) - fc_fabric_opts.append(cfg.IntOpt('fc_fabric_port_' - + fabric_name, default=22, - help='Connecting port')) - fc_fabric_opts.append(cfg.StrOpt('principal_switch_wwn_' - + fabric_name, - default=fabric_name, - help='Principal switch WWN ' - 'of the fabric')) - config.append_config_values(fc_fabric_opts) + self.fabric_configs = fabric_opts.load_fabric_configurations( + fabric_names) def get_device_mapping_from_network(self, initiator_wwn_list, @@ -125,17 +97,17 @@ class BrcdFCSanLookupService(FCCommon): get_formatted_wwn(i)) for fabric_name in fabrics: - fabric_ip = self.configuration.safe_get('fc_fabric_address_' - + fabric_name) - fabric_user = self.configuration.safe_get('fc_fabric_user_' - + fabric_name) - fabric_pwd = self.configuration.safe_get('fc_fabric_password_' - + fabric_name) - fabric_port = self.configuration.safe_get( - 'fc_fabric_port_' + fabric_name) - fabric_principal_wwn = self.configuration.safe_get( - 'principal_switch_wwn_' - + fabric_name) + fabric_ip = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_address') + fabric_user = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_user') + fabric_pwd = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_password') + fabric_port = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_port') + fabric_principal_wwn = \ + self.fabric_configs[fabric_name].safe_get( + 'principal_switch_wwn') # Get name server data from fabric and find the targets # logged in diff --git a/cinder/zonemanager/drivers/brocade/brcd_fc_zone_driver.py b/cinder/zonemanager/drivers/brocade/brcd_fc_zone_driver.py index f84020d421d..bda2f1d29ef 100644 --- a/cinder/zonemanager/drivers/brocade/brcd_fc_zone_driver.py +++ b/cinder/zonemanager/drivers/brocade/brcd_fc_zone_driver.py @@ -37,6 +37,7 @@ from cinder.openstack.common import excutils from cinder.openstack.common import importutils from cinder.openstack.common import lockutils from cinder.openstack.common import log as logging +from cinder.zonemanager.drivers.brocade import brcd_fabric_opts as fabric_opts from cinder.zonemanager.drivers.fc_zone_driver import FCZoneDriver LOG = logging.getLogger(__name__) @@ -49,11 +50,7 @@ brcd_opts = [ ] CONF = cfg.CONF -CONF.register_opts(brcd_opts) -CONF.import_opt('zone_activate', 'cinder.zonemanager.drivers.fc_zone_driver') -CONF.import_opt('zone_name_prefix', - 'cinder.zonemanager.drivers.fc_zone_driver') -CONF.import_opt('fc_fabric_names', 'cinder.zonemanager.drivers.fc_common') +CONF.register_opts(brcd_opts, 'fc-zone-manager') class BrcdFCZoneDriver(FCZoneDriver): @@ -100,54 +97,12 @@ class BrcdFCZoneDriver(FCZoneDriver): CONF.register_opts(base_san_opts) self.configuration.append_config_values(base_san_opts) fabric_names = self.configuration.fc_fabric_names.split(',') - fc_fabric_opts = [] + # There can be more than one SAN in the network and we need to # get credentials for each SAN. if fabric_names: - for fabric_name in fabric_names: - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_address_' - + fabric_name, - default='', - help='Management IP' - ' of fabric')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_user_' - + fabric_name, - default='', - help='Fabric user ID')) - fc_fabric_opts.append(cfg.StrOpt('fc_fabric_password_' - + fabric_name, - default='', - help='Password for user', - secret=True)) - fc_fabric_opts.append(cfg.IntOpt('fc_fabric_port_' - + fabric_name, - default=22, - help='Connecting port')) - fc_fabric_opts.append(cfg.StrOpt('zoning_policy_' - + fabric_name, - default=self.configuration - .zoning_policy, - help='overridden ' - 'zoning policy')) - fc_fabric_opts.append(cfg.BoolOpt('zone_activate_' - + fabric_name, - default=self - .configuration - .zone_activate, - help='overridden zoning ' - 'activation state')) - fc_fabric_opts.append(cfg.StrOpt('zone_name_prefix_' - + fabric_name, - default=self.configuration - .zone_name_prefix, - help='overridden zone ' - 'name prefix')) - fc_fabric_opts.append(cfg.StrOpt('principal_switch_wwn_' - + fabric_name, - default=fabric_name, - help='Principal switch ' - 'WWN of the fabric')) - self.configuration.append_config_values(fc_fabric_opts) + self.fabric_configs = fabric_opts.load_fabric_configurations( + fabric_names) def get_formatted_wwn(self, wwn_str): """Utility API that formats WWN to insert ':'.""" @@ -174,17 +129,13 @@ class BrcdFCZoneDriver(FCZoneDriver): LOG.debug(_("Add connection for Fabric:%s"), fabric) LOG.info(_("BrcdFCZoneDriver - Add connection " "for I-T map: %s"), initiator_target_map) - fabric_ip = self.configuration.safe_get( - 'fc_fabric_address_' + fabric) - fabric_user = self.configuration.safe_get( - 'fc_fabric_user_' + fabric) - fabric_pwd = self.configuration.safe_get( - 'fc_fabric_password_' + fabric) - fabric_port = self.configuration.safe_get( - 'fc_fabric_port_' + fabric) + fabric_ip = self.fabric_configs[fabric].safe_get('fc_fabric_address') + fabric_user = self.fabric_configs[fabric].safe_get('fc_fabric_user') + fabric_pwd = self.fabric_configs[fabric].safe_get('fc_fabric_password') + fabric_port = self.fabric_configs[fabric].safe_get('fc_fabric_port') zoning_policy = self.configuration.zoning_policy - zoning_policy_fab = self.configuration.safe_get( - 'zoning_policy_' + fabric) + zoning_policy_fab = self.fabric_configs[fabric].safe_get( + 'zoning_policy') if zoning_policy_fab: zoning_policy = zoning_policy_fab @@ -289,17 +240,13 @@ class BrcdFCZoneDriver(FCZoneDriver): LOG.debug(_("Delete connection for fabric:%s"), fabric) LOG.info(_("BrcdFCZoneDriver - Delete connection for I-T map: %s"), initiator_target_map) - fabric_ip = self.configuration.safe_get( - 'fc_fabric_address_' + fabric) - fabric_user = self.configuration.safe_get( - 'fc_fabric_user_' + fabric) - fabric_pwd = self.configuration.safe_get( - 'fc_fabric_password_' + fabric) - fabric_port = self.configuration.safe_get( - 'fc_fabric_port_' + fabric) + fabric_ip = self.fabric_configs[fabric].safe_get('fc_fabric_address') + fabric_user = self.fabric_configs[fabric].safe_get('fc_fabric_user') + fabric_pwd = self.fabric_configs[fabric].safe_get('fc_fabric_password') + fabric_port = self.fabric_configs[fabric].safe_get('fc_fabric_port') zoning_policy = self.configuration.zoning_policy - zoning_policy_fab = self.configuration.safe_get( - 'zoning_policy_' + fabric) + zoning_policy_fab = self.fabric_configs[fabric].safe_get( + 'zoning_policy') if zoning_policy_fab: zoning_policy = zoning_policy_fab @@ -436,14 +383,14 @@ class BrcdFCZoneDriver(FCZoneDriver): LOG.debug(_("Formatted Target wwn List:" " %s"), formatted_target_list) for fabric_name in fabrics: - fabric_ip = self.configuration.safe_get( - 'fc_fabric_address_' + fabric_name) - fabric_user = self.configuration.safe_get( - 'fc_fabric_user_' + fabric_name) - fabric_pwd = self.configuration.safe_get( - 'fc_fabric_password_' + fabric_name) - fabric_port = self.configuration.safe_get( - 'fc_fabric_port_' + fabric_name) + fabric_ip = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_address') + fabric_user = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_user') + fabric_pwd = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_password') + fabric_port = self.fabric_configs[fabric_name].safe_get( + 'fc_fabric_port') conn = None try: conn = importutils.import_object( diff --git a/cinder/zonemanager/drivers/fc_common.py b/cinder/zonemanager/drivers/fc_common.py index ce08c20c53d..984cdb63ff0 100644 --- a/cinder/zonemanager/drivers/fc_common.py +++ b/cinder/zonemanager/drivers/fc_common.py @@ -17,20 +17,6 @@ # -from oslo.config import cfg - -san_context_opts = [ - cfg.StrOpt('fc_fabric_names', - default=None, - help='Comma separated list of fibre channel fabric names.' - ' This list of names is used to retrieve other SAN credentials' - ' for connecting to each SAN fabric'), -] - -CONF = cfg.CONF -CONF.register_opts(san_context_opts) - - class FCCommon(object): """Common interface for FC operations.""" diff --git a/cinder/zonemanager/drivers/fc_zone_driver.py b/cinder/zonemanager/drivers/fc_zone_driver.py index 3f5e45d7dc6..9254bd212af 100644 --- a/cinder/zonemanager/drivers/fc_zone_driver.py +++ b/cinder/zonemanager/drivers/fc_zone_driver.py @@ -30,25 +30,11 @@ interfaces. """ -from oslo.config import cfg - from cinder.openstack.common import log as logging from cinder.zonemanager.drivers.fc_common import FCCommon LOG = logging.getLogger(__name__) -fc_zone_opts = [ - cfg.BoolOpt('zone_activate', - default=True, - help="Indicates whether zone should be activated or not"), - cfg.StrOpt('zone_name_prefix', - default="openstack", - help="A prefix to be used when naming zone"), -] - -CONF = cfg.CONF -CONF.register_opts(fc_zone_opts) - class FCZoneDriver(FCCommon): """Interface to manage Connection control during attach/detach.""" diff --git a/cinder/zonemanager/fc_san_lookup_service.py b/cinder/zonemanager/fc_san_lookup_service.py index 27528f7dd82..147b76bd2d0 100644 --- a/cinder/zonemanager/fc_san_lookup_service.py +++ b/cinder/zonemanager/fc_san_lookup_service.py @@ -23,23 +23,14 @@ defined in this class. """ -from oslo.config import cfg - from cinder import exception from cinder.openstack.common import importutils from cinder.openstack.common import log as logging +from cinder.volume import configuration as config +from cinder.zonemanager import fc_zone_manager LOG = logging.getLogger(__name__) -lookup_service_opts = [ - cfg.StrOpt('fc_san_lookup_service', - default='cinder.zonemanager.drivers.brocade' - '.brcd_fc_san_lookup_service.BrcdFCSanLookupService', - help='FC San Lookup Service'), -] - -CONF = cfg.CONF -CONF.register_opts(lookup_service_opts) class FCSanLookupService(object): @@ -53,8 +44,9 @@ class FCSanLookupService(object): def __init__(self, **kwargs): self.configuration = kwargs.get('configuration', None) - if self.configuration: - self.configuration.append_config_values(lookup_service_opts) + + opts = fc_zone_manager.zone_manager_opts + self.configuration = config.Configuration(opts, 'fc-zone-manager') def get_device_mapping_from_network(self, initiator_list, target_list): """Get device mapping from FC network. diff --git a/cinder/zonemanager/fc_zone_manager.py b/cinder/zonemanager/fc_zone_manager.py index 2fc4f8f1c25..dd938524709 100644 --- a/cinder/zonemanager/fc_zone_manager.py +++ b/cinder/zonemanager/fc_zone_manager.py @@ -37,6 +37,7 @@ from oslo.config import cfg from cinder import exception from cinder.openstack.common import importutils from cinder.openstack.common import log as logging +from cinder.volume import configuration as config LOG = logging.getLogger(__name__) @@ -48,14 +49,24 @@ zone_manager_opts = [ cfg.StrOpt('zoning_policy', default='initiator-target', help='Zoning policy configured by user'), + cfg.StrOpt('fc_fabric_names', + default=None, + help='Comma separated list of fibre channel fabric names.' + ' This list of names is used to retrieve other SAN credentials' + ' for connecting to each SAN fabric'), + cfg.StrOpt('fc_san_lookup_service', + default='cinder.zonemanager.drivers.brocade' + '.brcd_fc_san_lookup_service.BrcdFCSanLookupService', + help='FC San Lookup Service'), ] CONF = cfg.CONF -CONF.register_opts(zone_manager_opts) +CONF.register_opts(zone_manager_opts, 'fc-zone-manager') class ZoneManager: """Manages Connection control during attach/detach.""" + driver = None fabric_names = [] @@ -69,10 +80,11 @@ class ZoneManager: zone_driver = self.configuration.zone_driver LOG.debug(_("Zone Driver from config: {%s}"), zone_driver) + zm_config = config.Configuration(zone_manager_opts, 'fc-zone-manager') # Initialize vendor specific implementation of FCZoneDriver self.driver = importutils.import_object( zone_driver, - configuration=self.configuration) + configuration=zm_config) def get_zoning_state_ref_count(self, initiator_wwn, target_wwn): """Zone management state check. @@ -103,7 +115,7 @@ class ZoneManager: LOG.debug(_("Target List :%s"), {initiator: target_list}) # get SAN context for the target list - fabric_map = self.driver.get_san_context(target_list) + fabric_map = self.get_san_context(target_list) LOG.debug(_("Fabric Map after context lookup:%s"), fabric_map) # iterate over each SAN and apply connection control for fabric in fabric_map.keys(): @@ -147,7 +159,7 @@ class ZoneManager: {initiator: target_list}) # get SAN context for the target list - fabric_map = self.driver.get_san_context(target_list) + fabric_map = self.get_san_context(target_list) LOG.debug(_("Delete connection Fabric Map from SAN " "context: %s"), fabric_map) @@ -175,6 +187,16 @@ class ZoneManager: LOG.error(msg) raise exception.ZoneManagerException(reason=msg) + def get_san_context(self, target_wwn_list): + """SAN lookup for end devices. + + Look up each SAN configured and return a map of SAN (fabric IP) + to list of target WWNs visible to the fabric. + """ + fabric_map = self.driver.get_san_context(target_wwn_list) + LOG.debug(_("Got SAN context:%s"), fabric_map) + return fabric_map + def get_valid_initiator_target_map(self, initiator_target_map, add_control): """Reference count check for end devices. diff --git a/etc/cinder/cinder.conf.sample b/etc/cinder/cinder.conf.sample index 11c64aac42c..b5eef2668ed 100644 --- a/etc/cinder/cinder.conf.sample +++ b/etc/cinder/cinder.conf.sample @@ -1782,6 +1782,8 @@ #zoning_mode=none +[fc-zone-manager] + # # Options defined in cinder.zonemanager.drivers.brocade.brcd_fc_zone_driver # @@ -1790,36 +1792,6 @@ #brcd_sb_connector=cinder.zonemanager.drivers.brocade.brcd_fc_zone_client_cli.BrcdFCZoneClientCLI -# -# Options defined in cinder.zonemanager.drivers.fc_common -# - -# Comma separated list of fibre channel fabric names. This -# list of names is used to retrieve other SAN credentials for -# connecting to each SAN fabric (string value) -#fc_fabric_names= - - -# -# Options defined in cinder.zonemanager.drivers.fc_zone_driver -# - -# Indicates whether zone should be activated or not (boolean -# value) -#zone_activate=true - -# A prefix to be used when naming zone (string value) -#zone_name_prefix=openstack - - -# -# Options defined in cinder.zonemanager.fc_san_lookup_service -# - -# FC San Lookup Service (string value) -#fc_san_lookup_service=cinder.zonemanager.drivers.brocade.brcd_fc_san_lookup_service.BrcdFCSanLookupService - - # # Options defined in cinder.zonemanager.fc_zone_manager # @@ -1831,6 +1803,14 @@ # Zoning policy configured by user (string value) #zoning_policy=initiator-target +# Comma separated list of fibre channel fabric names. This +# list of names is used to retrieve other SAN credentials for +# connecting to each SAN fabric (string value) +#fc_fabric_names= + +# FC San Lookup Service (string value) +#fc_san_lookup_service=cinder.zonemanager.drivers.brocade.brcd_fc_san_lookup_service.BrcdFCSanLookupService + [ssl] @@ -2094,6 +2074,37 @@ #enforce_token_bind=permissive +[BRCD_FABRIC_EXAMPLE] + +# +# Options defined in cinder.zonemanager.drivers.brocade.brcd_fabric_opts +# + +# Management IP of fabric (string value) +#fc_fabric_address= + +# Fabric user ID (string value) +#fc_fabric_user= + +# Password for user (string value) +#fc_fabric_password= + +# Connecting port (integer value) +#fc_fabric_port=22 + +# overridden zoning policy (string value) +#zoning_policy=initiator-target + +# overridden zoning activation state (boolean value) +#zone_activate=true + +# overridden zone name prefix (string value) +#zone_name_prefix= + +# Principal switch WWN of the fabric (string value) +#principal_switch_wwn= + + [matchmaker_ring] #