创建 Nova v3 API 的 JSON Schema 定义

https://blueprints.launchpad.net/nova/+spec/v3-api-schema

完成 Nova v3 API 请求体的 JSON Schema 定义。

问题描述

Nova 包含大量的 RESTful API,但并非所有请求体的 API 参数都经过了完全验证。为了验证所有参数,已经使用 JSON Schema 库实现了一个 API 验证框架。之后,我们需要为每个 API 添加 JSON Schema 定义,但我们无法在 Icehouse 周期内完成它们。在 Juno 周期中,我们需要实现对 v2.1 API 的强验证,正如设计峰会上的讨论。这意味着我们需要为 v3 API 实现强验证,因为 v2.1 API 是在 v3 API 实现的基础上构建的。

提议的变更

每个 API 定义都应以以下方式添加

  • 在 ./nova/api/openstack/compute/schemas/v3/ 下创建定义文件。

  • 每个定义应使用 JSON Schema 描述。

  • 每个定义中的参数(type、minLength 等)可以从当前验证代码、DB 模式、单元测试、Tempest 代码等定义。

  • 尽可能重用 nova/api/validation/parameter_types.py 中现有的预定义参数类型(名称、主机名、布尔值等)。

备选方案

在 API 验证框架之前,我们需要将验证代码添加到每个 API 方法中,以临时的方式进行处理。这些更改会使 API 方法代码变得混乱,并且由于验证不完整,我们需要创建多个补丁。例如,“创建一个 flavor extraspec” API 在 Icehouse 中为了其验证被更改了两次

如果使用 JSON Schema 定义,可接受的请求格式将是明确的,并且我们无需在未来进行这种临时工作。

  • 为什么不使用 Pecan

    一些项目(Ironic、Ceilometer 等)使用 Pecan/WSME 框架实现,我们可以从这些框架中自动获取 API 文档。在 WSME 实现中,开发人员应该为每个 API 定义 API 参数。Pecan 可以使 API 路由(URL、METHOD)的实现更加容易。API 文档是从这些定义的组合中生成的。在 Icehouse 峰会上,Nova 团队决定选择 Pecan 作为 Nova v3 API 框架,并使用 JSONSchema 代替 WSME,因为 Nova 包含复杂的 API(API 扩展),而 WSME 无法覆盖它们。此外,Pecan 的实现(https://blueprints.launchpad.net/nova/+spec/v3-api-pecan)在开发中也存在困难,并且没有完成。因此,现在 Nova v3 API 使用 Nova 原始的 WSGI 框架和 JSONSchema 实现,我们无法使用 Pecan。

数据模型影响

REST API 影响

通过对每个 API 应用严格的验证,一些在 v2 API 中被接受的值将在 v3 API 中被拒绝。例如,这里选择“创建一个服务器”API 的服务器名称。服务器名称的字符串模式在 v2 API 中根本没有被验证。我们现在可以通过 v2 API 指定 UTF-8(非 ASCII)字符作为服务器名称。为了进行强/全面的验证,我们将预定义的参数类型“name”也应用于服务器名称。该类型仅允许“a-zA-Z0-9._-”作为字符串模式,并拒绝 UTF-8 字符。在最坏的情况下,我们可以放宽对名称的输入验证。

安全影响

更早期的输入验证将减少恶意用户输入利用安全漏洞的能力。

通知影响

其他最终用户影响

性能影响

Nova 将需要一些性能成本来进行这种全面的验证,因为对现在未经验证的 API 参数的检查将会增加。但是,我认为这是公共 REST API 所必需的成本,我们需要为此付出代价。

其他部署者影响

开发人员影响

实现新的 REST API 的开发人员需要在 API 实现中添加 JSON Schema 定义。

实现

负责人

主要负责人

oomichi

其他贡献者

aikawa takada-yuiko xu-haiwei

工作项

这项任务需要大量的补丁,进度管理是关键。它们在 https://etherpad.openstack.org/p/nova-v3-api-validation 上跟踪。现在,大多数 API 的实现已经完成,除了几个新的 API(instance-group 和 server-external-events),我们需要审查它们。

依赖项

  • 如果将 nova-network 移植到 v3 API,我们需要为其创建一些 JSON Schema 补丁。

测试

通过这种实现,我们需要从负面请求案例的角度改进单元测试覆盖率。当前的单元测试没有覆盖所有负面案例,我们将能够添加它们,因为使有效的请求格式变得清晰。此外,我们能够通过这项工作发现原始单元测试中的错误。我们在 Icehouse 中修复了一些单元测试错误

现在 Tempest 包含负面测试生成器。该生成器基于用 JSON Schema 描述的 API 定义自动运行负面测试。通过将此蓝图的 API 定义从 Nova 移植到 Tempest,我们也可以提高 Tempest 的测试覆盖率。

文档影响

从长远来看,我希望这些 API 定义也用于 API 规范文档的自动生成。我们可以获得可信的 API 文档,这对用户和开发人员来说会很好。作为第一步,我提交了从 API 定义生成 API 示例文件的蓝图。这超出了本描述的范围,但我将其作为有用的示例:https://blueprints.launchpad.net/nova/+spec/generate-api-sample-from-api-schema

  • 为什么不使用当前的模板文件

    API 示例是从固定格式的模板文件生成的

    {
        "evacuate": {
            "host": "%(host)s",
            "admin_password": "%(adminPass)s",
            "on_shared_storage": "%(onSharedStorage)s"
        }
    }
    

    API 开发人员应该编写这种模板文件来实施 API,并且他们应该从这些模板生成 API 示例文件。结果,API 实现审查有很多文件,有时这些文件在断开的缩进、不存在的参数(拼写错误等)方面存在错误。为了改善这种情况,我建议使用 JSONSchema 定义代替模板文件。之后,我们可以删除模板文件,并且审查将更加容易。

参考资料