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 <alau2@cisco.com>
Closes-Bug: #1496270
Change-Id: I752fb19c3d12431df01a77492d60817bc8385e3a
This commit is contained in:
chenying 2016-01-22 07:17:54 +08:00
parent 0ed3a80d6c
commit 7ca7b2597b
2 changed files with 106 additions and 73 deletions

View File

@ -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):

View File

@ -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,