ETSI NFV-SOL 多版本设计

https://blueprints.launchpad.net/tacker/+spec/multi-version-api

本规范提出了一种新的基于 ETSI NFV-SOL 的 Tacker 实现设计,以支持 ETSI NFV Release2、3 和 4 的多个版本。API 版本在 ETSI NFV-SOL 文档中描述。在 Release 3 中,VNF 生命周期管理接口 SOL003 v2.6.1 [1] 被定义为“1.3.0”,并在 v3.3.1 [2] 中升级到“2.0.0”。

问题描述

ETSI NFV Release3 和 4 文档已经发布,而 Tacker 目前仅支持基于 Release2 的实现,使用 ETSI NFV-SOL v2.6.1 [1]。在 Release4 中,关于云原生功能 (CNF) 的许多扩展正在讨论中。为了支持这些新的规范,Tacker 需要一种新的设计来支持其 API 上的多个版本。

提议的变更

为了支持多版本 API,Tacker 需要进行以下更改

  1. 符合 ETSI NFV SOL013 v3.4.1 [3] 的 HTTP 头部字段

    • 请求头部字段

    • 响应头部字段

  2. 符合 ETSI NFV SOL013 v3.4.1 [3] 的 ApiVersionInformation

    • VNF 生命周期管理 (/vnflcm)

    • VNF 包管理 (/vnfpkgm)

  3. 控制器中的主/次版本支持

    • 模式验证

    • VnfInstances (/vnflcm/{v1 或 v2}/vnf_instances)

    • VnfLcmOpOccs (/vnflcm/{v1 或 v2}/vnf_lcm_op_occs)

    • 订阅 (/vnflcm/{v1 或 v2}/subscriptions)

  4. Conductor 中的主/次版本支持

    • Conductor 服务器调用多版本驱动程序

    • VnflcmDriver

    • OpenStack InfraDriver

    • Kubernetes InfraDriver

  5. 数据库中的主/次版本支持

    • 对象

    • SQLAlchemy

操作设计

以下是多版本 API 设计的工作流程图

     +----------+
     | Request  |
     | Response |
     |          |
     +--+-------+
        |
+-------+--------------------------------------+
|       |                        Tacker-server |
|    +--v------------------+                   |
|    | Schema validation   |                   |
|    |  * VNF Lifecycle    |                   |
| +--+                     |                   |
| |  +---------------------+                   |
| |  +---------------------+   +-------------+ |
| +->| VNF Lifecycle       |   | ApiVersion  | |
|    |  vnflcm/{v1 or v2}  |   |  /vnflcm    | |
|    |   /vnf_instances    |   |  /vnfpkgm   | |
|    |   /vnf_lcm_op_occs  |   |             | |
|    |   /subscriptions    |   +-------------+ |
|    |                     |                   |
|    +--+------------------+                   |
|       |                                      |
+-------+--------------------------------------+
        |
+-------+--------------------------------------+
|       |                     Tacker-conductor |
|    +--v--------------+                       |
|    | Conductor       |                       |
| +--+                 |                       |
| |  +-----------------+                       |
| |  +-----------------+   +-----------------+ |     +-----------------+
| +->| VnflcmDriverV1  +-->| InfraDriverV1   +-+--+->| OpenStack VIM   |
| |  |                 |   |                 | |  |  |                 |
| |  +-----------------+   +-----------------+ |  |  +-----------------+
| +->| VnflcmDriverV2  +-->| InfraDriverV2   +-+--+->| Kubernetes VIM  |
|    |                 |   |                 | |     |                 |
|    +-----------------+   +-----------------+ |     +-----------------+
|                                              |
+----------------------------------------------+

请求/响应头部字段

请求和响应头部字段的规范在 ETSI NFV-SOL013 v3.4.1 [3] 的第 4.2 节中定义。Tacker 已经具有其请求和响应类,但并非支持所有必需的字段。

请求类需要以下头部字段

头部字段名称

描述

Accept

响应可接受的内容类型。如果响应预期具有非空消息体,则此头部字段必须存在。

Content-Type

请求体的 MIME 类型。如果请求具有非空消息体,则此头部字段必须存在。

Authorization

请求的授权令牌。

Range

从文件中请求的字节范围。

版本

响应此请求时请求使用的 API 版本。

响应需要支持提供以下头部字段

头部字段名称

描述

Content-Type

响应体的 MIME 类型。如果响应具有非空消息体,则此头部字段必须存在。

Location

用于重定向,或者在创建新资源时使用。如果响应状态码为 201 或 3xx,则此头部字段必须存在。在 RESTful NFV-MANO API 中,如果响应状态码为 202 并且创建了新资源,则此头部字段也使用。

WWW-Authenticate

如果相应的 HTTP 请求未提供授权,或者提供了无效的授权令牌,则进行挑战或错误详细信息。

Accept-Ranges

服务器用于指示是否支持某些资源的范围。

Content-Range

指示响应中包含的字节范围以及文件的总长度。

Retry-After

用于指示用户代理在发出后续请求之前应等待多长时间。它可以与 503 响应一起使用。此字段的值可以是 HTTP 日期或接收到响应后延迟的秒数。

链接

对其他资源的引用。

版本

响应此请求时请求使用的 API 版本。

版本管理

根据 ETSI NFV-SOL013 v3.4.1 [3],所有接口都需要提供 ApiVersionInformation 以获取版本信息。

Tacker 现在支持两个 API,ETSI NFV-SOL003 中的 VNF 生命周期管理和 ETSI NFV-SOL005 中的 VNF 包管理接口。它们都需要以下两个 URI

  1. {apiRoot}/{apiName}/api_versions

  2. {apiRoot}/{apiName}/{apiMajorVersion}/api_versions

API 规范的详细信息在 REST API 影响章节中描述。

用于主/次版本的控制器

VNF 生命周期管理的模式验证已更新,以支持多个主/次版本。每个操作都有一个针对每个主版本的验证字典。该字典针对新的次版本进行更新。例如,POST {apiRoot}/vnflcm/v1/vnf_instances 与 v2.0.0 和 v2.0.1,其中一些更新存在于较新版本中

vnf_instances_create_v200 = {
  "type": "object",
  "properties": {
      "vnfdId": parameter_types.uuid,
      "vnfInstanceName": parameter_types.name_allow_zero_min_length,
      "vnfInstanceDescription": parameter_types.description,
      "metadata": parameter_types.keyvalue_pairs,
  },
  "required": ["vnfdId"],
  "additionalProperties": True,
}

vnf_instances_create_v201 = copy.deepcopy(vnf_instances_create_v200)
vnf_instances_create_v201["properties"].update({
    "somethingNew": parameter_types.something
})

VNF 生命周期管理的控制器现在在 VnflcmController 中实现,但是,它被分成三个控制器;VnfInstancesController、VnfLcmOpOccController 和 SubscriptionsControllers。此更改有助于我们更轻松地理解 VNF 生命周期管理巨大的逻辑块。

用于主/次版本的 Conductor

Conductor 服务器需要根据请求中的 Version 头部调用不同版本的 VnflcmDrivers。VnflcmDrivers 应该是不同的类实现,以避免依赖于彼此,从而管理未来已弃用的 API 版本。

另一方面,在 VnflcmDriver 中实现所有逻辑对于每个版本来说都过于冗余,因为它们在不同的主版本中大部分是相同的。因此,VnflcmDrivers 将其逻辑暴露给公共函数文件,例如 vnf_instances_utils.py。这使得能够在 VnflcmDriver 中重用逻辑并减少重复的代码块。

OpenStack 和 Kubernetes 的 InfraDrivers 也被重新设计为遵循不同版本的 API,因为它们可能需要不同的逻辑。

用于主/次版本的数据库

不同的主 API 版本需要不同的数据库表,因为主版本在 API 的资源结构发生更改并破坏向后兼容性时会递增。否则,复杂的依赖关系会使数据模型难以维护。

同样,将逻辑暴露给 VnflcmDriver 中的公共函数文件以在不同的 API 版本中重用相同的逻辑也是有用的。

多版本 API 的序列

../../_images/0133.png
  1. 客户端发送 HTTP 请求(例如 POST vnflcm/v2/vnf_instances/instantiate)

  2. 控制器接收并验证请求

  3. 控制器创建 VnfLcmOpOcc(“STARTING”) 表

  4. 控制器发送 RPC 到 Conductor 并向客户端发送“202 Accepted”

  5. Conductor 接收 RPC 并调用 VnflcmDriver

    1. 找到请求中的 Version 头部字段

    2. 选择具有 API 版本的适当版本的 VnflcmDriver

  6. VnflcmDriver 更新 VnfLcmOpOcc(“PROCESSING”) 表

  7. VnflcmDriver 调用 InfraDriver

    1. 找到请求中的 Version 头部字段

    2. 选择具有 API 版本的适当版本的 InfraDriver

  8. VnflcmDriver 更新 VnfLcmOpOcc(“COMPLETED”) 表

备选方案

Release 2 实现与 Release 3 的实现之间的差异对于某些 API 来说可能有限。也可以继承 Release 2 的类以用于新的 Release 3 类,但是这种设计会使版本管理更加困难。因此,在本规范中,Release 3 的类是新创建的,其实现可以在 Release 2 和 Release 3 之间与 utils 函数共享。

数据模型影响

无。

REST API 影响

  • 名称:API 版本
    描述:读取 API 版本信息
    方法类型: GET
    资源的 URL:/vnflcm/api_versions, /vnflcm/{v1/v2}/api_versions
    请求:无
    响应:

    数据类型

    基数

    响应代码

    描述

    ApiVersionInformation

    1

    成功 200 错误 4xx/5xx

    已成功读取 API 版本信息。

    属性名称

    数据类型

    基数

    描述

    uriPrefix

    字符串

    1

    指定 API 的 URI 前缀,格式如下 {apiRoot}/{apiName}/{apiMajorVersion}/。

    apiVersions

    结构

    1..N

    由 uriPrefix 属性指示的 API 支持的版本。

    > version

    字符串

    1

    标识受支持的版本。

    > isDeprecated

    布尔值

    0..1

    如果提供此信息,则此属性指示由 version 属性指示的版本是否已弃用(true)或未弃用(false)。

    > retirementDate

    DateTime

    0..1

    API 版本将不再受支持的日期和时间。如果 isDeprecated 属性设置为 true,则可以包含此属性,否则应省略此属性。

安全影响

无。

通知影响

无。

其他最终用户影响

  • 由于 python-tackerclient 的更改,CLI 选项可能会更改以支持版本管理。

性能影响

无。

其他部署者影响

无。

开发人员影响

  • python-tackerclient 需要支持版本管理。

  • Tacker 的基本设计已重新创建,所有新功能都需要遵循控制器和 Conductor 的新设计。

实现

负责人

主要负责人

伊藤良人 <yoshito.itou.dr@hco.ntt.co.jp>

其他贡献者

野口宏文 <hirofumi.noguchi.rs@hco.ntt.co.jp>

工作项

  • 添加新的请求/响应类

  • 添加用于 API 版本管理的新控制器

  • 添加支持主/次版本的新控制器设计

  • 添加新的 Conductor 以调用不同主版本的 VnflcmDrivers

  • 添加新的数据库设计以分离不同的主版本

依赖项

无。

测试

将添加 Release 3 的 VNF 生命周期管理的单元和功能测试用例。

文档影响

将添加多版本支持设计的完整贡献者指南。

参考资料