在 REST API 中暴露虚拟设备标签

https://blueprints.launchpad.net/nova/+spec/expose-virtual-device-tags-in-rest-api

2.32 微版本允许创建带有标记的块设备和虚拟接口(端口)的服务器,而 2.49 微版本允许在附加卷和端口时指定标签,但没有办法从 REST API 获取这些标签。本规范建议在列出给定服务器的卷附件和端口时,在 REST API 中暴露块设备映射和虚拟接口标签。

问题描述

可以附加带有标签的卷和端口到服务器,但 REST API 中没有任何内容允许用户读取这些标签。虚拟设备标签可以通过 config drive 或 metadata API 服务在访客虚拟机内部获得,但无法通过前端计算 REST API 获得。

此外,在 删除卷附加请求中的设备 规范中,通过标签将卷附件关联到 BlockDeviceMapping 对象作为替换方案,以取代对否则未使用的 device 字段的依赖,以确定客户机内块设备的顺序。

分离和附加启动卷 规范中,使用卷附件标签也是一种讨论方案,用于指示附加到服务器的哪个卷是根卷,而无需依赖服务器 OS-EXT-SRV-ATTR:root_device_name 字段。

用例

作为用户,我想基于标签将信息关联到附加到我的服务器的卷和端口。

提议的变更

在一个新的微版本中,在显示卷附件和附加端口时,在 REST API 响应中暴露虚拟设备标签。

有关路由和响应更改的详细信息,请参阅 REST API 影响 部分。

技术/性能考虑因素

在显示附加卷标签时,暴露标签实际上不需要额外的操作,因为我们已经为每个实例查询数据库以获取 BlockDeviceMappingList。

但是,os-interface 端口标签提出了不同的挑战。今天的 GET /servers/{server_id}/os-interfaceGET /servers/{server_id}/os-interface/{port_id} API 只是代理到 neutron 网络 API,以列出附加到实例的端口以及显示有关附加到实例的端口的详细信息。

附加到实例的端口的设备标签未存储在 neutron 中,而是存储在 nova cell 数据库 virtual_interfaces 表中。因此,我们遇到的问题是在列出服务器附加的端口并希望显示标签时,需要查询 neutron API 以列出端口,然后查询 virtual_interfaces 表以获取标签。我们有两个选择

  1. 接受在列出单个实例的端口时,执行一个额外的数据库查询以获取标签问题不大。

  2. 与其代理对 neutron 的调用,我们可以依赖实例网络信息缓存来提供详细信息。这可能没问题,但我们当前未将标签存储在信息缓存中,因此对于任何现有实例,除非我们执行数据库查询来查找它们并修复缓存,否则不会显示标签。

鉴于选项 2 的复杂性,本规范将仅使用选项 1。

非卷 BDM

应该注意的是,交换和临时块设备在创建服务器时也可以具有标签,但是今天 API 中没有任何内容暴露这些类型的 BDM;API 仅暴露卷 BDM。因此,本规范不打算暴露非卷块设备映射标签。如果将来添加了某种 GET /servers/{server_id}/disks API,我们可以暴露交换和临时块设备及其标签,但这超出本规范的范围。

备选方案

除了在 os-volume_attachmentsos-interface API 中显示标签外,我们还可以修改服务器 show/list 视图构建器,以便在服务器资源 os-extended-volumes:volumes_attachedaddresses 字段中提供标签。对于显示附加卷标签来说,这很容易实现,因为我们已经查询数据库以获取每个实例的 BDM,但如 提议的更改 部分所述,对于端口标签来说,这并非易事,因为这些标签当前未存储在用于构建 addresses 字段响应值的实例网络信息缓存中。而且只在服务器响应中显示附加卷标签而不显示虚拟接口标签会很奇怪。我们可以随着时间的推移修复网络信息缓存,但这似乎过于复杂,因为提议的更改已经提供了一种获取给定服务器资源附加的所有卷/端口的标签信息的方法。

我们也可以借此机会暴露 BlockDeviceMapping 上其他字段,这些字段是在创建服务器时作为输入,例如 boot_indexvolume_typesource_typedestination_typeguest_format 等。为了简单起见,这从提议的更改中省略,因为专注于多种资源类型的标签暴露更为简单。

数据模型影响

无。

REST API 影响

将更改两个 API 资源路由。在所有情况下,如果块设备映射或虚拟接口记录没有指定标签,则 tag 键的响应值将为 None

os-volume_attachments

将为以下每个 API 的响应添加一个 tag 字段。

  • GET /servers/{server_id}/os-volume_attachments (list)

    {
      "volumeAttachments": [{
        "device": "/dev/sdd",
        "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
        "serverId": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
        "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
        "tag": "os"
      }]
    }
    
  • GET /servers/{server_id}/os-volume_attachments/{volume_id} (show)

    {
      "volumeAttachment": {
        "device": "/dev/sdd",
        "id": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
        "serverId": "2390fb4d-1693-45d7-b309-e29c4af16538",
        "volumeId": "a26887c6-c47b-4654-abb5-dfadf7d3f803",
        "tag": "os"
      }
    }
    
  • POST /servers/{server_id}/os-volume_attachments (attach)

    {
      "volumeAttachment": {
        "device": "/dev/vdb",
        "id": "c996dd74-44a0-4fd1-a582-a14a4007cc94",
        "serverId": "2390fb4d-1693-45d7-b309-e29c4af16538",
        "volumeId": "c996dd74-44a0-4fd1-a582-a14a4007cc94",
        "tag": "data"
      }
    }
    

os-interface

将为以下每个 API 的响应添加一个 tag 字段。

  • GET /servers/{server_id}/os-interface (list)

    {
      "interfaceAttachments": [{
        "fixed_ips": [{
          "ip_address": "192.168.1.3",
          "subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef"
        }],
        "mac_addr": "fa:16:3e:4c:2c:30",
        "net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
        "port_id": "ce531f90-199f-48c0-816c-13e38010b442",
        "port_state": "ACTIVE",
        "tag": "public"
      }]
    }
    
  • GET /servers/{server_id}/os-interface/{port_id} (show)

    {
      "interfaceAttachment": {
        "fixed_ips": [{
          "ip_address": "192.168.1.3",
          "subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef"
        }],
        "mac_addr": "fa:16:3e:4c:2c:30",
        "net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
        "port_id": "ce531f90-199f-48c0-816c-13e38010b442",
        "port_state": "ACTIVE",
        "tag": "public"
      }
    }
    
  • POST /servers/{server_id}/os-interface (attach)

    {
      "interfaceAttachment": {
        "fixed_ips": [{
          "ip_address": "192.168.1.4",
          "subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef"
        }],
        "mac_addr": "fa:16:3e:4c:2c:31",
        "net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
        "port_id": "ce531f90-199f-48c0-816c-13e38010b443",
        "port_state": "ACTIVE",
        "tag": "management"
      }
    }
    

安全影响

无。

通知影响

BlockDevicePayload 对象已经暴露了 BDM 标签,用于版本化通知。IpPayload 对象未暴露标签,因为它们不在实例网络信息缓存中,但这些 payload 仅通过 InstancePayload 暴露,就像 servers API 一样,我们不会进行额外的更改来尝试显示服务器(InstancePayload)主体内的资源的标签。如果需要,这可以在将来完成,可能使用配置选项,例如 [notifications]/bdms_in_notifications,但这超出本规范的范围。

其他最终用户影响

python-novaclient 和 python-openstackclient 将根据需要进行更新以支持新的微版本。这可能只是在列出附加卷和端口时在 CLI 输出中添加一个新的 Tag 列。

性能影响

在显示服务器附加端口的设备标签时,将对 virtual_interfaces 表进行新的数据库查询。这应该对 API 响应时间产生最小的影响。

其他部署者影响

无。

开发人员影响

无。

升级影响

无。

实现

负责人

主要负责人

Matt Riedemann <mriedem.os@gmail.com> (mriedem)

工作项

实现一个新的微版本,并使用它来确定是否应该在列出/显示/附加卷/端口到服务器时,在 os-volume_attachmentsos-interface API 响应中包含一个新的 tag 字段。

依赖项

无。

测试

功能 API 样本测试应该足以覆盖此功能。

文档影响

计算 API 参考将更新,以记录 os-volume_attachmentsos-interface API 响应中的 tag 字段。

参考资料

这最初是在 Ocata 会议 上讨论的。它在 Rocky PTG 上再次出现。

相关规范

历史

修订版

发布名称

描述

Pike

最初提出但已放弃

Stein

重新提出