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