'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('cisco', 'fcfabric-', True)
def add_connection(self, fabric, initiator_target_map, host_name=None, storage_system=None):

    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
    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()
        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, 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:
                        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, self.configuration.cisco_zone_name_prefix, SUPPORTED_CHARS)
                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 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)
