面向用户资源的元数据

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 参考

  • 最终用户指南

  • 发布说明

参考资料