From 7ca7b2597b2e5cb1d4e5ffb8cd79ca117c645d7d Mon Sep 17 00:00:00 2001 From: chenying Date: Fri, 22 Jan 2016 07:17:54 +0800 Subject: [PATCH] Cisco: can't add new zone when no zone is created before Can't add new zone on Cisco switch when there is no zone exists on it. This patch fixes this bug. Co-Authored-By: Al Lau Closes-Bug: #1496270 Change-Id: I752fb19c3d12431df01a77492d60817bc8385e3a --- .../zonemanager/test_cisco_fc_zone_driver.py | 39 ++++- .../drivers/cisco/cisco_fc_zone_driver.py | 140 +++++++++--------- 2 files changed, 106 insertions(+), 73 deletions(-) diff --git a/cinder/tests/unit/zonemanager/test_cisco_fc_zone_driver.py b/cinder/tests/unit/zonemanager/test_cisco_fc_zone_driver.py index 06d06d9279f..5e458a062ff 100644 --- a/cinder/tests/unit/zonemanager/test_cisco_fc_zone_driver.py +++ b/cinder/tests/unit/zonemanager/test_cisco_fc_zone_driver.py @@ -17,6 +17,7 @@ """Unit tests for Cisco FC zone driver.""" +import mock from oslo_concurrency import processutils from oslo_config import cfg from oslo_utils import importutils @@ -24,6 +25,7 @@ from oslo_utils import importutils from cinder import exception from cinder import test from cinder.volume import configuration as conf +from cinder.zonemanager.drivers.cisco import cisco_fc_zone_driver as driver _active_cfg_before_add = {} _active_cfg_before_delete = { @@ -32,6 +34,12 @@ _active_cfg_before_delete = { ['10:00:8c:7c:ff:52:3b:01', '20:24:00:02:ac:00:0a:50'])}, 'active_zone_config': 'cfg1'} +_active_cfg_default = { + 'zones': { + 'openstack10008c7cff523b0120240002ac000b90': ( + ['10:00:8c:7c:ff:52:3b:01', + '20:24:00:02:ac:00:0a:50'])}, + 'active_zone_config': 'cfg1'} _activate = True _zone_name = 'openstack10008c7cff523b0120240002ac000a50' _target_ns_map = {'100000051e55a100': ['20240002ac000a50']} @@ -127,6 +135,34 @@ class TestCiscoFcZoneDriver(CiscoFcZoneDriverBaseTest, test.TestCase): 'CISCO_FAB_1', _initiator_target_map) self.assertNotIn(_zone_name, GlobalVars._zone_state) + @mock.patch.object(driver.CiscoFCZoneDriver, 'get_zoning_status') + @mock.patch.object(driver.CiscoFCZoneDriver, 'get_active_zone_set') + def test_add_connection(self, get_active_zone_set_mock, + get_zoning_status_mock): + """Test normal flows.""" + GlobalVars._is_normal_test = True + GlobalVars._zone_state = [] + self.setup_driver(self.setup_config(True, 1)) + get_zoning_status_mock.return_value = {'mode': 'basis', + 'session': 'none'} + get_active_zone_set_mock.return_value = _active_cfg_default + self.driver.add_connection('CISCO_FAB_1', _initiator_target_map) + self.assertTrue(_zone_name in GlobalVars._zone_state) + + @mock.patch.object(driver.CiscoFCZoneDriver, 'get_zoning_status') + @mock.patch.object(driver.CiscoFCZoneDriver, 'get_active_zone_set') + def test_add_connection_with_no_cfg(self, get_active_zone_set_mock, + get_zoning_status_mock): + """Test normal flows.""" + GlobalVars._is_normal_test = True + GlobalVars._zone_state = [] + self.setup_driver(self.setup_config(True, 1)) + get_zoning_status_mock.return_value = {'mode': 'basis', + 'session': 'none'} + get_active_zone_set_mock.return_value = {} + self.driver.add_connection('CISCO_FAB_1', _initiator_target_map) + self.assertTrue(_zone_name in GlobalVars._zone_state) + def test_add_connection_for_invalid_fabric(self): """Test abnormal flows.""" GlobalVars._is_normal_test = True @@ -157,7 +193,8 @@ class FakeCiscoFCZoneClientCLI(object): def get_active_zone_set(self): return GlobalVars._active_cfg - def add_zones(self, zones, isActivate): + def add_zones(self, zones, activate, fabric_vsan, active_zone_set, + zone_status): GlobalVars._zone_state.extend(zones.keys()) def delete_zones(self, zone_names, isActivate): diff --git a/cinder/zonemanager/drivers/cisco/cisco_fc_zone_driver.py b/cinder/zonemanager/drivers/cisco/cisco_fc_zone_driver.py index a52fd5a6015..56ddaa1b526 100644 --- a/cinder/zonemanager/drivers/cisco/cisco_fc_zone_driver.py +++ b/cinder/zonemanager/drivers/cisco/cisco_fc_zone_driver.py @@ -163,43 +163,18 @@ class CiscoFCZoneDriver(fc_zone_driver.FCZoneDriver): zone_names = [] if cfgmap_from_fabric.get('zones'): zone_names = cfgmap_from_fabric['zones'].keys() - # based on zoning policy, create zone member list and - # push changes to fabric. - for initiator_key in initiator_target_map.keys(): - zone_map = {} - initiator = initiator_key.lower() - t_list = initiator_target_map[initiator_key] - if zoning_policy == 'initiator-target': - for t in t_list: - target = t.lower() - zone_members = [ - zm_utils.get_formatted_wwn(initiator), - zm_utils.get_formatted_wwn(target)] - zone_name = ( - driver_utils.get_friendly_zone_name( - zoning_policy, - initiator, - target, - host_name, - storage_system, - self.configuration.cisco_zone_name_prefix, - SUPPORTED_CHARS)) - if (len(cfgmap_from_fabric) == 0 or ( - zone_name not in zone_names)): - zone_map[zone_name] = zone_members - else: - # This is I-T zoning, skip if zone exists. - LOG.info(_LI("Zone exists in I-T mode. " - "Skipping zone creation %s"), - zone_name) - elif zoning_policy == 'initiator': + # based on zoning policy, create zone member list and + # push changes to fabric. + for initiator_key in initiator_target_map.keys(): + zone_map = {} + initiator = initiator_key.lower() + t_list = initiator_target_map[initiator_key] + if zoning_policy == 'initiator-target': + for t in t_list: + target = t.lower() zone_members = [ - zm_utils.get_formatted_wwn(initiator)] - for t in t_list: - target = t.lower() - zone_members.append( - zm_utils.get_formatted_wwn(target)) - + zm_utils.get_formatted_wwn(initiator), + zm_utils.get_formatted_wwn(target)] zone_name = ( driver_utils.get_friendly_zone_name( zoning_policy, @@ -209,45 +184,66 @@ class CiscoFCZoneDriver(fc_zone_driver.FCZoneDriver): storage_system, self.configuration.cisco_zone_name_prefix, SUPPORTED_CHARS)) + if (len(cfgmap_from_fabric) == 0 or ( + zone_name not in zone_names)): + zone_map[zone_name] = zone_members + else: + # This is I-T zoning, skip if zone exists. + LOG.info(_LI("Zone exists in I-T mode. " + "Skipping zone creation %s"), + zone_name) + elif zoning_policy == 'initiator': + zone_members = [ + zm_utils.get_formatted_wwn(initiator)] + for t in t_list: + target = t.lower() + zone_members.append( + zm_utils.get_formatted_wwn(target)) + zone_name = ( + driver_utils.get_friendly_zone_name( + zoning_policy, + initiator, + target, + host_name, + storage_system, + self.configuration.cisco_zone_name_prefix, + SUPPORTED_CHARS)) - if len(zone_names) > 0 and (zone_name in zone_names): - zone_members = zone_members + filter( - lambda x: x not in zone_members, - cfgmap_from_fabric['zones'][zone_name]) - zone_map[zone_name] = zone_members - else: - msg = _("Zoning Policy: %s, not" - " recognized") % zoning_policy - LOG.error(msg) - raise exception.FCZoneDriverException(msg) + if len(zone_names) > 0 and (zone_name in zone_names): + zone_members = zone_members + filter( + lambda x: x not in zone_members, + cfgmap_from_fabric['zones'][zone_name]) + zone_map[zone_name] = zone_members + else: + msg = _("Zoning Policy: %s, not" + " recognized") % zoning_policy + LOG.error(msg) + raise exception.FCZoneDriverException(msg) - LOG.info(_LI("Zone map to add: %s"), zone_map) - - if len(zone_map) > 0: - conn = None - try: - conn = importutils.import_object( - self.configuration.cisco_sb_connector, - ipaddress=fabric_ip, - username=fabric_user, - password=fabric_pwd, - port=fabric_port, - vsan=zoning_vsan) - conn.add_zones( - zone_map, self.configuration.cisco_zone_activate, - zoning_vsan, cfgmap_from_fabric, - statusmap_from_fabric) - conn.cleanup() - except exception.CiscoZoningCliException as cisco_ex: - msg = _("Exception: %s") % six.text_type(cisco_ex) - raise exception.FCZoneDriverException(msg) - except Exception: - msg = _("Failed to add zoning configuration.") - LOG.exception(msg) - raise exception.FCZoneDriverException(msg) + if len(zone_map) > 0: + LOG.debug("Zone map to add: %s", zone_map) + conn = None + try: + conn = importutils.import_object( + self.configuration.cisco_sb_connector, + ipaddress=fabric_ip, + username=fabric_user, + password=fabric_pwd, + port=fabric_port, + vsan=zoning_vsan) + conn.add_zones( + zone_map, self.configuration.cisco_zone_activate, + zoning_vsan, cfgmap_from_fabric, + statusmap_from_fabric) + conn.cleanup() + except exception.CiscoZoningCliException as cisco_ex: + msg = _("Exception: %s") % six.text_type(cisco_ex) + raise exception.FCZoneDriverException(msg) + except Exception: + msg = _("Failed to add zoning configuration.") + LOG.exception(msg) + raise exception.FCZoneDriverException(msg) LOG.debug("Zones added successfully: %s", zone_map) - else: - LOG.debug("Zoning session exists VSAN: %s", zoning_vsan) @lockutils.synchronized('cisco', 'fcfabric-', True) def delete_connection(self, fabric, initiator_target_map, host_name=None,