Пример #1
0
    def get_device_mapping_from_network(self, initiator_list, target_list):
        """Get device mapping from FC network.

        Gets a filtered list of initiator ports and target ports for each SAN
        available.
        :param initiator_list: list of initiator port WWN
        :param target_list: list of target port WWN
        :returns: device wwn map in following format

        .. code-block:: python

            {
                <San name>: {
                    'initiator_port_wwn_list':
                    ('200000051E55A100', '200000051E55A121'..)
                    'target_port_wwn_list':
                    ('100000051E55A100', '100000051E55A121'..)
                }
            }

        :raises Exception: when a lookup service implementation is not
                 specified in cinder.conf:fc_san_lookup_service
        """
        # Initialize vendor specific implementation of  FCZoneDriver
        if (self.configuration.fc_san_lookup_service):
            lookup_service = self.configuration.fc_san_lookup_service
            LOG.debug("Lookup service to invoke: " "%s", lookup_service)
            self.lookup_service = importutils.import_object(
                lookup_service, configuration=self.configuration)
        else:
            msg = _("Lookup service not configured. Config option for "
                    "fc_san_lookup_service needs to specify a concrete "
                    "implementation of the lookup service.")
            LOG.error(msg)
            raise exception.FCSanLookupServiceException(msg)
        try:
            device_map = self.lookup_service.get_device_mapping_from_network(
                initiator_list, target_list)
        except Exception as e:
            LOG.exception('Unable to get device mapping from network.')
            raise exception.FCSanLookupServiceException(e)
        return device_map
    def _get_switch_data(self, ssh_pool, cmd):
        utils.check_ssh_injection([cmd])

        with ssh_pool.item() as ssh:
            try:
                switch_data, err = processutils.ssh_execute(ssh, cmd)
            except processutils.ProcessExecutionError as e:
                msg = (_("SSH Command failed with error: '%(err)s', Command: "
                         "'%(command)s'") % {
                             'err': six.text_type(e),
                             'command': cmd
                         })
                LOG.error(msg)
                raise exception.FCSanLookupServiceException(message=msg)

        return switch_data
Пример #3
0
 def get_device_mapping_from_network(self, initiator_wwn_list,
                                     target_wwn_list):
     if not GlobalParams._is_normal_test:
         raise exception.FCSanLookupServiceException("Error")
     device_map = {}
     initiators = []
     targets = []
     for i in initiator_wwn_list:
         if (i in _initiator_ns_map[_fabric_wwn]):
             initiators.append(i)
     for t in target_wwn_list:
         if (t in _target_ns_map[_fabric_wwn]):
             targets.append(t)
     device_map[_fabric_wwn] = {
         'initiator_port_wwn_list': initiators,
         'target_port_wwn_list': targets
     }
     return device_map
Пример #4
0
 def _get_switch_data(self, cmd):
     stdin, stdout, stderr = None, None, None
     utils.check_ssh_injection([cmd])
     try:
         stdin, stdout, stderr = self.client.exec_command(cmd)
         switch_data = stdout.readlines()
     except paramiko.SSHException as e:
         msg = (_("SSH Command failed with error '%(err)r' "
                  "'%(command)s'") % {'err': str(e), 'command': cmd})
         LOG.error(msg)
         raise exception.FCSanLookupServiceException(message=msg)
     finally:
         if (stdin):
             stdin.flush()
             stdin.close()
         if (stdout):
             stdout.close()
         if (stderr):
             stderr.close()
     return switch_data
Пример #5
0
    def get_device_mapping_from_network(self, initiator_wwn_list,
                                        target_wwn_list):
        """Provides the initiator/target map for available SAN contexts.

        Looks up nameserver of each fc SAN configured to find logged in devices
        and returns a map of initiator and target port WWNs for each fabric.

        :param initiator_wwn_list: List of initiator port WWN
        :param target_wwn_list: List of target port WWN
        :returns: List -- device wwn map in following format

        .. code-block:: default

            {
                <San name>: {
                    'initiator_port_wwn_list':
                    ('200000051e55a100', '200000051e55a121'..)
                    'target_port_wwn_list':
                    ('100000051e55a100', '100000051e55a121'..)
                }
            }

        :raises Exception: when connection to fabric is failed
        """
        device_map = {}
        formatted_target_list = []
        formatted_initiator_list = []
        fabric_map = {}
        fabric_names = self.configuration.fc_fabric_names
        fabrics = None
        if not fabric_names:
            raise exception.InvalidParameterValue(
                err=_("Missing Fibre Channel SAN configuration "
                      "param - fc_fabric_names"))

        fabrics = [x.strip() for x in fabric_names.split(',')]
        LOG.debug("FC Fabric List: %s", fabrics)
        if fabrics:
            for t in target_wwn_list:
                formatted_target_list.append(fczm_utils.get_formatted_wwn(t))

            for i in initiator_wwn_list:
                formatted_initiator_list.append(
                    fczm_utils.get_formatted_wwn(i))

            for fabric_name in fabrics:
                fabric_ip = self.fabric_configs[fabric_name].safe_get(
                    'fc_fabric_address')

                # Get name server data from fabric and find the targets
                # logged in
                nsinfo = ''
                try:
                    LOG.debug("Getting name server data for "
                              "fabric %s", fabric_ip)
                    conn = self._get_southbound_client(fabric_name)
                    nsinfo = conn.get_nameserver_info()
                except exception.FCSanLookupServiceException:
                    with excutils.save_and_reraise_exception():
                        LOG.error(
                            "Failed collecting name server info from"
                            " fabric %s", fabric_ip)
                except Exception as e:
                    msg = _("SSH connection failed "
                            "for %(fabric)s with error: %(err)s") % {
                                'fabric': fabric_ip,
                                'err': e
                            }
                    LOG.error(msg)
                    raise exception.FCSanLookupServiceException(message=msg)

                LOG.debug("Lookup service:nsinfo-%s", nsinfo)
                LOG.debug("Lookup service:initiator list from "
                          "caller-%s", formatted_initiator_list)
                LOG.debug("Lookup service:target list from "
                          "caller-%s", formatted_target_list)
                visible_targets = [
                    x for x in nsinfo if x in formatted_target_list
                ]
                visible_initiators = [
                    x for x in nsinfo if x in formatted_initiator_list
                ]

                if visible_targets:
                    LOG.debug("Filtered targets is: %s", visible_targets)
                    # getting rid of the : before returning
                    for idx, elem in enumerate(visible_targets):
                        elem = str(elem).replace(':', '')
                        visible_targets[idx] = elem
                else:
                    LOG.debug("No targets are in the nameserver for SAN %s",
                              fabric_name)

                if visible_initiators:
                    # getting rid of the : before returning ~sk
                    for idx, elem in enumerate(visible_initiators):
                        elem = str(elem).replace(':', '')
                        visible_initiators[idx] = elem
                else:
                    LOG.debug(
                        "No initiators are in the nameserver "
                        "for SAN %s", fabric_name)

                fabric_map = {
                    'initiator_port_wwn_list': visible_initiators,
                    'target_port_wwn_list': visible_targets
                }
                device_map[fabric_name] = fabric_map
        LOG.debug("Device map for SAN context: %s", device_map)
        return device_map
Пример #6
0
    def initialize_connection(self, volume, connector):
        """Assigns the volume to a server.

        Assign any created volume to a compute node/host so that it can be
        used from that host.

        The  driver returns a driver_volume_type of 'fibre_channel'.
        The target_wwn can be a single entry or a list of wwns that
        correspond to the list of remote wwn(s) that will export the volume.
        Example return values:

            {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'encrypted': False,
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': '1234567890123',
                }
            }

            or

             {
                'driver_volume_type': 'fibre_channel'
                'data': {
                    'encrypted': False,
                    'target_discovered': True,
                    'target_lun': 1,
                    'target_wwn': ['1234567890123', '0987654321321'],
                }
            }


        Steps to export a volume on 3PAR
          * Create a host on the 3par with the target wwn
          * Create a VLUN for that HOST with the volume we want to export.

        """
        common = self._login()
        try:
            # we have to make sure we have a host
            host = self._create_host(common, volume, connector)
            target_wwns, init_targ_map, numPaths = \
                self._build_initiator_target_map(common, connector)
            # check if a VLUN already exists for this host
            existing_vlun = common.find_existing_vlun(volume, host)

            vlun = None
            if existing_vlun is None:
                # now that we have a host, create the VLUN
                nsp = None
                lun_id = None
                active_fc_port_list = common.get_active_fc_target_ports()

                if self.lookup_service:
                    if not init_targ_map:
                        msg = _("Setup is incomplete. Device mapping "
                                "not found from FC network. "
                                "Cannot perform VLUN creation.")
                        LOG.error(msg)
                        raise exception.FCSanLookupServiceException(msg)

                    for target_wwn in target_wwns:
                        for port in active_fc_port_list:
                            if port['portWWN'].lower() == target_wwn.lower():
                                nsp = port['nsp']
                                vlun = common.create_vlun(volume,
                                                          host,
                                                          nsp,
                                                          lun_id=lun_id)
                                if lun_id is None:
                                    lun_id = vlun['lun']
                                break
                else:
                    init_targ_map.clear()
                    del target_wwns[:]
                    host_connected_nsp = []
                    for fcpath in host['FCPaths']:
                        if 'portPos' in fcpath:
                            host_connected_nsp.append(
                                common.build_nsp(fcpath['portPos']))
                    for port in active_fc_port_list:
                        if (
                            port['type'] == common.client.PORT_TYPE_HOST and
                            port['nsp'] in host_connected_nsp
                        ):
                            nsp = port['nsp']
                            vlun = common.create_vlun(volume,
                                                      host,
                                                      nsp,
                                                      lun_id=lun_id)
                            target_wwns.append(port['portWWN'])
                            if vlun['remoteName'] in init_targ_map:
                                init_targ_map[vlun['remoteName']].append(
                                    port['portWWN'])
                            else:
                                init_targ_map[vlun['remoteName']] = [
                                    port['portWWN']]
                            if lun_id is None:
                                lun_id = vlun['lun']
                if lun_id is None:
                    # New vlun creation failed
                    msg = _('No new vlun(s) were created')
                    LOG.error(msg)
                    raise exception.VolumeDriverException(msg)
            else:
                vlun = existing_vlun

            info = {'driver_volume_type': 'fibre_channel',
                    'data': {'target_lun': vlun['lun'],
                             'target_discovered': True,
                             'target_wwn': target_wwns,
                             'initiator_target_map': init_targ_map}}

            encryption_key_id = volume.get('encryption_key_id', None)
            info['data']['encrypted'] = encryption_key_id is not None
            return info
        finally:
            self._logout(common)