针对卷查询的通用过滤支持

https://blueprints.launchpad.net/cinder/+spec/db-volume-filtering

卷数据库 API 的过滤支持不一致。例如,查询所有卷和按项目查询卷时都支持过滤。但是,按主机或组查询卷时不支持过滤。

问题描述

数据库函数可以获取所有卷、获取特定项目中的所有卷、获取特定组中的所有卷以及获取托管在特定主机上的所有卷。请参阅数据库 API 中的以下函数:

  • volume_get_all

  • volume_get_all_by_project

  • volume_get_all_by_group

  • volume_get_all_by_host

只有获取所有卷和按项目获取所有卷的查询支持额外的过滤。

此蓝图的目的是使这些 API 之间的过滤支持保持一致。

用例

提议的变更

当前的卷过滤逻辑已经封装在通用的 _generate_paginate_query 函数中。过滤需要移动到一个通用函数(例如 _process_volume_filters),该函数将使用过滤信息更新模型查询对象。

然后,例如,volume_get_all_by_host 可以这样使用它:

def volume_get_all_by_host(context, host, filters=None):
    """Retrieves all volumes hosted on a host."""
    if host and isinstance(host, basestring):
        session = get_session()
        with session.begin():
            host_attr = getattr(models.Volume, 'host')
            conditions = [host_attr == host,
                          host_attr.op('LIKE')(host + '#%')]
            query = _volume_get_query(context).filter(or_(*conditions))
            if filters:
                query = _process_volume_filters(query, filters)
                if not query:
                    return None
            return query.all()
    elif not host:
        return []

备选方案

与其将过滤支持添加到其他卷 API,调用者可以简单地使用定义主机或组信息的过滤器调用 volume_get_all API。这种方法的缺点是它要求调用者了解如何构建该查询;这对于主机 API 尤其成问题,因为过滤器实际上是

  • 给定主机的精确字符串匹配

  • 一个 REGEX 匹配,其中主机匹配“<host>#<pool>”形式的值

数据模型影响

REST API 影响

安全影响

通知影响

其他最终用户影响

性能影响

复杂的数据库过滤器可能会影响查询性能;但是,这已经存在于 volume_get_all 和 volume_get_all_by_project API 中。

其他部署者影响

开发人员影响

实现

负责人

主要负责人

Steven Kaufer (kaufer)

其他贡献者

工作项

  • 将 sqlalchemy 数据库 API 中的卷过滤逻辑重构到一个通用函数中,并从现有的 _generate_paginate_query 函数中调用它

  • 更新按主机和组获取卷的函数,以使用通用的过滤函数

依赖项

测试

由于将使用通用的过滤处理所有卷数据库查询,现有的测试覆盖率就足够了。

文档影响

参考资料