Beispiel #1
0
 def test_get_friendly_zone_name_initiator_mode_hostname_none(self, value):
     self.assertEqual(
         value,
         driver_utils.get_friendly_zone_name('initiator',
                                             "10:00:8c:7c:ff:52:3b:01",
                                             None, None, None, "openstack",
                                             TEST_CHAR_SET))
Beispiel #2
0
 def test_get_friendly_zone_name_storagename_length_too_long(self, value):
     self.assertEqual(
         value,
         driver_utils.get_friendly_zone_name(
             'initiator-target', "10:00:8c:7c:ff:52:3b:01",
             "20:24:00:02:ac:00:0a:50", "OS_Host100XXXXXXXXXX",
             "AMCE_ArrayYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
             "YYYY", "openstack", TEST_CHAR_SET))
Beispiel #3
0
 def test_get_friendly_zone_name_hostname_none(self, value):
     self.assertEqual(
         value,
         driver_utils.get_friendly_zone_name('initiator-target',
                                             "10:00:8c:7c:ff:52:3b:01",
                                             "20:24:00:02:ac:00:0a:50",
                                             None, "AMCE_Array",
                                             "openstack", TEST_CHAR_SET))
Beispiel #4
0
 def test_get_friendly_zone_name_initiator_mode_hostname_max_length(self,
                                                                    value):
     self.assertEqual(value,
                      driver_utils.get_friendly_zone_name(
                          'initiator', "10:00:8c:7c:ff:52:3b:01", None,
                          'OS_Host100XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
                          'XXXXX',
                          None, "openstack", TEST_CHAR_SET))
Beispiel #5
0
 def test_get_friendly_zone_name_max_length(self, value):
     self.assertEqual(value,
                      driver_utils.get_friendly_zone_name(
                          'initiator-target', "10:00:8c:7c:ff:52:3b:01",
                          "20:24:00:02:ac:00:0a:50",
                          "OS_Host100XXXXXXXXXX",
                          "AMCE_ArrayYYYYYYYYYY",
                          "openstack", TEST_CHAR_SET))
Beispiel #6
0
 def test_get_friendly_zone_name_valid_hostname_storagesystem(self, value):
     self.assertEqual(
         value,
         driver_utils.get_friendly_zone_name('initiator-target',
                                             "10:00:8c:7c:ff:52:3b:01",
                                             "20:24:00:02:ac:00:0a:50",
                                             "OS_Host100", 'AMCE'
                                             '_Array', "openstack",
                                             TEST_CHAR_SET))
    def delete_connection(self,
                          fabric,
                          initiator_target_map,
                          host_name=None,
                          storage_system=None):
        """Concrete implementation of delete_connection.

        Based on zoning policy and state of each I-T pair, list of zones
        are created for deletion. The zones are either updated deleted based
        on the policy and attach/detach state of each I-T pair.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.debug("Delete connection for fabric: %s", fabric)
        LOG.info("CiscoFCZoneDriver - Delete connection for I-T map: %s",
                 initiator_target_map)
        fabric_ip = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_address')
        fabric_user = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_user')
        fabric_pwd = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_password')
        fabric_port = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_port')
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'cisco_zoning_policy')
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'cisco_zone_name_prefix')

        if not zone_name_prefix:
            zone_name_prefix = self.configuration.cisco_zone_name_prefix

        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab

        zoning_vsan = self.fabric_configs[fabric].safe_get('cisco_zoning_vsan')

        LOG.info("Zoning policy for fabric %s", zoning_policy)

        statusmap_from_fabric = self.get_zoning_status(fabric_ip, fabric_user,
                                                       fabric_pwd, fabric_port,
                                                       zoning_vsan)

        if statusmap_from_fabric.get('session') == 'none':
            cfgmap_from_fabric = self.get_active_zone_set(
                fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)

            zone_names = []
            if cfgmap_from_fabric.get('zones'):
                zone_names = cfgmap_from_fabric['zones'].keys()

            # Based on zoning policy, get zone member list and push
            # changes to fabric. This operation could result in an update
            # for zone config with new member list or deleting zones from
            # active cfg.

            LOG.debug("zone config from Fabric: %s", cfgmap_from_fabric)
            for initiator_key in initiator_target_map.keys():
                initiator = initiator_key.lower()
                formatted_initiator = zm_utils.get_formatted_wwn(initiator)
                zone_update_map = {}
                zones_to_delete = []
                t_list = initiator_target_map[initiator_key]
                if zoning_policy == 'initiator-target':
                    # In this case, zone needs to be deleted.
                    for t in t_list:
                        target = t.lower()
                        zone_name = (driver_utils.get_friendly_zone_name(
                            zoning_policy, initiator, target, host_name,
                            storage_system, zone_name_prefix, SUPPORTED_CHARS))
                        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)
                            zones_to_delete.append(zone_name)

                elif zoning_policy == 'initiator':
                    zone_members = [formatted_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, zone_name_prefix, SUPPORTED_CHARS)
                    # Check if there are zone members leftover after removal
                    if (zone_names and (zone_name in zone_names)):
                        filtered_members = list(
                            filter(lambda x: x not in zone_members,
                                   cfgmap_from_fabric['zones'][zone_name]))

                        # The assumption here is that initiator is always
                        # there in the zone as it is 'initiator' policy.
                        # If filtered list is empty, we remove that zone.
                        # If there are other members leftover, then perform
                        # update_zone to remove targets
                        LOG.debug("Zone delete - I mode: filtered targets: %s",
                                  filtered_members)
                        if filtered_members:
                            remove_members = list(
                                filter(
                                    lambda x: x in cfgmap_from_fabric['zones'][
                                        zone_name], zone_members))
                            if remove_members:
                                # Do not want to remove the initiator
                                remove_members.remove(formatted_initiator)
                                LOG.debug("Zone members to remove: %s",
                                          remove_members)
                                zone_update_map[zone_name] = remove_members
                                LOG.debug("Filtered zone Map to update: %s",
                                          zone_update_map)
                        else:
                            zones_to_delete.append(zone_name)
                else:
                    LOG.info("Zoning Policy: %s, not recognized",
                             zoning_policy)
                LOG.debug("Zone map to remove update: %s", zone_update_map)
                LOG.debug("Final Zone list to delete: %s", zones_to_delete)
                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)
                    # Update zone membership.
                    if zone_update_map:
                        conn.update_zones(
                            zone_update_map,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, ZoneConstant.ZONE_REMOVE,
                            cfgmap_from_fabric, statusmap_from_fabric)
                    # Delete zones ~sk.
                    if zones_to_delete:
                        zone_name_string = ''
                        num_zones = len(zones_to_delete)
                        for i in range(0, num_zones):
                            if i == 0:
                                zone_name_string = (
                                    '%s%s' %
                                    (zone_name_string, zones_to_delete[i]))
                            else:
                                zone_name_string = ('%s%s%s' %
                                                    (zone_name_string, ';',
                                                     zones_to_delete[i]))

                        conn.delete_zones(
                            zone_name_string,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, cfgmap_from_fabric,
                            statusmap_from_fabric)
                    conn.cleanup()
                except Exception:
                    msg = _("Failed to update or delete zoning configuration")
                    LOG.exception(msg)
                    raise exception.FCZoneDriverException(msg)
                LOG.debug("Zones deleted successfully: %s", zone_update_map)
            else:
                LOG.debug("Zoning session exists VSAN: %s", zoning_vsan)
    def add_connection(self,
                       fabric,
                       initiator_target_map,
                       host_name=None,
                       storage_system=None):
        """Concrete implementation of add_connection.

        Based on zoning policy and state of each I-T pair, list of zone
        members are created and pushed to the fabric to add zones. The
        new zones created or zones updated are activated based on isActivate
        flag set in cinder.conf returned by volume driver after attach
        operation.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """

        LOG.debug("Add connection for Fabric: %s", fabric)
        LOG.info("CiscoFCZoneDriver - Add connection "
                 "for I-T map: %s", initiator_target_map)
        fabric_ip = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_address')
        fabric_user = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_user')
        fabric_pwd = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_password')
        fabric_port = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_port')
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'cisco_zoning_policy')
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'cisco_zone_name_prefix')

        if not zone_name_prefix:
            zone_name_prefix = self.configuration.cisco_zone_name_prefix

        zoning_vsan = self.fabric_configs[fabric].safe_get('cisco_zoning_vsan')

        LOG.info("Zoning policy for Fabric %s", zoning_policy)

        statusmap_from_fabric = self.get_zoning_status(fabric_ip, fabric_user,
                                                       fabric_pwd, fabric_port,
                                                       zoning_vsan)

        if statusmap_from_fabric.get('session') == 'none':

            cfgmap_from_fabric = self.get_active_zone_set(
                fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)
            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 = {}
                zone_update_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, 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(
                                "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, zone_name_prefix, SUPPORTED_CHARS))

                    # If zone exists, then perform an update_zone and add
                    # new members into existing zone.
                    if zone_name and (zone_name in zone_names):
                        zone_members = list(
                            filter(
                                lambda x: x not in cfgmap_from_fabric['zones'][
                                    zone_name], zone_members))
                        if zone_members:
                            zone_update_map[zone_name] = zone_members
                    else:
                        zone_map[zone_name] = zone_members
                else:
                    msg = _("Zoning Policy: %s, not"
                            " recognized") % zoning_policy
                    LOG.error(msg)
                    raise exception.FCZoneDriverException(msg)

            LOG.info("Zone map to add: %(zone_map)s", {'zone_map': zone_map})
            LOG.info("Zone map to update add: %(zone_update_map)s",
                     {'zone_update_map': zone_update_map})
            if zone_map or zone_update_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)
                    if zone_map:
                        conn.add_zones(zone_map,
                                       self.configuration.cisco_zone_activate,
                                       zoning_vsan, cfgmap_from_fabric,
                                       statusmap_from_fabric)
                    if zone_update_map:
                        conn.update_zones(
                            zone_update_map,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, ZoneConstant.ZONE_ADD,
                            cfgmap_from_fabric, statusmap_from_fabric)
                    conn.cleanup()
                except c_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("Zones already exist - Initiator Target Map: %s",
                          initiator_target_map)
        else:
            LOG.debug("Zoning session exists VSAN: %s", zoning_vsan)
Beispiel #9
0
    def delete_connection(self, fabric, initiator_target_map, host_name=None,
                          storage_system=None):
        """Concrete implementation of delete_connection.

        Based on zoning policy and state of each I-T pair, list of zones
        are created for deletion. The zones are either updated deleted based
        on the policy and attach/detach state of each I-T pair.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.info(_LI("BrcdFCZoneDriver - Delete connection for fabric "
                 "%(fabric)s for I-T map: %(i_t_map)s"),
                 {'fabric': fabric,
                  'i_t_map': initiator_target_map})
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'zoning_policy')
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'zone_name_prefix')
        zone_activate = self.fabric_configs[fabric].safe_get(
            'zone_activate')
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        LOG.info(_LI("Zoning policy for fabric %(policy)s"),
                 {'policy': zoning_policy})
        conn = self._get_southbound_client(fabric)
        cfgmap_from_fabric = self._get_active_zone_set(conn)

        zone_names = []
        if cfgmap_from_fabric.get('zones'):
            zone_names = cfgmap_from_fabric['zones'].keys()

        # Based on zoning policy, get zone member list and push changes to
        # fabric. This operation could result in an update for zone config
        # with new member list or deleting zones from active cfg.
        LOG.debug("zone config from Fabric: %(cfgmap)s",
                  {'cfgmap': cfgmap_from_fabric})
        for initiator_key in initiator_target_map.keys():
            initiator = initiator_key.lower()
            formatted_initiator = utils.get_formatted_wwn(initiator)
            zone_map = {}
            zones_to_delete = []
            t_list = initiator_target_map[initiator_key]
            if zoning_policy == 'initiator-target':
                # In this case, zone needs to be deleted.
                for t in t_list:
                    target = t.lower()
                    zone_name = driver_utils.get_friendly_zone_name(
                        zoning_policy,
                        initiator,
                        target,
                        host_name,
                        storage_system,
                        zone_name_prefix,
                        SUPPORTED_CHARS)
                    LOG.debug("Zone name to delete: %(zonename)s",
                              {'zonename': zone_name})
                    if len(zone_names) > 0 and (zone_name in zone_names):
                        # delete zone.
                        LOG.debug("Added zone to delete to list: %(zonename)s",
                                  {'zonename': zone_name})
                        zones_to_delete.append(zone_name)

            elif zoning_policy == 'initiator':
                zone_members = [formatted_initiator]
                for t in t_list:
                    target = t.lower()
                    zone_members.append(utils.get_formatted_wwn(target))

                zone_name = driver_utils.get_friendly_zone_name(
                    zoning_policy,
                    initiator,
                    target,
                    host_name,
                    storage_system,
                    zone_name_prefix,
                    SUPPORTED_CHARS)

                if (zone_names and (zone_name in zone_names)):
                    # Check to see if there are other zone members
                    # in the zone besides the initiator and
                    # the targets being removed.
                    filtered_members = filter(
                        lambda x: x not in zone_members,
                        cfgmap_from_fabric['zones'][zone_name])

                    # If there are other zone members, proceed with
                    # zone update to remove the targets.  Otherwise,
                    # delete the zone.
                    if filtered_members:
                        zone_members.remove(formatted_initiator)
                        # Verify that the zone members in target list
                        # are listed in zone definition.  If not, remove
                        # the zone members from the list of members
                        # to remove, otherwise switch will return error.
                        zm_list = cfgmap_from_fabric['zones'][zone_name]
                        for t in t_list:
                            formatted_target = utils.get_formatted_wwn(t)
                            if formatted_target not in zm_list:
                                zone_members.remove(formatted_target)
                        if zone_members:
                            LOG.debug("Zone members to remove: "
                                      "%(members)s", {'members': zone_members})
                            zone_map[zone_name] = zone_members
                    else:
                        zones_to_delete.append(zone_name)
            else:
                LOG.warning(_LW("Zoning policy not recognized: %(policy)s"),
                            {'policy': zoning_policy})
            LOG.debug("Zone map to update: %(zonemap)s",
                      {'zonemap': zone_map})
            LOG.debug("Zone list to delete: %(zones)s",
                      {'zones': zones_to_delete})
            try:
                # Update zone membership.
                if zone_map:
                    conn.update_zones(zone_map, zone_activate,
                                      fc_zone_constants.ZONE_REMOVE,
                                      cfgmap_from_fabric)
                # Delete zones
                if zones_to_delete:
                    zone_name_string = ''
                    num_zones = len(zones_to_delete)
                    for i in range(0, num_zones):
                        if i == 0:
                            zone_name_string = (
                                '%s%s' % (
                                    zone_name_string, zones_to_delete[i]))
                        else:
                            zone_name_string = '%s;%s' % (
                                zone_name_string, zones_to_delete[i])

                    conn.delete_zones(
                        zone_name_string, zone_activate,
                        cfgmap_from_fabric)
            except (exception.BrocadeZoningCliException,
                    exception.BrocadeZoningHttpException) as brocade_ex:
                raise exception.FCZoneDriverException(brocade_ex)
            except Exception:
                msg = _("Failed to update or delete zoning "
                        "configuration.")
                LOG.exception(msg)
                raise exception.FCZoneDriverException(msg)
            finally:
                conn.cleanup()
Beispiel #10
0
    def add_connection(self, fabric, initiator_target_map, host_name=None,
                       storage_system=None):
        """Concrete implementation of add_connection.

        Based on zoning policy and state of each I-T pair, list of zone
        members are created and pushed to the fabric to add zones. The
        new zones created or zones updated are activated based on isActivate
        flag set in cinder.conf returned by volume driver after attach
        operation.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.info(_LI("BrcdFCZoneDriver - Add connection for fabric "
                     "%(fabric)s for I-T map: %(i_t_map)s"),
                 {'fabric': fabric,
                  'i_t_map': initiator_target_map})
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'zoning_policy')
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'zone_name_prefix')
        zone_activate = self.fabric_configs[fabric].safe_get(
            'zone_activate')
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        LOG.info(_LI("Zoning policy for Fabric %(policy)s"),
                 {'policy': zoning_policy})
        if (zoning_policy != 'initiator'
                and zoning_policy != 'initiator-target'):
            LOG.info(_LI("Zoning policy is not valid, "
                         "no zoning will be performed."))
            return

        client = self._get_southbound_client(fabric)
        cfgmap_from_fabric = self._get_active_zone_set(client)

        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 = {}
            zone_update_map = {}
            initiator = initiator_key.lower()
            target_list = initiator_target_map[initiator_key]
            if zoning_policy == 'initiator-target':
                for target in target_list:
                    zone_members = [utils.get_formatted_wwn(initiator),
                                    utils.get_formatted_wwn(target)]
                    zone_name = driver_utils.get_friendly_zone_name(
                        zoning_policy,
                        initiator,
                        target,
                        host_name,
                        storage_system,
                        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 already exists.
                        LOG.info(_LI("Zone exists in I-T mode. Skipping "
                                     "zone creation for %(zonename)s"),
                                 {'zonename': zone_name})
            elif zoning_policy == 'initiator':
                zone_members = [utils.get_formatted_wwn(initiator)]
                for target in target_list:
                    zone_members.append(utils.get_formatted_wwn(target))

                zone_name = driver_utils.get_friendly_zone_name(
                    zoning_policy,
                    initiator,
                    target,
                    host_name,
                    storage_system,
                    zone_name_prefix,
                    SUPPORTED_CHARS)

                # If zone exists, then do a zoneadd to update
                # the zone members in the existing zone.  Otherwise,
                # do a zonecreate to create a new zone.
                if len(zone_names) > 0 and (zone_name in zone_names):
                    # Verify that the target WWNs are not already members
                    # of the existing zone.  If so, remove them from the
                    # list of members to add, otherwise error will be
                    # returned from the switch.
                    for t in target_list:
                        if t in cfgmap_from_fabric['zones'][zone_name]:
                            zone_members.remove(utils.get_formatted_wwn(t))
                    if zone_members:
                        zone_update_map[zone_name] = zone_members
                else:
                    zone_map[zone_name] = zone_members

            LOG.info(_LI("Zone map to create: %(zonemap)s"),
                     {'zonemap': zone_map})
            LOG.info(_LI("Zone map to update: %(zone_update_map)s"),
                     {'zone_update_map': zone_update_map})

            try:
                if zone_map:
                    client.add_zones(zone_map, zone_activate,
                                     cfgmap_from_fabric)
                    LOG.debug("Zones created successfully: %(zonemap)s",
                              {'zonemap': zone_map})
                if zone_update_map:
                    client.update_zones(zone_update_map, zone_activate,
                                        fc_zone_constants.ZONE_ADD,
                                        cfgmap_from_fabric)
                    LOG.debug("Zones updated successfully: %(updatemap)s",
                              {'updatemap': zone_update_map})
            except (exception.BrocadeZoningCliException,
                    exception.BrocadeZoningHttpException) as brocade_ex:
                raise exception.FCZoneDriverException(brocade_ex)
            except Exception:
                msg = _("Failed to add or update zoning configuration.")
                LOG.exception(msg)
                raise exception.FCZoneDriverException(msg)
            finally:
                client.cleanup()
Beispiel #11
0
    def delete_connection(self, fabric, initiator_target_map, host_name=None,
                          storage_system=None):
        """Concrete implementation of delete_connection.

        Based on zoning policy and state of each I-T pair, list of zones
        are created for deletion. The zones are either updated deleted based
        on the policy and attach/detach state of each I-T pair.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.debug("Delete connection for fabric: %s", fabric)
        LOG.info("CiscoFCZoneDriver - Delete connection for I-T map: %s",
                 initiator_target_map)
        fabric_ip = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_address')
        fabric_user = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_user')
        fabric_pwd = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_password')
        fabric_port = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_port')
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'cisco_zoning_policy')
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'cisco_zone_name_prefix')

        if not zone_name_prefix:
            zone_name_prefix = self.configuration.cisco_zone_name_prefix

        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab

        zoning_vsan = self.fabric_configs[fabric].safe_get('cisco_zoning_vsan')

        LOG.info("Zoning policy for fabric %s", zoning_policy)

        statusmap_from_fabric = self.get_zoning_status(
            fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)

        if statusmap_from_fabric.get('session') == 'none':
            cfgmap_from_fabric = self.get_active_zone_set(
                fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)

            zone_names = []
            if cfgmap_from_fabric.get('zones'):
                zone_names = cfgmap_from_fabric['zones'].keys()

            # Based on zoning policy, get zone member list and push
            # changes to fabric. This operation could result in an update
            # for zone config with new member list or deleting zones from
            # active cfg.

            LOG.debug("zone config from Fabric: %s", cfgmap_from_fabric)
            for initiator_key in initiator_target_map.keys():
                initiator = initiator_key.lower()
                formatted_initiator = zm_utils.get_formatted_wwn(initiator)
                zone_update_map = {}
                zones_to_delete = []
                t_list = initiator_target_map[initiator_key]
                if zoning_policy == 'initiator-target':
                    # In this case, zone needs to be deleted.
                    for t in t_list:
                        target = t.lower()
                        zone_name = (
                            driver_utils.get_friendly_zone_name(
                                zoning_policy,
                                initiator,
                                target,
                                host_name,
                                storage_system,
                                zone_name_prefix,
                                SUPPORTED_CHARS))
                        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)
                            zones_to_delete.append(zone_name)

                elif zoning_policy == 'initiator':
                    zone_members = [formatted_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,
                        zone_name_prefix,
                        SUPPORTED_CHARS)
                    # Check if there are zone members leftover after removal
                    if (zone_names and (zone_name in zone_names)):
                        filtered_members = filter(
                            lambda x: x not in zone_members,
                            cfgmap_from_fabric['zones'][zone_name])

                        # The assumption here is that initiator is always
                        # there in the zone as it is 'initiator' policy.
                        # If filtered list is empty, we remove that zone.
                        # If there are other members leftover, then perform
                        # update_zone to remove targets
                        LOG.debug("Zone delete - I mode: filtered targets: %s",
                                  filtered_members)
                        if filtered_members:
                            remove_members = filter(
                                lambda x: x in
                                cfgmap_from_fabric['zones'][zone_name],
                                zone_members)
                            if remove_members:
                                # Do not want to remove the initiator
                                remove_members.remove(formatted_initiator)
                                LOG.debug("Zone members to remove: %s",
                                          remove_members)
                                zone_update_map[zone_name] = remove_members
                                LOG.debug("Filtered zone Map to update: %s",
                                          zone_update_map)
                        else:
                            zones_to_delete.append(zone_name)
                else:
                    LOG.info("Zoning Policy: %s, not recognized",
                             zoning_policy)
                LOG.debug("Zone map to remove update: %s", zone_update_map)
                LOG.debug("Final Zone list to delete: %s", zones_to_delete)
                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)
                    # Update zone membership.
                    if zone_update_map:
                        conn.update_zones(
                            zone_update_map,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, ZoneConstant.ZONE_REMOVE,
                            cfgmap_from_fabric, statusmap_from_fabric)
                    # Delete zones ~sk.
                    if zones_to_delete:
                        zone_name_string = ''
                        num_zones = len(zones_to_delete)
                        for i in range(0, num_zones):
                            if i == 0:
                                zone_name_string = ('%s%s' % (
                                                    zone_name_string,
                                                    zones_to_delete[i]))
                            else:
                                zone_name_string = ('%s%s%s' % (
                                                    zone_name_string, ';',
                                                    zones_to_delete[i]))

                        conn.delete_zones(zone_name_string,
                                          self.configuration.
                                          cisco_zone_activate,
                                          zoning_vsan, cfgmap_from_fabric,
                                          statusmap_from_fabric)
                    conn.cleanup()
                except Exception:
                    msg = _("Failed to update or delete zoning configuration")
                    LOG.exception(msg)
                    raise exception.FCZoneDriverException(msg)
                LOG.debug("Zones deleted successfully: %s", zone_update_map)
            else:
                LOG.debug("Zoning session exists VSAN: %s", zoning_vsan)
Beispiel #12
0
    def add_connection(self, fabric, initiator_target_map, host_name=None,
                       storage_system=None):
        """Concrete implementation of add_connection.

        Based on zoning policy and state of each I-T pair, list of zone
        members are created and pushed to the fabric to add zones. The
        new zones created or zones updated are activated based on isActivate
        flag set in cinder.conf returned by volume driver after attach
        operation.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """

        LOG.debug("Add connection for Fabric: %s", fabric)
        LOG.info("CiscoFCZoneDriver - Add connection "
                 "for I-T map: %s", initiator_target_map)
        fabric_ip = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_address')
        fabric_user = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_user')
        fabric_pwd = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_password')
        fabric_port = self.fabric_configs[fabric].safe_get(
            'cisco_fc_fabric_port')
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'cisco_zoning_policy')
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'cisco_zone_name_prefix')

        if not zone_name_prefix:
            zone_name_prefix = self.configuration.cisco_zone_name_prefix

        zoning_vsan = self.fabric_configs[fabric].safe_get('cisco_zoning_vsan')

        LOG.info("Zoning policy for Fabric %s", zoning_policy)

        statusmap_from_fabric = self.get_zoning_status(
            fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)

        if statusmap_from_fabric.get('session') == 'none':

            cfgmap_from_fabric = self.get_active_zone_set(
                fabric_ip, fabric_user, fabric_pwd, fabric_port, zoning_vsan)
            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 = {}
                zone_update_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,
                                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("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,
                            zone_name_prefix,
                            SUPPORTED_CHARS))

                    # If zone exists, then perform an update_zone and add
                    # new members into existing zone.
                    if zone_name and (zone_name in zone_names):
                        zone_members = filter(
                            lambda x: x not in
                            cfgmap_from_fabric['zones'][zone_name],
                            zone_members)
                        if zone_members:
                            zone_update_map[zone_name] = zone_members
                    else:
                        zone_map[zone_name] = zone_members
                else:
                    msg = _("Zoning Policy: %s, not"
                            " recognized") % zoning_policy
                    LOG.error(msg)
                    raise exception.FCZoneDriverException(msg)

            LOG.info("Zone map to add: %(zone_map)s",
                     {'zone_map': zone_map})
            LOG.info("Zone map to update add: %(zone_update_map)s",
                     {'zone_update_map': zone_update_map})
            if zone_map or zone_update_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)
                    if zone_map:
                        conn.add_zones(
                            zone_map,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, cfgmap_from_fabric,
                            statusmap_from_fabric)
                    if zone_update_map:
                        conn.update_zones(
                            zone_update_map,
                            self.configuration.cisco_zone_activate,
                            zoning_vsan, ZoneConstant.ZONE_ADD,
                            cfgmap_from_fabric,
                            statusmap_from_fabric)
                    conn.cleanup()
                except c_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("Zones already exist - Initiator Target Map: %s",
                          initiator_target_map)
        else:
            LOG.debug("Zoning session exists VSAN: %s", zoning_vsan)
Beispiel #13
0
    def delete_connection(self, fabric, initiator_target_map, host_name=None,
                          storage_system=None):
        """Concrete implementation of delete_connection.

        Based on zoning policy and state of each I-T pair, list of zones
        are created for deletion. The zones are either updated deleted based
        on the policy and attach/detach state of each I-T pair.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.info(_LI("BrcdFCZoneDriver - Delete connection for fabric "
                 "%(fabric)s for I-T map: %(i_t_map)s"),
                 {'fabric': fabric,
                  'i_t_map': initiator_target_map})
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get(
            'zoning_policy')
        zone_name_prefix = self.fabric_configs[fabric].safe_get(
            'zone_name_prefix')
        zone_activate = self.fabric_configs[fabric].safe_get(
            'zone_activate')
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        LOG.info(_LI("Zoning policy for fabric %(policy)s"),
                 {'policy': zoning_policy})
        conn = self._get_southbound_client(fabric)
        cfgmap_from_fabric = self._get_active_zone_set(conn)

        zone_names = []
        if cfgmap_from_fabric.get('zones'):
            zone_names = cfgmap_from_fabric['zones'].keys()

        # Based on zoning policy, get zone member list and push changes to
        # fabric. This operation could result in an update for zone config
        # with new member list or deleting zones from active cfg.
        LOG.debug("zone config from Fabric: %(cfgmap)s",
                  {'cfgmap': cfgmap_from_fabric})
        for initiator_key in initiator_target_map.keys():
            initiator = initiator_key.lower()
            formatted_initiator = utils.get_formatted_wwn(initiator)
            zone_map = {}
            zones_to_delete = []
            t_list = initiator_target_map[initiator_key]
            if zoning_policy == 'initiator-target':
                # In this case, zone needs to be deleted.
                for t in t_list:
                    target = t.lower()
                    zone_name = driver_utils.get_friendly_zone_name(
                        zoning_policy,
                        initiator,
                        target,
                        host_name,
                        storage_system,
                        zone_name_prefix,
                        SUPPORTED_CHARS)
                    LOG.debug("Zone name to delete: %(zonename)s",
                              {'zonename': zone_name})
                    if len(zone_names) > 0 and (zone_name in zone_names):
                        # delete zone.
                        LOG.debug("Added zone to delete to list: %(zonename)s",
                                  {'zonename': zone_name})
                        zones_to_delete.append(zone_name)

            elif zoning_policy == 'initiator':
                zone_members = [formatted_initiator]
                for t in t_list:
                    target = t.lower()
                    zone_members.append(utils.get_formatted_wwn(target))

                zone_name = driver_utils.get_friendly_zone_name(
                    zoning_policy,
                    initiator,
                    target,
                    host_name,
                    storage_system,
                    zone_name_prefix,
                    SUPPORTED_CHARS)

                if (zone_names and (zone_name in zone_names)):
                    filtered_members = filter(
                        lambda x: x not in zone_members,
                        cfgmap_from_fabric['zones'][zone_name])

                    # The assumption here is that initiator is always there
                    # in the zone as it is 'initiator' policy. We find the
                    # filtered list and if it is non-empty, add initiator
                    # to it and update zone if filtered list is empty, we
                    # remove that zone.
                    LOG.debug("Zone delete - initiator mode: "
                              "filtered targets: %(targets)s",
                              {'targets': filtered_members})
                    if filtered_members:
                        filtered_members.append(formatted_initiator)
                        LOG.debug("Filtered zone members to update: "
                                  "%(members)s", {'members': filtered_members})
                        zone_map[zone_name] = filtered_members
                        LOG.debug("Filtered zone map to update: %(zonemap)s",
                                  {'zonemap': zone_map})
                    else:
                        zones_to_delete.append(zone_name)
            else:
                LOG.warning(_LW("Zoning policy not recognized: %(policy)s"),
                            {'policy': zoning_policy})
            LOG.debug("Final zone map to update: %(zonemap)s",
                      {'zonemap': zone_map})
            LOG.debug("Final zone list to delete: %(zones)s",
                      {'zones': zones_to_delete})
            try:
                # Update zone membership.
                if zone_map:
                    conn.add_zones(
                        zone_map, zone_activate,
                        cfgmap_from_fabric)
                # Delete zones ~sk.
                if zones_to_delete:
                    zone_name_string = ''
                    num_zones = len(zones_to_delete)
                    for i in range(0, num_zones):
                        if i == 0:
                            zone_name_string = (
                                '%s%s' % (
                                    zone_name_string, zones_to_delete[i]))
                        else:
                            zone_name_string = '%s;%s' % (
                                zone_name_string, zones_to_delete[i])

                    conn.delete_zones(
                        zone_name_string, zone_activate,
                        cfgmap_from_fabric)
                conn.cleanup()
            except (exception.BrocadeZoningCliException,
                    exception.BrocadeZoningHttpException) as brocade_ex:
                raise exception.FCZoneDriverException(brocade_ex)
            except Exception:
                msg = _("Failed to update or delete zoning "
                        "configuration.")
                LOG.exception(msg)
                raise exception.FCZoneDriverException(msg)
Beispiel #14
0
    def add_connection(self, fabric, initiator_target_map, host_name=None, storage_system=None):
        """Concrete implementation of add_connection.

        Based on zoning policy and state of each I-T pair, list of zone
        members are created and pushed to the fabric to add zones. The
        new zones created or zones updated are activated based on isActivate
        flag set in cinder.conf returned by volume driver after attach
        operation.

        :param fabric: Fabric name from cinder.conf file
        :param initiator_target_map: Mapping of initiator to list of targets
        """
        LOG.info(
            _LI("BrcdFCZoneDriver - Add connection for fabric " "%(fabric)s for I-T map: %(i_t_map)s"),
            {"fabric": fabric, "i_t_map": initiator_target_map},
        )
        zoning_policy = self.configuration.zoning_policy
        zoning_policy_fab = self.fabric_configs[fabric].safe_get("zoning_policy")
        zone_name_prefix = self.fabric_configs[fabric].safe_get("zone_name_prefix")
        zone_activate = self.fabric_configs[fabric].safe_get("zone_activate")
        if zoning_policy_fab:
            zoning_policy = zoning_policy_fab
        LOG.info(_LI("Zoning policy for Fabric %(policy)s"), {"policy": zoning_policy})
        if zoning_policy != "initiator" and zoning_policy != "initiator-target":
            LOG.info(_LI("Zoning policy is not valid, " "no zoning will be performed."))
            return

        client = self._get_southbound_client(fabric)
        cfgmap_from_fabric = self._get_active_zone_set(client)

        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()
            target_list = initiator_target_map[initiator_key]
            if zoning_policy == "initiator-target":
                for target in target_list:
                    zone_members = [utils.get_formatted_wwn(initiator), utils.get_formatted_wwn(target)]
                    zone_name = driver_utils.get_friendly_zone_name(
                        zoning_policy, initiator, target, host_name, storage_system, 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 already exists.
                        LOG.info(
                            _LI("Zone exists in I-T mode. Skipping " "zone creation for %(zonename)s"),
                            {"zonename": zone_name},
                        )
            elif zoning_policy == "initiator":
                zone_members = [utils.get_formatted_wwn(initiator)]
                for target in target_list:
                    zone_members.append(utils.get_formatted_wwn(target))

                zone_name = driver_utils.get_friendly_zone_name(
                    zoning_policy, initiator, target, host_name, storage_system, 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

            LOG.info(_LI("Zone map to add: %(zonemap)s"), {"zonemap": zone_map})

            if len(zone_map) > 0:
                try:
                    client.add_zones(zone_map, zone_activate, cfgmap_from_fabric)
                    client.cleanup()
                except (exception.BrocadeZoningCliException, exception.BrocadeZoningHttpException) as brocade_ex:
                    raise exception.FCZoneDriverException(brocade_ex)
                except Exception:
                    msg = _("Failed to add zoning configuration.")
                    LOG.exception(msg)
                    raise exception.FCZoneDriverException(msg)
            LOG.debug("Zones added successfully: %(zonemap)s", {"zonemap": zone_map})
Beispiel #15
0
 def test_get_friendly_zone_name_hostname_none(self, value):
     self.assertEqual(value,
                      driver_utils.get_friendly_zone_name(
                          'initiator-target', "10:00:8c:7c:ff:52:3b:01",
                          "20:24:00:02:ac:00:0a:50", None, "AMCE_Array",
                          "openstack", TEST_CHAR_SET))
Beispiel #16
0
 def test_get_friendly_zone_name_valid_hostname_storagesystem(self, value):
     self.assertEqual(value,
                      driver_utils.get_friendly_zone_name(
                          'initiator-target', "10:00:8c:7c:ff:52:3b:01",
                          "20:24:00:02:ac:00:0a:50", "OS_Host100", 'AMCE'
                          '_Array', "openstack", TEST_CHAR_SET))