Beispiel #1
0
    def get_obj(self, path: str):
        """
        获取目录或对象

        :param path: 目录或对象路径
        :return:
            obj     # success
            None    # 不存在

        :raises: Error
        """
        na_md5 = get_str_hexMD5(path)
        model_class = self.get_obj_model_class()
        try:
            obj = model_class.objects.get(Q(na_md5=na_md5)
                                          | Q(na_md5__isnull=True),
                                          na=path)
        except model_class.DoesNotExist as e:
            return None
        except MultipleObjectsReturned as e:
            msg = f'数据库表{self.get_collection_name()}中存在多个相同的目录:{path}'
            logger.error(msg)
            raise exceptions.Error(message=msg)
        except Exception as e:
            msg = f'select {self.get_collection_name()},path={path},err={str(e)}'
            logger.error(msg)
            raise exceptions.Error(msg)

        return obj
Beispiel #2
0
def create_bucket(name: str,
                  user,
                  _id: int = None,
                  ceph_using: str = None,
                  pool_name: str = None):
    """
    创建存储桶

    :param name: bucket name
    :param user: user bucket belong to
    :param _id: bucket id
    :param ceph_using: 多ceph集群时,指定使用那个ceph集群
    :param pool_name: ceph pool name that bucket objects data storage
    """
    if not ceph_using and pool_name:
        raise exceptions.Error(message=f'指定"pool_name"时必须同时指定"ceph_using"')

    if not ceph_using:
        ceph_using = get_ceph_alias_rand()

    if pool_name:
        pools = get_ceph_poolnames(ceph_using)
        if pool_name not in pools:
            raise exceptions.Error(
                message=
                f'指定"pool_name"({pool_name})不在"ceph_using"({ceph_using})中')
    else:
        pool_name = get_ceph_poolname_rand(ceph_using)

    bucket_id = _id
    bucket_name = name
    if not _id:
        bucket_id = get_next_bucket_max_id()

    try:
        bucket = Bucket(id=bucket_id,
                        name=bucket_name,
                        ceph_using=ceph_using,
                        pool_name=pool_name,
                        user=user)
        bucket.save(force_insert=True)
    except Exception as e:
        raise exceptions.Error(
            message=f"create bucket metadata failed, {str(e)}.")

    col_name = bucket.get_bucket_table_name()
    bfm = BucketFileManagement(collection_name=col_name)
    model_class = bfm.get_obj_model_class()
    if not create_table_for_model_class(model=model_class):
        if not create_table_for_model_class(model=model_class):
            bucket.delete()
            delete_table_for_model_class(model=model_class)
            raise exceptions.Error(f"create bucket table failed.")

    return bucket
Beispiel #3
0
    def get_cur_dir_id(self, dir_path=None):
        """
        获得当前目录节点id
        :return:
            id: int     # 顶级目录时id=ROOT_DIR_ID

        :raises: Error,InvalidKey,SameKeyAlreadyExists,NoParentPath
        """
        if self.cur_dir_id:
            return self.cur_dir_id

        path = dir_path if dir_path else self._path
        # path为空,根目录为存储桶
        if path == '' or path == '/':
            return self.ROOT_DIR_ID

        path = self._hand_path(path)
        if not path:
            raise exceptions.InvalidKey(message='父路径无效')  # path参数有误

        try:
            obj = self.get_obj(path=path)
        except Exception as e:
            raise exceptions.Error(message=f'查询目录id错误,{str(e)}')

        if obj:
            if obj.is_dir():
                self.cur_dir_id = obj.id
                return self.cur_dir_id
            else:
                raise exceptions.SameKeyAlreadyExists(message='无效目录,同名对象已存在')

        raise exceptions.NoParentPath(message='目录路径不存在')
Beispiel #4
0
    def get_dir_or_obj_exists(self, name, check_path_exists: bool = True):
        """
        通过名称获取当前路径下的子目录或对象
        :param name: 目录名或对象名称
        :param check_path_exists: 是否检查当前路径是否存在
        :return:
            文件目录对象 or None
            raises: Exception   # 发生错误,或当前目录参数有误,对应目录不存在

        :raises: Error, NoParentPath
        """
        if check_path_exists:
            self.get_cur_dir_id()

        path = self.build_dir_full_name(name)
        try:
            dir_or_obj = self.get_obj(path=path)
        except Exception as e:
            raise exceptions.Error(message=f'查询目录id错误,{str(e)}')

        return dir_or_obj
Beispiel #5
0
def exception_handler(exc, context):
    """
    Returns the response that should be used for any given exception.
    """
    headers = {}

    if isinstance(exc, Http404):
        exc = exceptions.NotFound()
    elif isinstance(exc, PermissionDenied):
        exc = exceptions.AccessDenied()
    elif isinstance(exc, APIException):
        auth_header = getattr(exc, 'auth_header', None)
        if auth_header:
            headers['WWW-Authenticate'] = auth_header
        wait = getattr(exc, 'wait', None)
        if wait:
            headers['Retry-After'] = '%d' % wait

        if isinstance(exc, rf_exceptions.AuthenticationFailed):
            exc = exceptions.AuthenticationFailed(message=str(exc))
        elif isinstance(exc, rf_exceptions.NotAuthenticated):
            exc = exceptions.NotAuthenticated(message=str(exc))
        elif isinstance(exc, rf_exceptions.PermissionDenied):
            exc = exceptions.AccessDenied(message=str(exc))
        elif isinstance(exc, rf_exceptions.MethodNotAllowed):
            exc = exceptions.MethodNotAllowed()
        elif isinstance(exc, rf_exceptions.Throttled):
            exc = exceptions.Throttled(message=str(exc))
        else:
            exc = exceptions.Error(message=str(exc), status_code=exc.status_code)

    if isinstance(exc, exceptions.Error):
        set_rollback()
        return Response(data=exc.err_data(), status=exc.status_code, headers=headers)

    return None