在 V3 API 代码库上实现 v2.1 API

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

基于 v3 API 基础设施实现与 v2 兼容的 API。

问题描述

在 v3 API 开发中,我们改进了 API 基础设施,例如 API 插件加载、输入验证、策略检查等。此外,为了修复 v2 API 不一致的接口,我们对 Nova API 进行了大量的向后不兼容的更改(更改成功状态码、API 属性名称和 API URL)。这里有关于 v2 API 对用户、操作员和开发人员问题的全面描述:http://ozlabs.org/~cyeoh/V3_API.html

然而,关于 Nova 的未来以及同时支持 v2 和 v3 两个 API 所带来的维护开销,进行了大量的讨论。

提议的变更

经过大量的讨论,我们理解了 v3 API 基础设施的优势(API 插件加载、输入验证、策略检查等)。然而,它们向后不兼容的接口现在看起来有些过早,因为我们现在不确定当前的 v3 API 是否是最好的。这意味着即使切换到当前的 v3 API,我们也无法确定不再需要任何向后不兼容的更改。

本规范建议从 v3 代码中删除向后不兼容的更改。这意味着当前的 v3 一致接口将恢复到 v2 不一致的接口,例如

--- a/nova/api/openstack/compute/plugins/v3/servers.py
+++ b/nova/api/openstack/compute/plugins/v3/servers.py
@@ -752,7 +752,7 @@ class ServersController(wsgi.Controller):
The field image_ref is mandatory when no block devices have been
defined and must be a proper uuid when present.
"""
- image_href = server_dict.get('image_ref')
+ image_href = server_dict.get('imageRef')

这个提议对 v3 API 开发人员来说很痛苦,因为他们努力了一年多时间来创建一致的接口,而且 v3 接口实际上比 v2 接口更好。然而,通过讨论,我们了解到向后不兼容的更改对用户来说非常痛苦,我们必须关注这些更改。

在这个规范中,我们将提供与 v2 兼容的 API,同时具有其他 v3 优势,作为第一步。在此规范之后,我们将通过逐步定义 API 规则来提供一致的接口。这些规则将防止相同的向后不兼容的更改,并保持一致的接口,即使在将来添加大量新的 API。但是,这目前不在本规范的范围内。

我们也同意在初始 v2.1 实现中,不会为其他 OpenStack API(例如 glance、cinder 或 neutron)实现代理。这些将在稍后添加,但在删除原始 v2 代码之前。

备选方案

通过这些讨论,我们意识到可以在 v3 API 代码库之上同时支持 v2 API 和 v3 API。在这种想法下,nova 将 v2 请求转换为 v3 请求并将其传递给 v3 API 方法。在 v3 API 方法操作之后,nova 再次将 v3 响应转换为 v2 响应并将其返回给客户端。然而,也对此想法进行了大量的讨论,因为在长期内,当我们有很多向后不兼容的更改时,许多转换会使 API 问题的调试变得困难。

数据模型影响

REST API 影响

呈现的 V2.1 REST API 将与 V2 API 相同,除非另有说明。

但是,请注意,V2.1 不支持 V2 API 的 XML 版本,仅支持 JSON 版本。然而,V2 API 的 XML 版本目前被标记为已弃用。

安全影响

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

通知影响

其他最终用户影响

潜在地,如果 python novaclient 可以与 /v2.1 通信而不是 /v2,这可能是有利的,但可能不需要更改代码来实现这一点。通过 keystone 配置来完成可能更简单。API 本身保持不变。

性能影响

更严格的输入验证也意味着需要在 API 层完成更多的工作,但总体而言这是一件好事。

其他部署者影响

如果部署者想要将 API 作为 /v2 而不是 /v2.1 导出,他们需要修改 api-paste.ini 文件(几行更改以禁用原始 V2 API 并将 APIRouterV21 作为 /v2 API)。

长远目标是在部署者和用户对 v2.1 满足他们的要求感到满意时,弃用并最终删除原始 V2 API 代码。

我们将使用的流程是

  • V2.1 完全实现,并经过 Tempest 验证(包括添加的关于响应数据的额外验证)

  • 来自多个来源(云提供商、用户等)的验证,确认 V2.1 与 V2 兼容

    • 这可以通过多种方式完成

      • Keystone 更改,以便宣传 /v2.1 而不是 /v2

      • 将 V2.1 作为 /v2 导出

      • 结合将 V2.1 输入验证放入日志而不是拒绝模式的可能性。

  • V2.1 在 OpenStack 发布中存在 N 个版本

  • 在广泛确认 V2.1 API 兼容后,V2 将被标记为已弃用

开发人员影响

开发人员的长期优势是

  • 所有 API 实现都在新的 API 框架上

  • 减少支持两个主要 API 版本的维护开销

  • 拥有更好的框架来处理未来的向后不兼容的更改。

在短期内,虽然旧的 V2 API 代码存在,仍然会存在双重维护开销。

实现

负责人

主要负责人

cyeoh-0

其他贡献者

oomichi Alex Xu

工作项

  • 将 v3 成功状态码更改为 v2 的状态码。

  • 将 v3 API 路由更改为 v2 的路由。

    • 处理 API URL 包含项目 ID。

    • 更改 API 资源路径。(例如:/keypairs(v3) -> /os-keypairs(v2))

    • 更改操作名称。(例如:migrate_live(v3) -> os-migrateLive(v2))

  • 将 v3 API 属性名称更改为 v2 的名称。

    • 更改 v3 代码的 API 解析器。

    • 更改输入验证的 API 模式。

  • 更改 v3 API 行为为 v2 的行为。在某些 API 上,行为不同。例如,v3 “创建一个私有 flavor” API 会自动为其自身项目添加 flavor 访问权限,但 v2 不会。

以下工作项不是强制性的,它属于愿望清单。

  • 更改 v3 插件代码路径。例如

    nova/api/openstack/compute/plugins/v3/servers.py
    -> nova/api/openstack/compute/plugins/servers.py
    

依赖项

测试

Tempest 已经包含大量的 v2 API 测试,现在这是一个很好的测试覆盖率。对于这个 v2.1 API,我们需要并行运行 v2 API 测试,用于当前的 v2 和 v2.1。作为一个想法,我们将通过从现有的 v2 API 测试类继承并针对 /v2.1 执行它们来添加 v2.1 API 测试。已经提出了一个关于这个想法的规范

https://review.openstack.org/#/c/96661/

文档影响

由于 API 除了输入验证方面的改进外不会更改,因此 v2 API 的文档基本上与以前相同。在可能的错误状态码方面,需要进行一些更新。

从长远来看,改进的输入验证基础设施以及响应验证的 JSON 模式的开发将使自动生成 v2 文档更容易,而不是依赖当前主要手动流程。

参考资料