面向用户资源的元数据¶
Launchpad蓝图
https://blueprints.launchpad.net/manila/+spec/metadata-for-share-resources
Manila 在其数据库中将用户拥有的有形技术资产存储为资源。这些资产包括文件共享、快照、访问控制规则、导出位置、共享网络和安全服务等。资源的设计旨在容纳机器和人类都可以区分的标识符,例如 ID、名称和描述。但是,这些标识符可能不足以或不够灵活地满足最终用户的需求,例如能够将资源标记为特定用途,或附加驱动某些自动化的标签。本规范提出了一种设计,允许用户修改所有面向用户的资源的元数据。
问题描述¶
最终用户与 manila API 交互以管理其共享文件系统存储资源。这些资源包括
共享
共享导出位置
共享访问规则
共享实例
共享实例导出位置
共享副本
共享副本导出位置
共享快照
共享组
共享组快照
安全服务
共享网络
共享网络子网
所有这些资源都可以通过 ID 识别。其中一些甚至允许将自由文本设置为名称和/或描述。自由文本通常很难构造、分解或查询,因此这些字段对人类来说更有用,而不是对机器来说。很多时候,用户希望能够存储更多的辅助上下文信息。
他们今天使用“元数据”来处理共享和访问规则的一种方式。元数据是一个术语,用于描述与某些数据关联的辅助信息。对于共享和访问规则,用户今天使用元数据作为灵活的键=值对来附加有用的可选/附加信息。对于上述其他资源,这种交互是不可能的。
元数据不仅对用户交互有帮助。它还可以为 manila 本身提供额外的表示空间。例如,该服务当前使用数据库对象来表示导出位置元数据,以向最终用户传达有关特定导出的有用提示,例如偏好和可访问性。此元数据由服务拥有,最终用户无法修改此元数据。
用例¶
用户可能希望使用元数据来存储上下文信息,例如
资源的用途,例如:“usedfor=fileserver”
有关配置器的详细信息,例如:“createdby=manila-csi”
分组信息,例如:“department=physics”
其他时间信息,例如:“last_audited=2020-12-24T00:22:29”
客户端的挂载点标签,例如:“fstag=website”
预计元数据交互在资源之间是统一且一致的,这使得构建基于这些 API 的自动化更容易。
提议的变更¶
将在 manila 的 API 模块中创建一个新的元数据控制器 mixin,所有面向用户的 API 控制器都可以继承该 mixin。此 mixin 将实现 API 处理程序代码以
获取资源元数据(检索所有元数据,或特定项目)
设置/取消设置所有资源元数据(创建、更新或删除键=值对形式的元数据项)
设置单个资源元数据项(更新特定的键=值对)
取消设置资源元数据项(删除特定的键=值对)
为了区分和保护服务拥有或仅管理员拥有的元数据,将有一个 ignore_keys 参数和忽略的键字典,以防止最终用户操纵这些元数据项。
备选方案¶
键值元数据的替代方案包括名称和描述字段。可以更新当前不支持名称和/或描述的资源,以包含这些字段。这种替代方案存在上述的不灵活性问题,并且不能涵盖所有用例。
我们也可以根据用户反馈一次添加一个元数据控制器,而不是为每个面向用户的资源添加元数据控制器。这也可以让我们单独测试每个元数据控制器并逐步构建。这没什么争议,但是,每个资源 API 更新都必须在新的微版本中进行,并且一次性进行而不是使用继承模式来涵盖通用代码会更昂贵。测试工作量很大,是不可避免的。
与其区分“用户”拥有的和“服务”拥有的元数据,我们可以允许最终用户修改所有元数据——甚至服务创建的数据。这样做可以简化用户交互,但是,它可能会损害服务并导致错误行为。
另一种选择是包含一个 user_modifiable 布尔字段到元数据中,或者引入细粒度的 RBAC。但是,这可能会产生过多的 RBAC 规则,这些规则可能是不必要的。如果这变成了一个用例,可以很容易地在提议的设计之上构建。
数据模型影响¶
为了存储资源元数据,需要新的表和相应的 ORM 模型。这些表将在数据库升级期间创建,并在数据库降级期间被取消和销毁。
现有元数据表(共享(“share_metadata”),导出位置(“share_instance_export_locations_metadata”)将被修改,以包含一个名为 deleted 的字符串属性。此属性的默认值为 False。
现有元数据表也将被修改,以将“id”字段的数据类型替换为长度为 36 的字符串,用于 UUID。这将是为了避免整数溢出并提供可扩展性。
元数据表的通用 ORM 模式如下(其中“Resource”是实际资源名称的占位符)
class ResourceMetadata(BASE, ManilaBase):
"""Represents a metadata key/value pair for a Resource."""
__tablename__ = 'resource_metadata'
id = Column(String(36), primary_key=True)
key = Column(String(255), nullable=False)
value = Column(String(1023), nullable=False)
resource_id = Column(String(36), ForeignKey('resources.id'), nullable=False)
deleted = Column(String(36), default='False')
resource = orm.relationship(Resource, backref="resource_metadata",
foreign_keys=resource_id,
primaryjoin='and_('
'ResourceMetadata.resource_id == Resource.id,'
'ResourceMetadata.deleted == "False)')
元数据项在被服务或最终用户取消设置时不会被软删除。除非资源已使用元数据查询,或请求了资源的详细视图,否则元数据表不会与资源一起加载。
REST API 影响¶
将为每个资源创建新的 API 端点来索引元数据、显示元数据项、创建元数据、更新元数据项、更新所有元数据(删除所有现有元数据并使用请求的元数据更新)以及删除元数据项。这些 API 的一般结构如下
索引元数据¶
以 JSON 格式检索所有元数据键=值对
GET /v2/{resource}/metadata
示例请求体:null
成功代码: 200
默认 API 策略角色:项目读取者
错误代码:401(未授权),403(策略未授权),404(无效资源)
示例响应体:
{ "metadata": { "project": "my_app", "aim": "doc" } }
显示特定元数据项¶
检索单个元数据键=值对
GET /v2/{resource}/metadata/{key}
示例请求体:null
成功代码: 200
默认 API 策略角色:项目读取者
错误代码:401(未授权),403(策略未授权),404(无效资源)
示例响应体:
{ "metadata": { "project": "my_app", } }
更新所有元数据¶
使用更新后的集合替换所有元数据,也可以用于删除所有元数据
PUT /v2/{resource}/metadata
示例请求体:
{ "metadata": { "aim": "changed_doc", "project": "my_app", "new_metadata_key": "new_information" } }
成功代码: 200
默认 API 策略角色:项目成员
错误代码:401(未授权),403(策略未授权),404(无效资源),400(格式错误的请求)
示例响应体:
{ "metadata": { "aim": "changed_doc", "project": "my_app", "new_metadata_key": "new_information" } }
注意: 如果请求者不是系统或项目管理员,则属于仅管理员字典的元数据键将不会被删除和更新。
更新特定元数据项¶
更新特定的元数据项,其余保持不变
POST /v2/{resource}/metadata/{key}
示例请求体:
{ "metadata": { "aim": "updated_doc", } }
成功代码: 200
默认 API 策略角色:项目成员
错误代码:401(未授权),403(策略未授权),404(无效资源),400(格式错误的请求)
示例响应体:
{ "metadata": { "aim": "updated_doc", "project": "my_app", "new_metadata_key": "new_information" } }
重要
当前,POST /v2/{share}/metadata API 期望一个 meta 对象。但是,其他元数据 API 期望一个 metadata 对象。为了保持一致性,此错误将在新的 API 微版本中修复。
删除特定元数据项¶
硬删除单个元数据键=值对
DELETE /v2/{resource}/metadata/{key}
示例请求体:null
成功代码: 200
默认 API 策略角色:项目成员
错误代码:401(未授权),403(策略未授权),404(无效资源)
示例响应体:null
按元数据项查询资源¶
客户端可以执行 URL 编码
GET /v2/{resource}?metadata=%7B%27foo%27%3A%27bar%27%2C%27clemson%27%3A%27tigers%27%7D
或者请求也可以以解码格式进行。
GET /v2/{resource}?metadata={'foo':'bar','clemson':'tigers'}
驱动程序影响¶
无。元数据操作直接在 manila 数据库上执行,共享文件系统后端驱动程序在创建、修改或删除资源元数据期间不会被调用。
安全影响¶
建议对元数据操作进行速率限制,以防止恶意行为者或自动化向资源添加大量元数据项。
通知影响¶
无
其他最终用户影响¶
Python-manilaclient SDK 将包含对新 API 的支持,我们将确保新的 OSC 插件 shell 中有相应的 CLI 命令。Manila UI 对共享、导出位置和访问规则元数据的支持有限。本规范不寻求解决所有 UI 差距;但将尽一切努力缩小 CLI 工具和 UI 之间的功能差距。最终用户将能够通过 UI 执行所有元数据交互。
性能影响¶
API 性能可能会因资源查询包含元数据项而受到影响。由于我们将与资源的 detail 检索一起提供元数据,因此这些 API 的性能也会受到负面影响,因为需要新的数据库连接。随着共享数量和元数据表数量的增长,性能下降可能会很严重。这种影响将被记录;作为最佳实践,建议资源最多只有几个元数据项。
其他部署者影响¶
引入的新 API 可能需要调整策略文件,如果默认 RBAC 策略不可接受。
开发人员影响¶
在添加任何新的面向用户的元数据时,开发人员可以继承并扩展元数据 mixin 控制器。
实现¶
负责人¶
- 主要负责人
ashrod98 <ashrod98@gmail.com>
- 其他贡献者
gouthamr
工作项¶
添加数据库迁移以将共享、导出位置和访问规则元数据的
id字段从整数转换为字符串,并使用 UUID 填充该字段添加数据库迁移以在共享、导出位置和访问规则元数据表中引入“deleted”字段。
添加数据库迁移以创建所有其他资源的新的元数据表
添加
MetadataControllerMixin,继承并在所有资源中扩展,并提升 API 微版本。添加单元和集成测试
在 manilaclient SDK 中添加对元数据 API 的支持,并在 OSC CLI 和 SDK 中添加支持
在 UI 中添加对元数据交互的支持
添加文档
此 API 的进一步增强是为管理员提供创建仅管理员元数据值的接口。当前,仅管理员元数据值在 manila/manila/common/constants.py 中的字典中定义。这种固定的列表足以实现根据共享亲和力进行调度的后端过滤。为了实现此自定义,我们可以重新调整数据模型,以包含一个仅管理员布尔值,用于标识哪些键可由管理员或非管理员调整。或者,我们可以在 manila/manila/data/ 中提供一些配置选项。这种增强需要进一步考虑,可以在以后实施。
依赖项¶
不是直接依赖项,但此 API 更改包含实现此规范所需的元数据更改:亲和力和反亲和力调度器过滤器
测试¶
将编写广泛的单元测试来测试添加的 API 和数据库方法。将为所有数据库更改添加数据库“walk migrations”测试。Tempest 测试将添加到资源中,以涵盖新的元数据操作。
文档影响¶
API 参考
最终用户指南
发布说明