apply_zone_change_mock,
cfg_save_mock):
get_active_zs_mock.return_value = active_zoneset
- self.add_zones(new_zones, False)
+ self.add_zones(new_zones, False, None)
get_active_zs_mock.assert_called_once()
apply_zone_change_mock.assert_called_twice()
cfg_save_mock.assert_called_once()
@mock.patch.object(BrcdFCZoneClientCLI, 'get_active_zone_set')
@mock.patch.object(BrcdFCZoneClientCLI, 'apply_zone_change')
- @mock.patch.object(BrcdFCZoneClientCLI, '_cfg_save')
@mock.patch.object(BrcdFCZoneClientCLI, 'activate_zoneset')
def test_add_zones_new_zone_activate(self, get_active_zs_mock,
apply_zone_change_mock,
- cfg_save_mock,
activate_zoneset_mock):
get_active_zs_mock.return_value = active_zoneset
- self.add_zones(new_zone, True)
- get_active_zs_mock.assert_called_once()
+ self.add_zones(new_zone, True, active_zoneset)
apply_zone_change_mock.assert_called_once()
- cfg_save_mock.assert_called_once()
activate_zoneset_mock.assert_called_once()
@mock.patch.object(BrcdFCZoneClientCLI, '_ssh_execute')
return_value = self.deactivate_zoneset()
self.assertTrue(return_value)
- @mock.patch.object(BrcdFCZoneClientCLI, 'get_active_zone_set')
@mock.patch.object(BrcdFCZoneClientCLI, 'apply_zone_change')
@mock.patch.object(BrcdFCZoneClientCLI, '_cfg_save')
- def test_delete_zones_activate_false(self, get_active_zs_mock,
- apply_zone_change_mock,
+ def test_delete_zones_activate_false(self, apply_zone_change_mock,
cfg_save_mock):
- get_active_zs_mock.return_value = active_zoneset_multiple_zones
with mock.patch.object(self, '_zone_delete') \
as zone_delete_mock:
- self.delete_zones(zone_names_to_delete, False)
- get_active_zs_mock.assert_called_once()
+ self.delete_zones(zone_names_to_delete, False,
+ active_zoneset_multiple_zones)
apply_zone_change_mock.assert_called_once()
zone_delete_mock.assert_called_once_with(zone_names_to_delete)
cfg_save_mock.assert_called_once()
- @patch.object(BrcdFCZoneClientCLI, 'get_active_zone_set')
@patch.object(BrcdFCZoneClientCLI, 'apply_zone_change')
- @patch.object(BrcdFCZoneClientCLI, '_cfg_save')
@patch.object(BrcdFCZoneClientCLI, 'activate_zoneset')
- def test_delete_zones_activate_true(self, get_active_zs_mock,
- apply_zone_change_mock,
- cfg_save_mock,
+ def test_delete_zones_activate_true(self, apply_zone_change_mock,
activate_zs_mock):
- get_active_zs_mock.return_value = active_zoneset_multiple_zones
with mock.patch.object(self, '_zone_delete') \
as zone_delete_mock:
- self.delete_zones(zone_names_to_delete, True)
- get_active_zs_mock.assert_called_once()
+ self.delete_zones(zone_names_to_delete, True,
+ active_zoneset_multiple_zones)
apply_zone_change_mock.assert_called_once()
zone_delete_mock.assert_called_once_with(zone_names_to_delete)
- cfg_save_mock.assert_called_once()
activate_zs_mock.assert_called_once()
@patch.object(BrcdFCZoneClientCLI, '_get_switch_info')
def test_get_nameserver_info(self, get_switch_info_mock):
ns_info_list = []
- ns_info_list_expected = ['20:1a:00:05:1e:e8:e3:29',
- '20:1a:00:05:1e:e8:e3:29']
+ ns_info_list_expected = ['20:1a:00:05:1e:e8:e3:29']
get_switch_info_mock.return_value = (switch_data)
ns_info_list = self.get_nameserver_info()
self.assertEqual(ns_info_list, ns_info_list_expected)
"""Unit tests for Brocade fc zone driver."""
+import mock
import paramiko
from oslo.config import cfg
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_zone_driver \
+ import BrcdFCZoneDriver
LOG = logging.getLogger(__name__)
'cinder.zonemanager.drivers.brocade.brcd_fc_zone_driver'
'.BrcdFCZoneDriver', configuration=config)
- def fake_get_active_zone_set(self, fabric_ip, fabric_user, fabric_pwd):
+ def fake__get_active_zone_set(self, brcd_sb_connector, fabric_ip):
return GlobalVars._active_cfg
def fake_get_san_context(self, target_wwn_list):
fabric_map = {}
return fabric_map
- def test_add_connection(self):
+ @mock.patch.object(BrcdFCZoneDriver, '_get_active_zone_set')
+ def test_add_connection(self, get_active_zs_mock):
"""Normal flow for i-t mode."""
- GlobalVars._active_cfg = _active_cfg_before_add
GlobalVars._is_normal_test = True
GlobalVars._zone_state = []
- LOG.info(_("In Add GlobalVars._active_cfg:"
- " %s"), GlobalVars._active_cfg)
LOG.info(_("In Add GlobalVars._is_normal_test: "
"%s"), GlobalVars._is_normal_test)
LOG.info(_("In Add GlobalVars._zone_state:"
" %s"), GlobalVars._zone_state)
+ get_active_zs_mock.return_value = _active_cfg_before_add
self.driver.add_connection('BRCD_FAB_1', _initiator_target_map)
self.assertTrue(_zone_name in GlobalVars._zone_state)
- def test_delete_connection(self):
+ @mock.patch.object(BrcdFCZoneDriver, '_get_active_zone_set')
+ def test_delete_connection(self, get_active_zs_mock):
GlobalVars._is_normal_test = True
- GlobalVars._active_cfg = _active_cfg_before_delete
+ get_active_zs_mock.return_value = _active_cfg_before_delete
self.driver.delete_connection(
'BRCD_FAB_1', _initiator_target_map)
self.assertFalse(_zone_name in GlobalVars._zone_state)
- def test_add_connection_for_initiator_mode(self):
+ @mock.patch.object(BrcdFCZoneDriver, '_get_active_zone_set')
+ def test_add_connection_for_initiator_mode(self, get_active_zs_mock):
"""Normal flow for i mode."""
GlobalVars._is_normal_test = True
- GlobalVars._active_cfg = _active_cfg_before_add
+ get_active_zs_mock.return_value = _active_cfg_before_add
self.setup_driver(self.setup_config(True, 2))
self.driver.add_connection('BRCD_FAB_1', _initiator_target_map)
self.assertTrue(_zone_name in GlobalVars._zone_state)
- def test_delete_connection_for_initiator_mode(self):
+ @mock.patch.object(BrcdFCZoneDriver, '_get_active_zone_set')
+ def test_delete_connection_for_initiator_mode(self, get_active_zs_mock):
GlobalVars._is_normal_test = True
- GlobalVars._active_cfg = _active_cfg_before_delete
+ get_active_zs_mock.return_value = _active_cfg_before_delete
self.setup_driver(self.setup_config(True, 2))
self.driver.delete_connection(
'BRCD_FAB_1', _initiator_target_map)
def __init__(self, ipaddress, username, password, port):
LOG.info(_("User: %s"), username)
LOG.info(_("_zone_state: %s"), GlobalVars._zone_state)
+ self.firmware_supported = True
if not GlobalVars._is_normal_test:
raise paramiko.SSHException("Unable to connect to fabric")
LOG.debug("Inside get_active_zone_set %s", GlobalVars._active_cfg)
return GlobalVars._active_cfg
- def add_zones(self, zones, isActivate):
+ def add_zones(self, zones, isActivate, active_zone_set):
GlobalVars._zone_state.extend(zones.keys())
- def delete_zones(self, zone_names, isActivate):
+ def delete_zones(self, zone_names, isActivate, active_zone_set):
zone_list = zone_names.split(';')
GlobalVars._zone_state = [
x for x in GlobalVars._zone_state if x not in zone_list]
fake_build_driver)
self.zm = fc_zone_manager.ZoneManager(configuration=config)
+ self.configuration = conf.Configuration(None)
+ self.configuration.fc_fabric_names = fabric_name
+ self.driver = Mock(FCZoneDriver)
def __init__(self, *args, **kwargs):
test.TestCase.__init__(self, *args, **kwargs)
switch_data = None
return zone_set
- def add_zones(self, zones, activate):
+ def add_zones(self, zones, activate, active_zone_set=None):
"""Add zone configuration.
This method will add the zone configuration passed by user.
['50:06:0b:00:00:c2:66:04', '20:19:00:05:1e:e8:e3:29']
}
activate - True/False
+ active_zone_set - active zone set dict retrieved from
+ get_active_zone_set method
"""
LOG.debug("Add Zones - Zones passed: %s", zones)
cfg_name = None
iterator_count = 0
zone_with_sep = ''
- active_zone_set = self.get_active_zone_set()
- LOG.debug("Active zone set:%s", active_zone_set)
+ if not active_zone_set:
+ active_zone_set = self.get_active_zone_set()
+ LOG.debug("Active zone set:%s", active_zone_set)
zone_list = active_zone_set[ZoneConstant.CFG_ZONES]
LOG.debug("zone list:%s", zone_list)
for zone in zones.keys():
# if zone exists, its an update. Delete & insert
# TODO(skolathur): This can be optimized to an update call later
- LOG.debug("Update call")
if (zone in zone_list):
try:
- self.delete_zones(zone, activate)
+ self.delete_zones(zone, activate, active_zone_set)
except exception.BrocadeZoningCliException:
with excutils.save_and_reraise_exception():
LOG.error(_("Deleting zone failed %s"), zone)
% {'zoneset': cfg_name, 'zones': zone_with_sep}
LOG.debug("New zone %s", cmd)
self.apply_zone_change(cmd.split())
- self._cfg_save()
if activate:
self.activate_zoneset(cfg_name)
+ else:
+ self._cfg_save()
except Exception as e:
self._cfg_trans_abort()
msg = _("Creating and activating zone set failed: "
"""Method to deActivate the zone config."""
return self._ssh_execute([ZoneConstant.DEACTIVATE_ZONESET], True, 1)
- def delete_zones(self, zone_names, activate):
+ def delete_zones(self, zone_names, activate, active_zone_set=None):
"""Delete zones from fabric.
Method to delete the active zone config zones
params zone_names: zoneNames separated by semicolon
params activate: True/False
+ params active_zone_set: the active zone set dict retrieved
+ from get_active_zone_set method
"""
active_zoneset_name = None
- active_zone_set = None
zone_list = []
- active_zone_set = self.get_active_zone_set()
+ if not active_zone_set:
+ active_zone_set = self.get_active_zone_set()
active_zoneset_name = active_zone_set[
ZoneConstant.ACTIVE_ZONE_CONFIG]
zone_list = active_zone_set[ZoneConstant.CFG_ZONES]
self.deactivate_zoneset()
cmd = 'cfgdelete "%(active_zoneset_name)s"' \
% {'active_zoneset_name': active_zoneset_name}
- # Active zoneset is being deleted, hence reset is_active
+ # Active zoneset is being deleted, hence reset activate flag
activate = False
else:
cmd = 'cfgremove "%(active_zoneset_name)s", "%(zone_names)s"' \
self.apply_zone_change(cmd.split())
for zone in zones:
self._zone_delete(zone)
- self._cfg_save()
if activate:
self.activate_zoneset(active_zoneset_name)
+ else:
+ self._cfg_save()
except Exception as e:
msg = _("Deleting zones failed: (command=%(cmd)s error=%(err)s)."
) % {'cmd': cmd, 'err': e}
cli_output = None
return_list = []
try:
- cli_output = self._get_switch_info([ZoneConstant.NS_SHOW])
+ cmd = '%(nsshow)s;%(nscamshow)s' % {
+ 'nsshow': ZoneConstant.NS_SHOW,
+ 'nscamshow': ZoneConstant.NS_CAM_SHOW}
+ cli_output = self._get_switch_info([cmd])
except exception.BrocadeZoningCliException:
with excutils.save_and_reraise_exception():
LOG.error(_("Failed collecting nsshow "
"info for fabric %s"), self.switch_ip)
if (cli_output):
return_list = self._parse_ns_output(cli_output)
- try:
- cli_output = self._get_switch_info([ZoneConstant.NS_CAM_SHOW])
- except exception.BrocadeZoningCliException:
- with excutils.save_and_reraise_exception():
- LOG.error(_("Failed collecting nscamshow "
- "info for fabric %s"), self.switch_ip)
- if (cli_output):
- return_list.extend(self._parse_ns_output(cli_output))
cli_output = None
return return_list
channel.close()
except Exception as e:
LOG.exception(e)
- LOG.debug("_execute_cmd: stdout to return:%s" % stdout)
LOG.debug("_execute_cmd: stderr to return:%s" % stderr)
return (stdout, stderr)
Version history:
1.0 - Initial Brocade FC zone driver
+ 1.1 - Implements performance enhancements
"""
- VERSION = "1.0"
+ VERSION = "1.1"
def __init__(self, **kwargs):
super(BrcdFCZoneDriver, self).__init__(**kwargs)
+ self.sb_conn_map = {}
self.configuration = kwargs.get('configuration', None)
if self.configuration:
self.configuration.append_config_values(brcd_opts)
LOG.debug("Add connection for Fabric:%s", fabric)
LOG.info(_("BrcdFCZoneDriver - Add connection "
"for I-T map: %s"), initiator_target_map)
- 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.fabric_configs[fabric].safe_get(
'zoning_policy')
zoning_policy = zoning_policy_fab
LOG.info(_("Zoning policy for Fabric %s"), zoning_policy)
- cli_client = None
- try:
- cli_client = importutils.import_object(
- self.configuration.brcd_sb_connector,
- ipaddress=fabric_ip,
- username=fabric_user,
- password=fabric_pwd,
- port=fabric_port)
- if not cli_client.is_supported_firmware():
- msg = _("Unsupported firmware on switch %s. Make sure "
- "switch is running firmware v6.4 or higher"
- ) % fabric_ip
- LOG.error(msg)
- raise exception.FCZoneDriverException(msg)
- except exception.BrocadeZoningCliException as brocade_ex:
- raise exception.FCZoneDriverException(brocade_ex)
- except Exception as e:
- LOG.error(e)
- msg = _("Failed to add zoning configuration %s") % e
- raise exception.FCZoneDriverException(msg)
+ cli_client = self._get_cli_client(fabric)
+ cfgmap_from_fabric = self._get_active_zone_set(cli_client)
- cfgmap_from_fabric = self.get_active_zone_set(
- fabric_ip, fabric_user, fabric_pwd, fabric_port)
zone_names = []
if cfgmap_from_fabric.get('zones'):
zone_names = cfgmap_from_fabric['zones'].keys()
if len(zone_map) > 0:
try:
cli_client.add_zones(
- zone_map, self.configuration.zone_activate)
+ zone_map, self.configuration.zone_activate,
+ cfgmap_from_fabric)
cli_client.cleanup()
except exception.BrocadeZoningCliException as brocade_ex:
raise exception.FCZoneDriverException(brocade_ex)
LOG.debug("Delete connection for fabric:%s", fabric)
LOG.info(_("BrcdFCZoneDriver - Delete connection for I-T map: %s"),
initiator_target_map)
- 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.fabric_configs[fabric].safe_get(
'zoning_policy')
zoning_policy = zoning_policy_fab
LOG.info(_("Zoning policy for fabric %s"), zoning_policy)
- conn = None
- try:
- conn = importutils.import_object(
- self.configuration.brcd_sb_connector,
- ipaddress=fabric_ip,
- username=fabric_user,
- password=fabric_pwd,
- port=fabric_port)
- if not conn.is_supported_firmware():
- msg = _("Unsupported firmware on switch %s. Make sure "
- "switch is running firmware v6.4 or higher"
- ) % fabric_ip
- LOG.error(msg)
- raise exception.FCZoneDriverException(msg)
- except exception.BrocadeZoningCliException as brocade_ex:
- raise exception.FCZoneDriverException(brocade_ex)
- except Exception as e:
- LOG.error(e)
- msg = _("Failed to delete zoning configuration %s") % e
- raise exception.FCZoneDriverException(msg)
+ conn = self._get_cli_client(fabric)
+ cfgmap_from_fabric = self._get_active_zone_set(conn)
- cfgmap_from_fabric = self.get_active_zone_set(
- fabric_ip, fabric_user, fabric_pwd, fabric_port)
zone_names = []
if cfgmap_from_fabric.get('zones'):
zone_names = cfgmap_from_fabric['zones'].keys()
LOG.debug("Zone name to del: %s", zone_name)
if len(zone_names) > 0 and (zone_name in zone_names):
# delete zone.
- LOG.debug(("Added zone to delete to "
- "list: %s"), zone_name)
+ LOG.debug("Added zone to delete to "
+ "list: %s", zone_name)
zones_to_delete.append(zone_name)
elif zoning_policy == 'initiator':
# Update zone membership.
if zone_map:
conn.add_zones(
- zone_map, self.configuration.zone_activate)
+ zone_map, self.configuration.zone_activate,
+ cfgmap_from_fabric)
# Delete zones ~sk.
if zones_to_delete:
zone_name_string = ''
zone_name_string, ';', zones_to_delete[i])
conn.delete_zones(
- zone_name_string, self.configuration.zone_activate)
+ zone_name_string, self.configuration.zone_activate,
+ cfgmap_from_fabric)
conn.cleanup()
except Exception as e:
LOG.error(e)
LOG.debug("Formatted Target wwn List:"
" %s", formatted_target_list)
for fabric_name in fabrics:
- 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(
- self.configuration.brcd_sb_connector,
- ipaddress=fabric_ip,
- username=fabric_user,
- password=fabric_pwd,
- port=fabric_port)
- if not conn.is_supported_firmware():
- msg = _("Unsupported firmware on switch %s. Make sure "
- "switch is running firmware v6.4 or higher"
- ) % fabric_ip
- LOG.error(msg)
- raise exception.FCZoneDriverException(msg)
- except exception.BrocadeZoningCliException as brocade_ex:
- raise exception.FCZoneDriverException(brocade_ex)
- except Exception as e:
- LOG.error(e)
- msg = _("Failed to get SAN context %s") % e
- raise exception.FCZoneDriverException(msg)
+ conn = self._get_cli_client(fabric_name)
# Get name server data from fabric and get the targets
# logged in.
LOG.debug("name server info from fabric:%s", nsinfo)
conn.cleanup()
except exception.BrocadeZoningCliException as ex:
+ if not conn.is_supported_firmware():
+ msg = _("Unsupported firmware on switch %s. Make sure "
+ "switch is running firmware v6.4 or higher"
+ ) % conn.switch_ip
+ LOG.error(msg)
+ raise exception.FCZoneDriverException(msg)
with excutils.save_and_reraise_exception():
LOG.error(_("Error getting name server "
"info: %s"), ex)
LOG.debug("Return SAN context output:%s", fabric_map)
return fabric_map
- def get_active_zone_set(self, fabric_ip,
- fabric_user, fabric_pwd, fabric_port):
- """Gets active zone config from fabric."""
- cfgmap = {}
- conn = None
+ def _get_active_zone_set(self, conn):
+ cfgmap = None
try:
- LOG.debug("Southbound connector:"
- " %s", self.configuration.brcd_sb_connector)
- conn = importutils.import_object(
- self.configuration.brcd_sb_connector,
- ipaddress=fabric_ip, username=fabric_user,
- password=fabric_pwd, port=fabric_port)
+ cfgmap = conn.get_active_zone_set()
+ except exception.BrocadeZoningCliException:
if not conn.is_supported_firmware():
msg = _("Unsupported firmware on switch %s. Make sure "
"switch is running firmware v6.4 or higher"
- ) % fabric_ip
+ ) % conn.switch_ip
LOG.error(msg)
raise exception.FCZoneDriverException(msg)
- cfgmap = conn.get_active_zone_set()
- conn.cleanup()
- except exception.BrocadeZoningCliException as brocade_ex:
- raise exception.FCZoneDriverException(brocade_ex)
except Exception as e:
- msg = (_("Failed to access active zoning configuration:%s") % e)
- LOG.error(msg)
+ LOG.error(e)
+ msg = _("Failed to retrieve active zoning configuration %s") % e
raise exception.FCZoneDriverException(msg)
LOG.debug("Active zone set from fabric: %s", cfgmap)
return cfgmap
+
+ def _get_cli_client(self, 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')
+ cli_client = None
+ try:
+ cli_client = self.sb_conn_map.get(fabric_ip)
+ if not cli_client:
+ LOG.debug("CLI client not found, creating for %s", fabric_ip)
+ cli_client = importutils.import_object(
+ self.configuration.brcd_sb_connector,
+ ipaddress=fabric_ip,
+ username=fabric_user,
+ password=fabric_pwd,
+ port=fabric_port)
+ self.sb_conn_map[fabric_ip] = cli_client
+ except Exception as e:
+ LOG.error(e)
+ msg = _("Failed to create sb connector for %s") % fabric_ip
+ raise exception.FCZoneDriverException(msg)
+ return cli_client