获取 driver_info 属性的 API¶
https://blueprints.launchpad.net/ironic/+spec/get-required-driver-info
该蓝图提出一个 API,用于返回所有 driver_info 属性,以及每个属性的描述。
问题描述¶
在初始 POST 请求中不指定任何 driver_info 属性来创建节点是可能的——这是合理的并且可以接受的。但是,API 没有公开 driver_info 属性列表,也没有公开节点驱动程序所需的属性。客户端无法知道在后续 PATCH 请求中发送哪些字段/属性,除非阅读 Ironic 的开发者文档(或源代码!)。
为了解决上述问题,提出一个 API,用于返回 driver_info 属性,以及每个属性的描述。描述将包括该属性是必需的还是可选的。
作为一个 API,它可能被人类和应用程序使用。
提议的变更¶
RESTful Web API¶
RESTful Web API 将被增强,添加
GET /v1/drivers/<driver>/properties
其中 <driver> 是驱动程序的名称。
如果请求不成功,例如指定了无效的驱动程序名称,则返回 HTTP 状态码 404 和错误消息。
如果成功,则返回 HTTP 状态码 200,响应(以 Json 格式)是一个列表,包含
<property name>: <property description>
其中 <property description> 是属性的描述,包括它是必需的、可选的或任何其他特殊情况。
例如:GET /v1/drivers/pxe_ssh/properties 可能会返回
{"pxe_deploy_ramdisk": "UUID... Required.",
"ssh_address": "IP address or hostname of the node to ssh into. Required.",
"ssh_virt_type": "virtualization software... Required.",
"ssh_user_name": "username to authenticate as. Required.",
"ssh_key_contents": "private key(s). One of this, ssh_key_filename,
or ssh_password must be specified."
"ssh_key_filename": "filename ... One of this, ssh_key_contents,
or ssh_password must be specified."
"ssh_password": "password... One of this, ssh_key_contents, or
ssh_key_filename must be specified."
"pxe_deploy_kernel": "UUID... Required."}
}
CLI 子命令¶
将添加 driver-properties 子命令
ironic driver-properties <driver_name>
它返回一个表格,其中包含指定驱动程序的 driver_info 属性。对于每个属性,将显示以下信息
driver_info 属性的名称
description
例如
$ ironic driver-properties fake_ipminative
+---------------+---------------------------------+
| Property | Description |
+---------------+----------+----------------------+
| ipmi_address | IP of the node's BMC. Required. |
| ipmi_password | IPMI password. Required. |
| ipmi_username | IPMI username. Required. |
+---------------+---------------------------------+
对于无效的驱动程序名称,它返回
The driver '<invalid-driver-name>' is unknown. (HTTP 404)
必需与可选属性¶
驱动程序属性是特定于每个驱动程序的,并且取决于驱动程序的接口(电源、部署、控制台、救援、管理)。我们是在接口实现中确定哪些属性是必需的,哪些是可选的。话虽如此,并非绝对黑白。例如,具有 SHPower power 接口的驱动程序需要指定 ssh_key_contents、ssh_key_filename 或 ssh_password 属性中的一个。处理这种“必须指定其中之一”的情况可能是合理的,但是如果希望“必须指定这些中的一个或多个”、“必须指定恰好 X 个这些”、“如果指定了 A,则必须指定 B”、“如果指定了 A,则必须指定 B 或 C”会发生什么?
在 讨论之后,我们决定采用在描述中指示属性是否必需,以及任何约束的方法。将不会返回显式的“required”字段。
API 服务获取信息的方式¶
一个 conductor 服务可以处理一个或多个不同的驱动程序。可能存在不同版本的 conductor 服务、不同版本的 API 服务以及通过不同的 conductor 服务提供的不同版本的驱动程序。Ironic 当前具有对 conductor 服务和 api 服务进行版本控制的机制(通过 RPC_API_VERSION)。但是,尚未提供对驱动程序版本控制的机制。
当/如果 Ironic 具有驱动程序版本控制机制时,API(和代码)可以更新为使用驱动程序版本来获取特定于该版本的驱动程序属性。
驱动程序升级(导致一个或多个 conductor 服务重新启动)需要考虑,因为驱动程序升级可能包括对其属性的更改。将存在升级窗口,在此期间,由于升级,不同的 conductor 服务可能正在处理不同的驱动程序。本规范假定升级窗口很小,并且在升级后,所有 conductor 服务将处理相同版本的驱动程序。(正确的解决方案是具有显式的驱动程序版本控制;一个中间解决方案可能是允许用户在查询驱动程序信息时显式指定一个 conductor 服务,但这似乎不是正确的做法。)
在 conductor 服务升级后,应重新启动所有 API 服务。因此,在升级窗口期间,API 服务可能会返回不正确/不同的驱动程序属性信息,但升级完成后,信息应再次正确。
虽然 API 服务可以直接访问/实例化驱动程序,但这只会使服务访问本地驱动程序。这些驱动程序可能不是 conductor 服务实际使用的驱动程序。此外,由于驱动程序与硬件通信,不应允许 API 服务直接访问它们。
因此,conductor 服务是获取驱动程序属性的网关。考虑了两种方法
API 服务通过 RPC 查询 conductor 服务,以获取驱动程序属性。它选择第一个 conductor 服务(如果假设所有 conductor 服务都在处理相同版本的驱动程序,则任何一个都可以)。**这是我们将采用的方法。**
API 服务查询 DB 以获取 conductor 服务放置在那里的驱动程序属性。当 conductor 服务启动时,它会将能够处理的每个驱动程序的属性信息添加到 DB 表中。由于多个 conductor 可能会处理相同的驱动程序,因此驱动程序信息将添加到与“conductor”表不同的新 DB 表中。
对于这两种方法,为每个用户请求进行 RPC 或 DB 调用可能会成为性能问题;特别是如果用户请求由某些自动化系统生成。由于信息在 conductor 服务(或更长时间)的生命周期内是静态的,因此 API 服务本地缓存信息是有意义的。
如果发生升级(其中更新了 conductor 驱动程序),则在完成 conductor 服务升级后,必须重新启动所有 API 服务。这将清除缓存,以确保 API 服务获取最新的驱动程序信息。
可以添加缓存刷新机制,但信息相对静态并且仅在驱动程序更改时才会更改。驱动程序更改应该不频繁,以至于在 conductor 服务升级后重新启动 API 服务就足够了。
由于将驱动程序信息存储在数据库中似乎没有太多好处,因为将进行缓存,因此将实现 API 服务查询 conductor 服务以获取驱动程序信息(方法 #1)。
备选方案¶
driver_info 信息可以通过非 API 方式提供
记录信息。
优点:无需任何代码更改,无需编写此规范
缺点:用户需要知道在哪里找到文档;需要保持文档的最新状态;更难以编写自动化工具来提取此信息
阅读代码。
优点:无需额外的代码更改;无需编写此规范;将始终是真相之源
缺点:非常不友好;用户需要知道 python 并知道在哪里找到适当的代码。
鉴于我们认为拥有 API 是件好事,因此排除了这些方法。
这不描述替代的 RESTful Web API、CLI 命令或响应输出,因为提议的 API 与现有的 API 保持一致,但显然存在替代方案。
数据模型影响¶
这将为每个 API 服务添加内部缓存。数据库不受影响。
REST API 影响¶
请参阅上面的 RESTful Web API 部分,了解有关新请求的描述。
驱动程序 API 影响¶
所有驱动程序接口(DeployInterface、PowerInterface、ConsoleInterface、RescueInterface、VendorInterface、ManagementInterface)都将/必须具有新方法
@abc.abstractmethod
def get_properties(self):
"""Return the properties of the interface.
:returns: a dictionary with <property name>:<property description>
entries
"""
Nova 驱动程序影响¶
无
安全影响¶
无
其他最终用户影响¶
请参阅上面的 CLI 子命令 部分,了解 CLI 子命令。
可扩展性影响¶
无
性能影响¶
可以忽略不计。
其他部署者影响¶
conductor 服务升级后,必须重新启动所有 API 服务的要求。
开发人员影响¶
除了进行审查之外,没有其他要求。嗯,确保在代码中更新属性列表。
实现¶
负责人¶
- 主要负责人
rloo
- 其他贡献者
无
工作项¶
Bug
API 没有公开必需的 driver_info (https://bugs.launchpad.net/ironic/+bug/1261915)
补丁
实现获取驱动程序属性的 API (https://review.openstack.org/#/c/73005/)
添加 driver-properties 命令 (https://review.openstack.org/#/c/76338/)
依赖项¶
无
测试¶
由于信息是静态的,Ironic 单元测试就足够了。
如果 QA 团队认为检查常用驱动程序的输出对 Tempest 有利,则应添加 Tempest 测试。
文档影响¶
CLI 子命令需要记录,但文档团队有一个脚本可以通过发出 ironic 命令来生成文档。
一个或多个指南(操作员和/或部署)需要提及在升级所有 conductor 服务后,必须重新启动所有 API 服务。
参考资料¶
关于如何处理必需与可选属性的讨论。从 2014-07-08T14:18:06 开始:http://eavesdrop.openstack.org/irclogs/%23openstack-ironic/%23openstack-ironic.2014-07-08.log