风味附加规格验证器

https://blueprints.launchpad.net/nova/+spec/flavor-extra-spec-validators

引入一种描述和验证风味附加规格的机制。

问题描述

风味附加规格是 nova 中一个比较混乱的部分。我们希望解决以下几个问题

  • 许多风味附加规格缺乏文档说明 [1]。虽然 Glance 有 metadefs [2],但这些通常是过时的、不完整的,并且无法从 nova 和我们的用户文档中获取。

  • 如果在附加规格中输入错误,则不会发出警告或错误,导致行为与预期不符。

  • 没有定义的方法来弃用风味附加规格,导致重复造轮子。

用例

  • 作为部署者,我希望了解可用的风味附加规格和镜像元数据属性,以及为什么我想使用它们。

  • 作为部署者,我希望 nova 在我使用了不存在或拼写错误的风味附加规格时告诉我。

  • 作为开发者,我希望有一种简单的方法来弃用风味附加规格,如果我们在 placement 中建模 NUMA 时,这将变得越来越普遍。

  • 作为文档编写者,我希望能够交叉引用各种可用的风味附加规格和镜像元数据属性。

提议的变更

风味附加规格是一个键值对。例如

hw:cpu_policy=dedicated

验证附加规格的部分与部分需要不同的解决方案。此规格旨在解决两者的验证问题,但是,以下内容不在此次变更的范围内

  • 强制执行附加规格依赖关系。例如,如果附加规格 A 要求先配置附加规格 B。我们将记录依赖关系,但不会强制执行。

    注意

    在大多数情况下,这已经由 virt 驱动程序处理,但发生的时间比此规格建议的时间晚得多。

  • 强制执行 virt 驱动程序依赖关系。不幸的是,虽然风味附加规格应该是通用的,但事实并非总是如此。如上所述,我们将记录此依赖关系,但不会强制执行。

此变更建立在 风味附加规格镜像元数据验证 之上,该验证涵盖了我们的一些问题。

值验证

值验证是这两个问题中更容易解决的一个。它将以通用方式解决以下问题

hw:cpu_policy=deddddicated

对于通用的附加规格,验证器的定义需要包含以下内容

  • 附加规格的名称或,例如,上述示例中的 hw:cpu_policy。这必须是可模式化的,以处理例如 hw:numa_cpus.{id}

  • 附加规格的描述。

  • 附加规格的支持状态。

  • 有效值;无论是整数、布尔值、匹配给定正则表达式或模式的字符串、枚举,还是其他任何内容

  • virt 驱动程序依赖关系;这仅用于文档目的,不会强制执行

  • 附加规格依赖关系;这仅用于文档目的,不会强制执行

对于在树内代码中定义的任何附加规格,我们建议也在树内维护定义。为此,我们建议添加一个新模块,nova.api.validation.extra_specs,它将包含风味验证器的定义。这些将使用 Python 对象定义。

例如

numa_node = base.ExtraSpecValidator(
    name='hw:numa_nodes',
    description=(
        'The number of virtual NUMA nodes to allocate to configure the '
        'guest with. Each virtual NUMA node will be mapped to a unique '
        'host NUMA node. Only supported by the libvirt virt driver.'
    ),
    value={
        'type': int,
        'description': 'The number of virtual NUMA nodes to allocate',
        'min': 1,
    },
)

numa_cpu = base.ExtraSpecValidator(
    name='hw:numa_cpu.{id}',
    description=(
        'A mapping of **guest** CPUs to the **guest** NUMA node '
        'identified by ``{id}``. This can be used to provide asymmetric '
        'CPU-NUMA allocation and is necessary where the number of guest '
        'NUMA nodes is not a factor of the number of guest CPUs.'
    ),
    parameters=[
        {
            'name': 'id',
            'type': int,
            'description': 'The ID of the **guest** NUMA node.',
        },
    ],
    value={
        'type': str,
        'description': (
            'The guest CPUs, in the form of a CPU map, to allocate to the '
            'guest NUMA node identified by ``{id}``.'
        ),
        'pattern': r'\^?\d+((-\d+)?(,\^?\d+(-\d+)?)?)*',
    },
)

除了在树内定义的附加规格之外,操作员还可以定义自己的附加规格,这些附加规格将由例如自定义调度器过滤器使用。对于这些,我们建议提供一个入口点,通过该入口点操作员可以定义自己的自定义定义。此入口点应指向一个附加规格验证器列表。这些将比树内定义具有较低的优先级。这预计不会造成很大的负担,因为操作员已经需要为自定义调度器过滤器提供一个包,并且将提供文档来帮助用户添加这些。

例如

nova.extra_spec_validators =
    custom_scheduler = custom.scheduler.extra_spec_validators:VALIDATORS
VALIDATORS = [
    base.ExtraSpecValidator(
        name='foo:bar',
        description='A custom, out-of-tree validator'
        value={
            'type:' bool,
            'description' 'Whether to allow the instance to do something',
        }
    ),
]

无论附加规格验证器的来源如何,它们都将由 flavors/{flavor_id}/os-extra_specs API 使用。将为此 API 引入一个微版本,以避免破坏意外设置错误值的现有工具。

键验证

我们还希望能够捕获无效的附加规格本身。它将以通用方式解决以下问题

hw:cpu_pollllicy=dedicated

这涉及维护一个所有有效附加规格的注册表。鉴于我们使用正则表达式来定义附加规格名称并通过入口点提供自定义附加规格验证器,我们预计将有足够的权限来实现这一点。但是,在某些情况下,操作员可能希望禁用或绕过此验证。为此,我们将向 flavors/{flavor_id}/os-extra_specs API 添加一个新的 validation 查询参数。这将接受三个可能的值

strict(默认值)

对于具有无效值或我们没有验证器的附加规格的请求,将以 HTTP 400 响应被拒绝。

permissive

对于具有无效值的附加规格的请求,将以 HTTP 400 响应被拒绝。对于未注册的附加规格的请求,将被记录但允许。

off

禁用验证。不会发生任何记录。

所有其他值将被拒绝。

其他变更

我们还建议添加工具来 (a) 从定义中渲染 reStructuredText 文档,以及 (b) 将定义转换为 Glance 元数据定义文件。这两个工具都将位于 nova 树中,使我们能够保持这些内容的唯一事实来源。

备选方案

  • 我们可以忽略上述一些问题,并尝试以一种分块的方式解决其他问题。这可能更加繁琐和耗时,因为需要在更多的地方进行修改。

  • 我们可以引入一个配置选项来切换严格的 API 验证,而不是或除了 API 微版本之外。这引入了一种由配置驱动的 API 行为的新示例,而我们正在努力从 nova 中删除这种行为。它也是不必要的,因为使用微版本或 validation 查询参数允许用户在绝对必要时继续使用旧行为。

  • 我们可以最初为无效的键记录警告,并在后续版本中引入 API 更改。这不必要,因为使用微版本或 validation 查询参数允许用户在绝对必要时继续使用旧行为。

  • 我们可以为每个引入的新附加规格引入一个新的 API 微版本。这将非常繁琐,仅适用于树内附加规格,并且总体而言是不必要的。

  • 我们可以不添加 validate 查询参数,而是坚持要求所有附加规格都已注册。但是,此验证旨在帮助操作员,而不是伤害他们,并且人们可能出于某些原因想要绕过此验证。

  • 我们可以使用 YAML 文件来描述树外附加规格,而不是自定义 Python 对象。但是,这容易受到意外篡改,并迫使人们学习多种配置方式。

数据模型影响

无。

REST API 影响

我们将向 flavors/{flavor_id}/os-extra_specs API 添加一个 API 微版本,以在无效的风味附加规格上返回 HTTP 400。我们还将添加对 validation 查询参数的支持,以在必要时部分或完全禁用此行为。

安全影响

无。

通知影响

无。

其他最终用户影响

最终用户将获得有关可用风味附加规格和镜像元数据属性的更好的文档。

性能影响

无。

其他部署者影响

操作员现在需要使用自定义验证器来描述部署中使用的任何自定义风味附加规格,否则在使用新的 API 微版本且未设置 validation 参数时会看到错误。

开发人员影响

开发者现在应将新的风味附加规格添加到 nova.api.validation.extra_specs 模块,以利用可用的验证功能。

升级影响

具有树外调度器过滤器或 virt 驱动程序的运营商可能需要将附加规格验证器添加到他们的包中。

实现

负责人

主要负责人

stephenfinucane

其他贡献者

功能联络人

stephenfinucane

工作项

  1. 为所有树内风味附加规格生成附加规格定义。

  2. 添加基于入口点的加载机制,用于自定义附加规格,并记录操作员如何使用它。

  3. 添加一个新的 API 微版本和代码来验证用户提供的风味附加规格和这些定义。

  4. 添加一个 Sphinx 扩展来将此规格渲染为文档,以及另一个工具将规格转换为 Glance 元数据定义。

  5. 添加一个工具来生成与 glance-metadef 兼容的 JSON 文件,这些文件可以被 glance 元数据定义目录 API 消耗。

依赖项

无。

测试

单元测试。

文档影响

将通过 Sphinx 的强大功能提供更好的文档。我们需要记录操作员如何为他们的自定义附加规格开发验证器。

参考资料

历史

修订版

发布名称

描述

Train

引入

Ussuri

重新提出,名称更简单,并进行了重大修改