Exemple #1
0
    def get_volume(self, name, volume_context=None, volume_prefix=""):
        logger.debug("Getting volume {} under context {}".format(
            name, volume_context))
        if not volume_context:
            logger.error(
                "volume_context is not specified, can not get volumes from storage."
            )
            raise array_errors.VolumeNotFoundError(name)

        volume_candidates = []

        if config.CONTEXT_POOL in volume_context:
            try:
                volume_candidates = self.client.get_volumes_by_pool(
                    volume_context[config.CONTEXT_POOL])
            except exceptions.NotFound as ex:
                if ERROR_CODE_RESOURCE_NOT_EXISTS in str(ex.message).upper():
                    raise array_errors.PoolDoesNotExist(
                        volume_context[config.CONTEXT_POOL], self.identifier)
                else:
                    raise ex

        for vol in volume_candidates:
            if vol.name == shorten_volume_name(name, volume_prefix):
                logger.debug("Found volume: {}".format(vol))
                return self._generate_volume_response(vol)

        raise array_errors.VolumeNotFoundError(name)
Exemple #2
0
    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
Exemple #3
0
    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_vol_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.VolumeNotFoundError(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" in ex.status:
                raise controller_errors.LunAlreadyInUseError(lun, host_name)
            else:
                raise controller_errors.MappingError(vol_name, host_name, ex)

        return str(lun)
    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 copy_to_existing_volume_from_snapshot(self, name, src_snap_name, src_snap_capacity_in_bytes,
                                           min_vol_size_in_bytes, pool=None):
     logger.debug(
         "Copy snapshot {0} data to volume {1}. Snapshot capacity {2}. Minimal requested volume capacity {3}".format(
             name, src_snap_name, src_snap_capacity_in_bytes, min_vol_size_in_bytes))
     try:
         logger.debug("Formatting volume {0}".format(name))
         self.client.cmd.vol_format(vol=name)
         logger.debug("Copying Snapshot {0} data to volume {1}.".format(name, src_snap_name))
         self.client.cmd.vol_copy(vol_src=src_snap_name, vol_trg=name)
         if min_vol_size_in_bytes > src_snap_capacity_in_bytes:
             min_vol_size_in_blocks = self._convert_size_bytes_to_blocks(min_vol_size_in_bytes)
             logger.debug(
                 "Increasing volume {0} size to {1} blocks.".format(name, min_vol_size_in_blocks))
             self.client.cmd.vol_resize(vol=name, size_blocks=min_vol_size_in_blocks)
     except xcli_errors.IllegalNameForObjectError as ex:
         logger.exception(ex)
         raise controller_errors.IllegalObjectName(ex.status)
     except xcli_errors.SourceVolumeBadNameError as ex:
         logger.exception(ex)
         raise controller_errors.SnapshotNotFoundError(src_snap_name)
     except (xcli_errors.VolumeBadNameError, xcli_errors.TargetVolumeBadNameError) as ex:
         logger.exception(ex)
         raise controller_errors.VolumeNotFoundError(name)
     except xcli_errors.OperationForbiddenForUserCategoryError as ex:
         logger.exception(ex)
         raise controller_errors.PermissionDeniedError("create vol : {0}".format(name))
    def get_volume(self, name, volume_context=None, volume_prefix=""):
        logger.debug("Getting volume {} under context {}".format(
            name, volume_context))
        if not volume_context:
            logger.error(
                "volume_context is not specified, can not get volumes from storage."
            )
            raise array_errors.VolumeNotFoundError(name)

        api_volume = self._get_api_volume_by_name(
            volume_name=name, pool_id=volume_context[config.CONTEXT_POOL])

        if api_volume:
            return self._generate_volume_response(api_volume)

        raise array_errors.VolumeNotFoundError(name)
 def _create_flashcopy(self,
                       source_volume_id,
                       target_volume_id,
                       options=None):
     logger.info(
         "creating FlashCopy relationship from '{0}' to '{1}'".format(
             source_volume_id, target_volume_id))
     source_volume_id = get_volume_id_from_scsi_identifier(source_volume_id)
     target_volume_id = get_volume_id_from_scsi_identifier(target_volume_id)
     if not options:
         options = []
     options.append(FLASHCOPY_PERMIT_SPACE_EFFICIENT_TARGET)
     try:
         api_flashcopy = self.client.create_flashcopy(
             source_volume_id=source_volume_id,
             target_volume_id=target_volume_id,
             options=options)
     except (exceptions.ClientError, exceptions.ClientException) as ex:
         if ERROR_CODE_ALREADY_FLASHCOPY in str(ex.message).upper():
             raise array_errors.SnapshotAlreadyExists(
                 target_volume_id, self.service_address)
         elif ERROR_CODE_VOLUME_NOT_FOUND_OR_ALREADY_PART_OF_CS_RELATIONSHIP in str(
                 ex.message).upper():
             raise array_errors.VolumeNotFoundError('{} or {}'.format(
                 source_volume_id, target_volume_id))
         else:
             raise ex
     if not self.validate_flashcopy(api_flashcopy.id):
         self._delete_flashcopy(api_flashcopy.id)
         logger.info("Flashcopy is not in a valid state")
         raise ValueError
     return self._get_api_volume_by_id(target_volume_id)
Exemple #8
0
    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)

        try:
            self.client.cmd.unmap_vol(host=host_name, vol=vol_name)
        except xcli_errors.VolumeBadNameError as ex:
            logger.exception(ex)
            raise controller_errors.VolumeNotFoundError(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 "The requested mapping is not defined" in ex.status:
                raise controller_errors.VolumeAlreadyUnmappedError(vol_name)
            else:
                raise controller_errors.UnMappingError(vol_name, host_name, ex)
    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_vol_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_MEET in ex.my_message:
                    raise controller_errors.HostNotFoundError(host_name)
                if SPECIFIED_OBJ_NOT_EXIST in ex.my_message:
                    raise controller_errors.VolumeNotFoundError(vol_name)
                if VOL_ALREADY_MAPPED in ex.my_message:
                    raise controller_errors.LunAlreadyInUseError(
                        lun, host_name)
                raise controller_errors.MappingError(vol_name, host_name, ex)
        except Exception as ex:
            logger.exception(ex)
            raise ex

        return str(lun)
    def setUp(self, connect):
        self.fqdn = "fqdn"
        self.mediator = XIVArrayMediator("user", "password", self.fqdn)
        self.mediator.client = Mock()

        self.mediator.get_volume = Mock()
        self.mediator.get_volume.side_effect = [
            array_errors.VolumeNotFoundError("vol")
        ]

        self.servicer = ControllerServicer(self.fqdn)

        self.request = Mock()
        caps = Mock()
        caps.mount = Mock()
        caps.mount.fs_type = "ext4"
        access_types = csi_pb2.VolumeCapability.AccessMode
        caps.access_mode.mode = access_types.SINGLE_NODE_WRITER

        self.request.volume_capabilities = [caps]

        self.pool = 'pool1'
        self.request.secrets = {
            "username": "******",
            "password": "******",
            "management_address": "mg"
        }
        self.request.parameters = {"pool": self.pool}
        self.capacity_bytes = 10
        self.request.capacity_range.required_bytes = self.capacity_bytes
        self.request.name = vol_name
 def _get_api_volume_by_id(self, volume_id, not_exist_err=True):
     try:
         volume = self.client.get_volume(volume_id)
         volume.flashcopy = self.get_flashcopies_by_volume(volume.id)
         return volume
     except exceptions.NotFound:
         if not_exist_err:
             raise array_errors.VolumeNotFoundError(volume_id)
Exemple #12
0
    def _get_vol_by_wwn(self, volume_id):
        vol_by_wwn = self.client.cmd.vol_list(wwn=volume_id).as_single_element
        if not vol_by_wwn:
            raise controller_errors.VolumeNotFoundError(volume_id)

        vol_name = vol_by_wwn.name
        logger.debug("found volume name : {0}".format(vol_name))
        return vol_name
Exemple #13
0
 def _get_cli_volume(self, volume_name_or_id, not_exist_err=True):
     try:
         cli_volume = self.client.svcinfo.lsvdisk(
             bytes=True, object_id=volume_name_or_id).as_single_element
         if not cli_volume and not_exist_err:
             raise controller_errors.VolumeNotFoundError(volume_name_or_id)
         return cli_volume
     except (svc_errors.CommandExecutionError, CLIFailureError) as ex:
         if not is_warning_message(ex.my_message):
             if (OBJ_NOT_FOUND in ex.my_message
                     or NAME_NOT_MEET in ex.my_message):
                 logger.info("volume not found")
                 if not_exist_err:
                     raise controller_errors.VolumeNotFoundError(
                         volume_name_or_id)
     except Exception as ex:
         logger.exception(ex)
         raise ex
 def _delete_flashcopy(self, flascopy_id):
     try:
         self.client.delete_flashcopy(flascopy_id)
     except exceptions.NotFound:
         raise array_errors.VolumeNotFoundError(flascopy_id)
     except exceptions.ClientException as ex:
         logger.error(
             "Failed to delete flascopy {} on array {}, reason is: {}".
             format(flascopy_id, self.identifier, ex.details))
         raise ex
    def _get_vol_by_wwn(self, volume_id):
        filter_value = 'vdisk_UID=' + volume_id
        vol_by_wwn = self.client.svcinfo.lsvdisk(
            filtervalue=filter_value).as_single_element
        if not vol_by_wwn:
            raise controller_errors.VolumeNotFoundError(volume_id)

        vol_name = vol_by_wwn.name
        logger.debug("found volume name : {0}".format(vol_name))
        return vol_name
    def get_volume(self, volume_name, volume_context=None, volume_prefix=""):
        logger.debug("Get volume : {}".format(volume_name))
        cli_volume = None
        try:
            cli_volume = self.client.svcinfo.lsvdisk(
                bytes=True, object_id=volume_name).as_single_element
        except (svc_errors.CommandExecutionError, CLIFailureError) as ex:
            if not is_warning_message(ex.my_message):
                if (OBJ_NOT_FOUND in ex.my_message
                        or NAME_NOT_MEET in ex.my_message):
                    logger.error("Volume not found")
                    raise controller_errors.VolumeNotFoundError(volume_name)
        except Exception as ex:
            logger.exception(ex)
            raise ex

        if not cli_volume:
            raise controller_errors.VolumeNotFoundError(volume_name)
        logger.debug("cli volume returned : {}".format(cli_volume))
        return self._generate_volume_response(cli_volume)
    def get_volume_name(self, volume_id):
        logger.debug("Searching for volume with id: {0}".format(volume_id))
        volume_id = get_volume_id_from_scsi_identifier(volume_id)
        try:
            api_volume = self.client.get_volume(volume_id)
        except exceptions.NotFound:
            raise array_errors.VolumeNotFoundError(volume_id)

        vol_name = api_volume.name
        logger.debug("found volume name : {0}".format(vol_name))
        return vol_name
Exemple #18
0
 def delete_volume(self, volume_id):
     logger.info("Deleting volume {}".format(volume_id))
     try:
         self.client.delete_volume(
             volume_id=get_volume_id_from_scsi_identifier(volume_id))
         logger.info("Finished deleting volume {}".format(volume_id))
     except exceptions.NotFound:
         raise array_errors.VolumeNotFoundError(volume_id)
     except exceptions.ClientException as ex:
         logger.error(
             "Failed to delete volume {} on array {}, reason is: {}".format(
                 volume_id, self.identifier, ex.details))
         raise array_errors.VolumeDeletionError(volume_id)
    def delete_volume(self, volume_id):
        logger.info("Deleting volume with id : {0}".format(volume_id))
        vol_name = self._get_vol_by_wwn(volume_id)

        try:
            self.client.cmd.vol_delete(vol=vol_name)
        except xcli_errors.VolumeBadNameError as ex:
            logger.exception(ex)
            raise controller_errors.VolumeNotFoundError(vol_name)

        except xcli_errors.OperationForbiddenForUserCategoryError as ex:
            logger.exception(ex)
            raise controller_errors.PermissionDeniedError("delete vol : {0}".format(vol_name))

        logger.info("Finished volume deletion. id : {0}".format(volume_id))
Exemple #20
0
    def get_volume(self, vol_name):
        logger.debug("Get volume : {}".format(vol_name))
        try:
            cli_volume = self.client.cmd.vol_list(
                vol=vol_name).as_single_element
        except xcli_errors.IllegalNameForObjectError as ex:
            logger.exception(ex)
            raise controller_errors.IllegalObjectName(ex.status)

        logger.debug("cli volume returned : {}".format(cli_volume))
        if not cli_volume:
            raise controller_errors.VolumeNotFoundError(vol_name)

        array_vol = self._generate_volume_response(cli_volume)
        return array_vol
Exemple #21
0
    def get_volume_mappings(self, volume_id):
        logger.debug("Getting volume mappings for volume id : "
                     "{0}".format(volume_id))
        vol_name = self._get_vol_by_wwn(volume_id)
        logger.debug("vol name : {0}".format(vol_name))
        try:
            mapping_list = self.client.svcinfo.lsvdiskhostmap(vdisk_name=vol_name)
            res = {}
            for mapping in mapping_list:
                logger.debug("mapping for vol is :{0}".format(mapping))
                res[mapping.get('host_name', '')] = mapping.get('SCSI_id', '')
        except(svc_errors.CommandExecutionError, CLIFailureError) as ex:
            logger.error(ex)
            raise controller_errors.VolumeNotFoundError(volume_id)

        return res
 def _create_similar_volume(self, target_volume_name, source_volume_name,
                            pool_id):
     logger.info(
         "creating target api volume '{0}' from source volume '{1}'".format(
             target_volume_name, source_volume_name))
     source_api_volume = self._get_api_volume_by_name(source_volume_name,
                                                      pool_id=pool_id)
     if not source_api_volume:
         raise array_errors.VolumeNotFoundError(source_volume_name)
     capabilities = {
         config.CAPABILITIES_SPACEEFFICIENCY: source_api_volume.tp
     }
     size_in_bytes = int(source_api_volume.cap)
     pool = source_api_volume.pool
     return self.create_volume(target_volume_name, size_in_bytes,
                               capabilities, pool)
Exemple #23
0
 def _delete_volume_by_name(self, volume_name, not_exist_err=True):
     logger.info("deleting volume with name : {0}".format(volume_name))
     try:
         self.client.svctask.rmvolume(vdisk_id=volume_name)
     except (svc_errors.CommandExecutionError, CLIFailureError) as ex:
         if not is_warning_message(ex.my_message):
             logger.warning(
                 "Failed to delete volume {}".format(volume_name))
             if (OBJ_NOT_FOUND in ex.my_message
                     or VOL_NOT_FOUND in ex.my_message) and not_exist_err:
                 raise controller_errors.VolumeNotFoundError(volume_name)
             else:
                 raise ex
     except Exception as ex:
         logger.exception(ex)
         raise ex
    def get_volume(self, volume_name, volume_context=None, volume_prefix=""):
        logger.debug("Get volume : {}".format(volume_name))
        try:
            cli_volume = self.client.cmd.vol_list(vol=volume_name).as_single_element
        except xcli_errors.IllegalNameForObjectError as ex:
            logger.exception(ex)
            raise controller_errors.IllegalObjectName(ex.status)

        logger.debug("cli volume returned : {}".format(cli_volume))
        if not cli_volume:
            raise controller_errors.VolumeNotFoundError(volume_name)

        if cli_volume.master_name:
            raise controller_errors.VolumeNameBelongsToSnapshotError(volume_name, self.endpoint)

        array_vol = self._generate_volume_response(cli_volume)
        return array_vol
    def delete_volume(self, volume_id):
        logger.info("Deleting volume with id : {0}".format(volume_id))
        vol_name = self._get_vol_by_wwn(volume_id)
        try:
            self.client.svctask.rmvolume(vdisk_id=vol_name)
        except (svc_errors.CommandExecutionError, CLIFailureError) as ex:
            if not is_warning_message(ex.my_message):
                logger.warning("Failed to delete volume {}".format(vol_name))
                if (OBJ_NOT_FOUND in ex.my_message
                        or VOL_NOT_FOUND in ex.my_message):
                    raise controller_errors.VolumeNotFoundError(vol_name)
                else:
                    raise ex
        except Exception as ex:
            logger.exception(ex)
            raise ex

        logger.info("Finished volume deletion. id : {0}".format(volume_id))
    def create_snapshot(self, name, volume_name, volume_context=None):
        logger.info("creating snapshot {0} from volume {1}".format(name, volume_name))

        try:
            cli_snapshot = self.client.cmd.snapshot_create(name=name, vol=volume_name).as_single_element
            logger.info("finished creating cli snapshot {0} from volume {1}".format(name, volume_name))
            return self._generate_snapshot_response(cli_snapshot)
        except xcli_errors.IllegalNameForObjectError as ex:
            logger.exception(ex)
            raise controller_errors.IllegalObjectName(ex.status)
        except xcli_errors.VolumeExistsError as ex:
            logger.exception(ex)
            raise controller_errors.SnapshotAlreadyExists(name, self.endpoint)
        except xcli_errors.VolumeBadNameError as ex:
            logger.exception(ex)
            raise controller_errors.VolumeNotFoundError(volume_name)
        except xcli_errors.OperationForbiddenForUserCategoryError as ex:
            logger.exception(ex)
            raise controller_errors.PermissionDeniedError(
                "create snapshot {0} from volume {1}".format(name, volume_name))
 def map_volume(self, volume_id, host_name):
     logger.debug("Mapping volume {} to host {}".format(
         volume_id, host_name))
     array_volume_id = get_volume_id_from_scsi_identifier(volume_id)
     try:
         mapping = self.client.map_volume_to_host(host_name,
                                                  array_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.VolumeNotFoundError(volume_id)
         else:
             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)
 def get_snapshot(self, snapshot_name, volume_context=None):
     logger.debug("Get snapshot : {} with context: {}".format(
         snapshot_name, volume_context))
     if not volume_context:
         logger.error(
             "volume_context is not specified, can not get volumes from storage."
         )
         raise array_errors.VolumeNotFoundError(snapshot_name)
     target_api_volume = self._get_api_volume_by_name(
         volume_name=snapshot_name,
         pool_id=volume_context[config.CONTEXT_POOL])
     if not target_api_volume:
         return None
     if not target_api_volume.flashcopy:
         logger.error(
             "FlashCopy relationship not found for target volume: {}".
             format(snapshot_name))
         raise array_errors.SnapshotNameBelongsToVolumeError(
             target_api_volume.name, self.service_address)
     flashcopy_rel = self._get_flashcopy(target_api_volume.flashcopy[0].id)
     source_volume_name = self.get_volume_name(
         flashcopy_rel.source_volume['id'])
     return self._generate_snapshot_response(target_api_volume,
                                             source_volume_name)
 def test_delete_volume_with_volume_not_found_error(self, ):
     self.delete_volume_returns_error(
         error=array_errors.VolumeNotFoundError("vol"),
         return_code=grpc.StatusCode.OK)