使用 ‘LIKE’ 操作符过滤资源¶
https://blueprints.launchpad.net/cinder/+spec/support-regexp-based-query
此蓝图建议修改某些过滤行为,在某些列(名称、描述等)上使用 ‘LIKE’ 表达式。
问题描述¶
目前,我们只能通过精确匹配来过滤 cinder 资源,当用户希望检索名称或属性部分相似的资源时,这不够灵活,特别是对于拥有大量卷的用户而言。正如在许多其他项目中已经介绍的那样,我们可以利用一些现有的机制,例如 nova 和 ironic。
用例¶
可能的用例是支持客户端批量操作,通过单个命令收集所需的资源。
提议的变更¶
虽然我们可以提供基于正则表达式过滤资源的功能,但我们可能会遇到 ReDos 攻击的风险。考虑到 ‘LIKE’ 操作符对于这种情况来说既灵活又安全。我们只能引入 ‘LIKE’ 操作符(‘NOT LIKE’ 是另一个有用的操作符,但它不如 ‘LIKE’ 常用)。我们可以很容易地将此过滤器单独应用于现有的通用过滤函数,使用装饰器
@apply_like_filters(model=models.Volume)
def _process_volume_filters(query, filters):
pass
此规范旨在支持在某些指定资源和列上基于 ‘LIKE’ 的过滤,由于我们将拥有通用的 资源过滤 功能,因此将利用该规范使其可配置,以便管理员进行配置,这是我们最终在过滤配置文件中将拥有的内容
{
"volume_filters": ["availability_zone", "status", "name~"]
}
这里的 ‘~’ 表示属性 ‘name’ 支持使用 like 操作符进行查询(不表示正则表达式操作符),一旦配置,API 中的键值对 name~=value 将最终被翻译成此 sql 语句
# '%' is automatically appended at both sides
SELECT * FROM volumes
WHERE name LIKE '%value%'
因此,在启用该开关后,最终用户可以使用以下输入过滤卷
cinder list --filters name=volume_preserved #exact matches
cinder list --filters name~=volume_preserved #inexact matches
假设我们有两个名称为 ‘volume_preserved_01’、‘volume_preserved_02’ 的卷,那么使用第一个命令我们将无法获得任何一个,而最后一个命令将获得两者。
备选方案¶
我们还可以部署 searchlight,它主要关注各种云资源查询,这是一个更广泛的话题。但我们也应该考虑没有 searchlight 的云环境。
此外,用户还可以收集所有原始数据并自行进行过滤,但显然我们试图避免这种情况,因为它会造成大量的资源浪费。
数据模型影响¶
无
REST API 影响¶
此更改需要 microversion 升级。
Cinder 客户端影响¶
将更新帮助文本以宣传此更改。
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
无
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
tommylikehu(tommylikehu@gmail.com)
工作项¶
更新通用的资源过滤逻辑,以接受配置文件中的新符号 ‘~’。
更新目标对象的通用过滤方法。
添加相关的单元测试用例
更新 cinder-client 和 OSC。
依赖项¶
依赖于通用的 资源过滤
测试¶
添加单元测试以覆盖过滤过程的更改。
文档影响¶
更新 API 文档。
参考资料¶
nova: https://review.openstack.org/#/c/45026/
ironic: https://review.openstack.org/#/c/266688/