From 85239cc81440d9e5a4aee3c0961c96a4197ad939 Mon Sep 17 00:00:00 2001 From: "Walter A. Boring IV" Date: Mon, 24 Feb 2014 12:10:52 -0800 Subject: [PATCH] Update FibreChannel Zone Manager config This patch changes the way the config options are layed out in the cinder.conf to follow the standards for grouping settings together. Instead of using dynamic config names to group settings together by fabric name, we look for fabric groups based upon the fc_fabric_names. We also create a new fc-zone-manager group for all of the global fczm settings. Change-Id: I91c8a05adec2fb12f664ca0df6007465c1a460e0 Closes-Bug: #1284338 DocImpact --- cinder/tests/zonemanager/__init__.py | 14 +++ .../test_brcd_fc_san_lookup_service.py | 38 ++++--- .../test_brcd_fc_zone_client_cli.py | 0 .../test_brcd_fc_zone_driver.py | 9 +- .../test_brcd_lookup_service.py | 3 +- .../{ => zonemanager}/test_fc_zone_manager.py | 0 .../test_volume_manager_fc.py | 57 ++++++---- .../drivers/brocade/brcd_fabric_opts.py | 63 +++++++++++ .../brocade/brcd_fc_san_lookup_service.py | 56 +++------- .../drivers/brocade/brcd_fc_zone_driver.py | 103 +++++------------- cinder/zonemanager/drivers/fc_common.py | 14 --- cinder/zonemanager/drivers/fc_zone_driver.py | 14 --- cinder/zonemanager/fc_san_lookup_service.py | 18 +-- cinder/zonemanager/fc_zone_manager.py | 30 ++++- etc/cinder/cinder.conf.sample | 71 +++++++----- 15 files changed, 249 insertions(+), 241 deletions(-) create mode 100644 cinder/tests/zonemanager/__init__.py rename cinder/tests/{ => zonemanager}/test_brcd_fc_san_lookup_service.py (79%) mode change 100755 => 100644 rename cinder/tests/{ => zonemanager}/test_brcd_fc_zone_client_cli.py (100%) rename cinder/tests/{ => zonemanager}/test_brcd_fc_zone_driver.py (96%) rename cinder/tests/{ => zonemanager}/test_brcd_lookup_service.py (97%) rename cinder/tests/{ => zonemanager}/test_fc_zone_manager.py (100%) rename cinder/tests/{ => zonemanager}/test_volume_manager_fc.py (73%) create mode 100644 cinder/zonemanager/drivers/brocade/brcd_fabric_opts.py 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] #