'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'

@lockutils.synchronized('brcd', 'fcfabric-', True)
def add_connection(self, fabric, initiator_target_map, host_name=None, storage_system=None):

    LOG.info('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('Zoning    policy    for    Fabric    %(policy)s', {'policy': zoning_policy})
    if ((zoning_policy != 'initiator') and (zoning_policy != 'initiator-target')):
        LOG.info('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()
    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:
                    LOG.info('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)):
                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('Zone    map    to    create:    %(zonemap)s', {'zonemap': zone_map})
        LOG.info('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()
