使用 Keystone 验证项目

https://blueprints.launchpad.net/nova/+spec/validate-project-with-keystone

目前没有验证 Nova 消耗的项目的功能。缺乏此功能的一个原因是性能,对外部服务进行验证可能会导致性能下降。但是,在用户传递项目 ID 或名称(例如,配额管理)的情况下,需要此功能,以便设置正确的配额。在用户想要将项目访问权限授予 flavor 的情况下,也需要此功能。

此蓝图仅适用于 API 调用非常少的情况下。更具体地说,它仅用于验证配额管理(例如,quota-defaults、quota-show、quota-update)和 flavor 管理(例如,flavor-access-add、flavor-access-list)中的项目 ID。任何超出配额和 flavor 管理的功能都需要单独的蓝图。

重要的是要注意,此实现不支持验证用户 ID。联合用户不会镜像在 Keystone 身份后端(例如,SQL)中。外部身份提供程序负责对用户进行身份验证,并使用 SAML 断言将身份验证结果传达给 Keystone。

问题描述

Nova 的配额管理功能要求在 CLI 的一部分中指定项目 ID。这会影响 nova quota-show 和 quota-update。当在上述配额操作之一中指定项目时,不会针对 Keystone 检查它们以验证其 ID。

用户可以指定项目名称而不是项目 ID,例如 nova quota-update –instances 9 demo。由于没有进行任何检查,因此会在 Nova 的 project_user_quotas 表中创建一个条目,其中 project_id 设置为项目名称。如果项目 ID 与 project_user_quotas 表中的内容不匹配,这将导致设置无效的配额并返回。

它还会影响 flavor 管理。更具体地说,nova flavor-access-add 和 flavor-access-list。当在上述 flavor 操作之一中指定项目时,不会针对 Keystone 检查它们以验证其 ID。

用例

作为最终用户,我希望为给定的项目 ID 正确设置配额和 flavor 访问权限。我不想意外地使用无效的项目 ID 设置配额或 flavor 访问权限,并假设操作成功,而实际上并非如此。

此实现提供了一层验证,以便由最终用户提供的项目 ID 针对配额和 flavor 管理正确地验证 Keystone。由最终用户提供的无效项目 ID 将被拒绝,并且不会在数据库中创建无效条目。

项目优先级

优先级目前未定义。此实现提供了一层验证,以便由最终用户提供的项目 ID 针对配额和 flavor 管理正确地验证 Keystone。

提议的变更

建议的解决方案是在 Nova 中公开一个 Keystone 客户端,类似于今天在 nova/volume/cinder.py 中存在的 cinder 客户端。将实现通过其 ID 获取项目的方法。当指定项目 ID 时,将针对 Keystone 客户端对其进行查询和验证。

备选方案

可以将项目 ID 未经验证的现有行为保持不变。用户需要从“keystone tenant-list”中找出适当的项目 ID。但是,这种替代方案会产生用户错误,用户可能会错误地为 nova quota-show 或 quota-update 指定项目名称而不是项目 ID。如果发生这种情况,配额将无法正确设置。

另一种选择是让 python-novaclient 验证项目 ID,并期望其他客户端(例如,第三方)也这样做。但是,如果其他客户端在调用 Nova 之前未进行验证,则它无法阻止错误数据插入 Nova。

数据模型影响

Nova 的 project_user_quotas 表中可能存在条目,其中 project_id 设置为无效 ID。但是,这些条目不具有任何重要价值,因为没有实际项目与之关联。在这种情况下,仍然可以使用 quota-delete 命令删除无效条目,因为对删除操作不进行 project_id 验证。

REST API 影响

以前,使用无效项目 ID 的 POST 和 GET 请求会在 Nova 的 project_user_quotas 表中创建一个条目,或者返回项目的配额值(如果有)。使用此建议,如果存在用于验证项目 ID 的 Keystone 服务帐户,则将从 POST 和 GET 请求返回 HTTPBadRequest(代码 400),以获取无效项目。如果不存在 Keystone 服务帐户,则该功能将继续按以前的方式运行,并且仅会记录警告消息(不会通过 POST 或 GET 请求返回)。

安全影响

为了正确验证项目 ID,需要创建一个具有足够权限来查找项目的 Keystone 服务帐户。该帐户应该对 Keystone 的访问权限有限,并且不访问任何其他服务。可以通过在 /etc/keystone/policy.json 中创建适当的基于角色的规则,并将查找项目的能力授予角色来完成此操作。

例如,管理员可以创建一个用户(例如,validator)并向其添加一个角色(例如,validation)。在 /etc/keystone/policy.json 下,管理员将添加这些规则

"identity:get_project": "rule:admin_required or role:validation",

在 /etc/nova/nova.conf 下,管理员将添加这些凭据

keystone_service_project_name = service
keystone_service_user = validator
keystone_service_password = keystone

如果存在上述凭据,将使用上述凭据实例化 Keystone 客户端。

如果 Nova 未配置为执行查找,则操作不应被阻止。相反,应记录一条警告消息,说明 Nova 未配置为执行查找。如果 Nova 已配置为执行查找,但 Keystone 服务帐户无效,则应阻止该操作并报告错误。

通知影响

其他最终用户影响

如果存在用于验证项目 ID 的 Keystone 服务帐户,则将从 POST 和 GET 请求返回 HTTPBadRequest,以获取无效项目。解释将是

  • 指定的项目 ID 无效。

性能影响

性能影响很小。需要连接到 Keystone 才能验证项目 ID。但是,由于很少更改配额/flavor 访问权限,因此这将是一项低频操作。

其他部署者影响

开发人员影响

为了正确验证项目 ID,需要创建一个 Keystone 服务帐户。如果不存在 Keystone 服务帐户,则不应阻止配额和 flavor 操作。相反,应记录一条警告消息,说明 Keystone 服务帐户不存在。这将允许现有的部署继续工作。

实现

负责人

主要负责人

thang-pham

其他贡献者

工作项

  • 创建一个实例化 Keystone 客户端的方法。

  • 实现通过给定的 ID 获取项目的方法。

  • 修改 nova/api/openstack/compute/contrib/quotas.py 中的 QuotaSetsController 类,以验证项目 ID(如果有)。

  • 修改 nova/api/openstack/compute/contrib/flavor_access.py 中的 FlavorActionController 类,以验证项目 ID(如果有)。

  • 修改 devstack 以创建 Keystone 服务帐户,将其凭据保存在 /etc/nova/nova.conf 中,并限制其在 /etc/keystone/policy.json 中的访问权限。

  • 创建 tempest 测试用例和 Nova 单元测试用例以验证功能。

依赖项

测试

将创建 Tempest 测试用例以及 Nova 单元测试用例来验证此功能。应测试以下命令:nova quota-show 和 quota-update。更具体地说,需要使用正确的 ID 指定 –tenant 选项以进行积极测试用例,并使用无效的 ID 进行消极测试用例。还应测试以下命令:flavor-access-add 和 flavor-access-list。需要使用正确的 ID 指定 tenant_id 以进行积极测试用例,并使用无效的 ID 进行消极测试用例。

文档影响

参考资料