def unmap_volume(self, volume_id, host_name): logger.debug("un-mapping volume : {0} from host : " "{1}".format(volume_id, host_name)) vol_name = self._get_vol_by_wwn(volume_id) cli_kwargs = { 'host': host_name, 'vdisk_id': vol_name } try: self.client.svctask.rmvdiskhostmap(**cli_kwargs) except (svc_errors.CommandExecutionError, CLIFailureError) as ex: if not is_warning_message(ex.my_message): logger.error(msg="Map volume {0} to host {1} failed. Reason " "is: {2}".format(vol_name, host_name, ex)) if NAME_NOT_MEET in ex.my_message: raise controller_errors.HostNotFoundError(host_name) if OBJ_NOT_FOUND in ex.my_message: raise controller_errors.VolumeNotFoundError(vol_name) if VOL_ALREADY_UNMAPPED in ex.my_message: raise controller_errors.VolumeAlreadyUnmappedError( vol_name) raise controller_errors.UnMappingError(vol_name, host_name, ex) except Exception as ex: logger.exception(ex) raise ex
def _get_next_available_lun(self, host_name): logger.debug( "getting host mapping list for host :{0}".format(host_name)) try: host_mapping_list = self.client.cmd.mapping_list( host=host_name).as_list except xcli_errors.HostBadNameError as ex: logger.exception(ex) raise controller_errors.HostNotFoundError(host_name) luns_in_use = set( [int(host_mapping.lun) for host_mapping in host_mapping_list]) logger.debug("luns in use : {0}".format(luns_in_use)) # try to use random lun number just in case there are many calls at the same time to reduce re-tries all_available_luns = [ i for i in range(self.MIN_LUN_NUMBER, self.MAX_LUN_NUMBER + 1) if i not in luns_in_use ] if len(all_available_luns) == 0: raise controller_errors.NoAvailableLunError(host_name) index = randint(0, len(all_available_luns) - 1) lun = all_available_luns[index] logger.debug("next random available lun is : {0}".format(lun)) return lun
def map_volume(self, volume_id, host_name): logger.debug("mapping volume : {0} to host : " "{1}".format(volume_id, host_name)) vol_name = self._get_volume_name_by_wwn(volume_id) cli_kwargs = {'host': host_name, 'object_id': vol_name, 'force': True} try: lun = self.get_first_free_lun(host_name) cli_kwargs.update({'scsi': lun}) self.client.svctask.mkvdiskhostmap(**cli_kwargs) except (svc_errors.CommandExecutionError, CLIFailureError) as ex: if not is_warning_message(ex.my_message): logger.error(msg="Map volume {0} to host {1} failed. Reason " "is: {2}".format(vol_name, host_name, ex)) if NAME_NOT_EXIST_OR_MEET_RULES in ex.my_message: raise array_errors.HostNotFoundError(host_name) if SPECIFIED_OBJ_NOT_EXIST in ex.my_message: raise array_errors.ObjectNotFoundError(vol_name) if LUN_ALREADY_IN_USE in ex.my_message: raise array_errors.LunAlreadyInUseError(lun, host_name) raise array_errors.MappingError(vol_name, host_name, ex) except Exception as ex: logger.exception(ex) raise ex return str(lun)
def get_host_by_host_identifiers(self, initiators): logger.debug( "Getting host name for initiators : {0}".format(initiators)) detailed_hosts_list = self._get_detailed_hosts_list() iscsi_host, fc_host = None, None for host in detailed_hosts_list: if initiators.is_array_iscsi_iqns_match(host.iscsi_names): iscsi_host = host.name logger.debug("found iscsi iqn in list : {0} for host : " "{1}".format(initiators.iscsi_iqn, iscsi_host)) if initiators.is_array_wwns_match(host.wwns): fc_host = host.name logger.debug("found fc wwns in list : {0} for host : " "{1}".format(initiators.fc_wwns, fc_host)) if iscsi_host and fc_host: if iscsi_host == fc_host: return fc_host, [ config.ISCSI_CONNECTIVITY_TYPE, config.FC_CONNECTIVITY_TYPE ] raise array_errors.MultipleHostsFoundError(initiators, fc_host) if iscsi_host: logger.debug("found host : {0} with iqn : {1}".format( iscsi_host, initiators.iscsi_iqn)) return iscsi_host, [config.ISCSI_CONNECTIVITY_TYPE] if fc_host: logger.debug("found host : {0} with fc wwn : {1}".format( fc_host, initiators.fc_wwns)) return fc_host, [config.FC_CONNECTIVITY_TYPE] logger.debug( "can not found host by using initiators: {0} ".format(initiators)) raise array_errors.HostNotFoundError(initiators)
def map_volume(self, volume_id, host_name): logger.debug("mapping volume : {0} to host : {1}".format( volume_id, host_name)) vol_name = self._get_object_name_by_wwn(volume_id) lun = self._get_next_available_lun(host_name) try: self.client.cmd.map_vol(host=host_name, vol=vol_name, lun=lun) except xcli_errors.OperationForbiddenForUserCategoryError as ex: logger.exception(ex) raise controller_errors.PermissionDeniedError( "map volume : {0} to host : {1}".format(volume_id, host_name)) except xcli_errors.VolumeBadNameError as ex: logger.exception(ex) raise controller_errors.ObjectNotFoundError(vol_name) except xcli_errors.HostBadNameError as ex: logger.exception(ex) raise controller_errors.HostNotFoundError(host_name) except xcli_errors.CommandFailedRuntimeError as ex: logger.exception(ex) if LUN_IS_ALREADY_IN_USE_ERROR in ex.status: raise controller_errors.LunAlreadyInUseError(lun, host_name) else: raise controller_errors.MappingError(vol_name, host_name, ex) return str(lun)
def unmap_volume(self, volume_id, host_name): logger.debug("Unmapping volume {} from host {}".format( volume_id, host_name)) try: mappings = self.client.get_host_mappings(host_name) lunid = None for mapping in mappings: if mapping.volume == volume_id: lunid = mapping.id break if lunid is not None: self.client.unmap_volume_from_host(host_name=host_name, lunid=lunid) logger.debug( "Successfully unmapped volume from host with lun {}.". format(lunid)) else: raise array_errors.ObjectNotFoundError(volume_id) except exceptions.NotFound as ex: if HOST_DOES_NOT_EXIST in str(ex.message).upper(): raise array_errors.HostNotFoundError(host_name) if MAPPING_DOES_NOT_EXIST in str(ex.message).upper(): raise array_errors.VolumeAlreadyUnmappedError(volume_id) except exceptions.ClientException as ex: raise array_errors.UnmappingError(volume_id, host_name, ex.details)
def test_publish_volume_map_volume_excpetions(self, enter): context = utils.FakeContext() self.mediator.map_volume.side_effect = [ array_errors.PermissionDeniedError("msg") ] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.PERMISSION_DENIED) self.mediator.map_volume.side_effect = [ array_errors.VolumeNotFoundError("vol") ] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) self.mediator.map_volume.side_effect = [ array_errors.HostNotFoundError("host") ] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND) self.mediator.map_volume.side_effect = [ array_errors.MappingError("", "", "") ] enter.return_value = self.mediator self.servicer.ControllerPublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.INTERNAL)
def unmap_volume(self, volume_id, host_name): logger.debug("un-mapping volume : {0} from host : {1}".format( volume_id, host_name)) vol_name = self._get_object_name_by_wwn(volume_id) try: self.client.cmd.unmap_vol(host=host_name, vol=vol_name) except xcli_errors.VolumeBadNameError as ex: logger.exception(ex) raise controller_errors.ObjectNotFoundError(vol_name) except xcli_errors.HostBadNameError as ex: logger.exception(ex) raise controller_errors.HostNotFoundError(host_name) except xcli_errors.OperationForbiddenForUserCategoryError as ex: logger.exception(ex) raise controller_errors.PermissionDeniedError( "unmap volume : {0} from host : {1}".format( volume_id, host_name)) except xcli_errors.CommandFailedRuntimeError as ex: logger.exception(ex) if UNDEFINED_MAPPING_ERROR in ex.status: raise controller_errors.VolumeAlreadyUnmappedError(vol_name) else: raise controller_errors.UnMappingError(vol_name, host_name, ex)
def get_host_by_host_identifiers(self, initiators): logger.debug("Getting host id for initiators : {0}".format(initiators)) matching_hosts_set = set() port_types = [] host_list = self.client.cmd.host_list().as_list for host in host_list: host_iscsi_ports = string_to_array(host.iscsi_ports, ',') host_fc_ports = string_to_array(host.fc_ports, ',') if initiators.is_array_wwns_match(host_fc_ports): matching_hosts_set.add(host.name) logger.debug("found host : {0}, by fc port : {1}".format( host.name, host_fc_ports)) port_types.append(FC_CONNECTIVITY_TYPE) if initiators.is_array_iscsi_iqns_match(host_iscsi_ports): matching_hosts_set.add(host.name) logger.debug("found host : {0}, by iscsi port : {1}".format( host.name, host_iscsi_ports)) port_types.append(ISCSI_CONNECTIVITY_TYPE) matching_hosts = sorted(matching_hosts_set) if not matching_hosts: raise controller_errors.HostNotFoundError(initiators) elif len(matching_hosts) > 1: raise controller_errors.MultipleHostsFoundError( initiators, matching_hosts) return matching_hosts[0], port_types
def get_host_by_host_identifiers(self, initiators): logger.debug("Getting host id for initiators : {0}".format(initiators)) host_list = self.client.svcinfo.lshost() iscsi_host, fc_host = None, None for host in host_list: host_detail = self.client.svcinfo.lshost( object_id=host.get('id', '')).as_single_element iscsi_names = host_detail.get('iscsi_name', '') wwns_value = host_detail.get('WWPN', []) if not isinstance(wwns_value, list): wwns_value = [wwns_value, ] if initiators.is_array_iscsi_iqns_match([iscsi_names]): iscsi_host = host_detail.get('name', '') logger.debug("found iscsi iqn in list : {0} for host : " "{1}".format(initiators.iscsi_iqn, iscsi_host)) if initiators.is_array_wwns_match(wwns_value): fc_host = host_detail.get('name', '') logger.debug("found fc wwns in list : {0} for host : " "{1}".format(initiators.fc_wwns, fc_host)) if iscsi_host and fc_host: if iscsi_host == fc_host: return fc_host, [config.ISCSI_CONNECTIVITY_TYPE, config.FC_CONNECTIVITY_TYPE] else: raise controller_errors.MultipleHostsFoundError(initiators, fc_host) elif iscsi_host: logger.debug("found host : {0} with iqn : {1}".format(iscsi_host, initiators.iscsi_iqn)) return iscsi_host, [config.ISCSI_CONNECTIVITY_TYPE] elif fc_host: logger.debug("found host : {0} with fc wwn : {1}".format(fc_host, initiators.fc_wwns)) return fc_host, [config.FC_CONNECTIVITY_TYPE] else: logger.debug("can not found host by using initiators: {0} ".format(initiators)) raise controller_errors.HostNotFoundError(initiators)
def _get_used_lun_ids_from_host(self, host_name): logger.debug("getting used lun ids for host :{0}".format(host_name)) luns_in_use = set() try: for mapping in self.client.svcinfo.lshostvdiskmap(host=host_name): luns_in_use.add(mapping.get('SCSI_id', '')) except (svc_errors.CommandExecutionError, CLIFailureError) as ex: logger.error(ex) raise array_errors.HostNotFoundError(host_name) logger.debug("The used lun ids for host :{0}".format(luns_in_use)) return luns_in_use
def get_node_id_info(node_id): logger.debug("getting node info for node id : {0}".format(node_id)) split_node = node_id.split(config.PARAMETERS_NODE_ID_DELIMITER) hostname, fc_wwns, iscsi_iqn = "", "", "" if len(split_node) == config.SUPPORTED_CONNECTIVITY_TYPES + 1: hostname, fc_wwns, iscsi_iqn = split_node elif len(split_node) == 2: hostname, fc_wwns = split_node else: raise array_errors.HostNotFoundError(node_id) logger.debug("node name : {0}, iscsi_iqn : {1}, fc_wwns : {2} ".format( hostname, iscsi_iqn, fc_wwns)) return hostname, fc_wwns, iscsi_iqn
def get_host_by_host_identifiers(self, initiators): logger.debug("Getting host by initiators: {}".format(initiators)) found = "" for host in self.client.get_hosts(): host_ports = host.host_ports_briefs wwpns = [p["wwpn"] for p in host_ports] if initiators.is_array_wwns_match(wwpns): found = host.name break if found: logger.debug("found host {0} with fc wwpns: {1}".format(found, initiators.fc_wwns)) return found, [config.FC_CONNECTIVITY_TYPE] logger.debug("can not found host by initiators: {0} ".format(initiators)) raise array_errors.HostNotFoundError(initiators)
def map_volume(self, volume_id, host_name, connectivity_type): logger.debug("Mapping volume {} to host {}".format(volume_id, host_name)) try: mapping = self.client.map_volume_to_host(host_name, volume_id) lun = scsilun_to_int(mapping.lunid) logger.debug("Successfully mapped volume to host with lun {}".format(lun)) return lun except exceptions.NotFound: raise array_errors.HostNotFoundError(host_name) except exceptions.ClientException as ex: if ERROR_CODE_MAP_VOLUME_NOT_ENOUGH_EXTENTS in str(ex.message).upper(): raise array_errors.NoAvailableLunError(volume_id) if ERROR_CODE_VOLUME_NOT_FOUND_FOR_MAPPING in str(ex.message).upper(): raise array_errors.ObjectNotFoundError(volume_id) raise array_errors.MappingError(volume_id, host_name, ex.details)
def test_unpublish_volume_get_host_by_host_identifiers_exception(self, enter): context = utils.FakeContext() self.mediator.get_host_by_host_identifiers = Mock() self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.MultipleHostsFoundError("", "")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertTrue("Multiple hosts" in context.details) self.assertEqual(context.code, grpc.StatusCode.INTERNAL) self.mediator.get_host_by_host_identifiers.side_effect = [array_errors.HostNotFoundError("")] enter.return_value = self.mediator self.servicer.ControllerUnpublishVolume(self.request, context) self.assertEqual(context.code, grpc.StatusCode.NOT_FOUND)
def get_array_fc_wwns(self, host_name=None): logger.debug("Getting the connected fc port wwpns for host {} from array".format(host_name)) try: host = self.client.get_host(host_name) wwpns = [port[LOGIN_PORT_WWPN] for port in host.login_ports if port[LOGIN_PORT_STATE] == LOGIN_PORT_STATE_ONLINE] logger.debug("Found wwpns: {}".format(wwpns)) return wwpns except exceptions.NotFound: raise array_errors.HostNotFoundError(host_name) except exceptions.ClientException as ex: logger.error( "Failed to get array fc wwpn. Reason is: {}".format(ex.details) ) raise ex
def get_node_id_info(node_id): logger.debug("getting node info for node id : {0}".format(node_id)) split_node = node_id.split(config.PARAMETERS_NODE_ID_DELIMITER) hostname, nvme_nqn, fc_wwns, iscsi_iqn = "", "", "", "" if len(split_node) == 4: hostname, nvme_nqn, fc_wwns, iscsi_iqn = split_node elif len(split_node) == 3: hostname, nvme_nqn, fc_wwns = split_node elif len(split_node) == 2: hostname, nvme_nqn = split_node else: raise array_errors.HostNotFoundError(node_id) logger.debug( "node name : {0}, nvme_nqn: {1}, fc_wwns : {2}, iscsi_iqn : {3} ". format(hostname, nvme_nqn, fc_wwns, iscsi_iqn)) return hostname, nvme_nqn, fc_wwns, iscsi_iqn
def map_volume(self, volume_id, host_name): logger.debug("Mapping volume {} to host {}".format( volume_id, host_name)) try: mapping = self.client.map_volume_to_host(host_name, volume_id) lun = scsilun_to_int(mapping.lunid) logger.debug( "Successfully mapped volume to host with lun {}".format(lun)) return lun except exceptions.NotFound: raise array_errors.HostNotFoundError(host_name) except exceptions.ClientException as ex: # [BE586015] addLunMappings Volume group operation failure: volume does not exist. if ERROR_CODE_VOLUME_NOT_FOUND_FOR_MAPPING in str( ex.message).upper(): raise array_errors.ObjectNotFoundError(volume_id) raise array_errors.MappingError(volume_id, host_name, ex.details)
def unmap_volume(self, volume_id, host_name): logger.debug("Unmapping volume {} from host {}".format( volume_id, host_name)) array_volume_id = get_volume_id_from_scsi_identifier(volume_id) try: mappings = self.client.get_host_mappings(host_name) lunid = None for mapping in mappings: if mapping.volume == array_volume_id: lunid = mapping.id break if lunid is not None: self.client.unmap_volume_from_host(host_name=host_name, lunid=lunid) logger.debug( "Successfully unmapped volume from host with lun {}.". format(lunid)) else: raise array_errors.VolumeNotFoundError(volume_id) except exceptions.NotFound: raise array_errors.HostNotFoundError(host_name) except exceptions.ClientException as ex: raise array_errors.UnMappingError(volume_id, host_name, ex.details)