代码中的策略¶
https://blueprints.launchpad.net/nova/+spec/policy-in-code
长期以来,一直希望将合理的策略默认值嵌入到代码中,并允许策略文件覆盖它们。这将允许部署者仅配置他们想要覆盖的策略,从而减少这些文件的尺寸和复杂性。它还将允许生成一个包含所有策略详尽列表的示例策略文件。
问题描述¶
这里涉及几个方面
给定一个已部署的策略文件,确定它与 Nova 期望的默认值之间的差异并非易事。这是因为提供的示例文件没有包含所有可配置策略的详尽列表,并且预期的默认值不包含在 Nova 代码库中。
对于使用默认值感到舒适的新部署,将不再需要策略文件。如果代码中的默认值发生更改,这将有助于部署者保持最新。对于更新到此版本的部署者,他们应该能够清理或删除他们的策略文件,使其更易于处理。
给定经过身份验证的请求上下文,无法确定哪些策略将通过。这是因为策略检查在整个代码中是临时性的,没有所有可能检查的中央注册表。
用例¶
作为部署者,我希望仅配置与默认值不同的策略。
提议的变更¶
该方案是,代码中应检查的任何策略都将使用 policy.Enforcer 对象进行注册,类似于配置注册的方式。代码库中的任何策略检查都将被转换为使用新的 policy.Enforcer.authorize 方法,以确保所有检查都已定义。authorize 方法的签名与 policy.Enforcer.enforce 相同。任何尝试使用未注册的策略都将引发异常。
注册需要两部分数据
规则名称,例如“compute:get”或“os_compute_api:servers:index”
规则,例如“rule:admin_or_owner”或“role:admin”
规则名称用于后续查找。规则对于设置默认值和生成示例文件是必要的。
还可以提供可选的描述。这将在可以从这些注册规则生成的示例策略文件中提供。需要注意的是,示例文件将生成为 yaml 格式,oslo.policy 现在可以将其作为输入。
例如
nova/policy/create.py
---------------------
from nova import policy
server_policies = [
policy.PolicyOpt("os_compute_api:servers:create",
"rule:admin_or_owner",
description="POST /servers"),
policy.PolicyOpt("os_compute_api:servers:create:forced_host",
"rule:admin_or_owner",
description="POST /servers with forced_host hint"),
policy.PolicyOpt("os_compute_api:servers:create:attach_volume",
"rule:admin_or_owner",
description="POST /servers with provided BDM"),
policy.PolicyOpt("os_compute_api:servers:create:attach_network",
"rule:admin_or_owner",
description="POST /servers with requested or "
"provided network"),
]
policy_engine = policy.get_policy()
# registration will error if a duplicate policy is defined
policy_engine.register_opts(server_policies)
nova/api/openstack/servers.py
-----------------------------
def create(self, context):
context.can('os_compute_api:servers:create')
if volume_to_attach:
context.can('os_compute_api:servers:create:attach_volume')
请注意,context.can() 将只是 policy.authorize() 的包装器。
当前的方案是将策略注册发生在像配置一样的集中位置。
备选方案¶
关于策略 API 的讨论已发生在 oslo.policy 规范中,用于这项工作,因此这里没有替代方案可供讨论。
数据模型影响¶
无
REST API 影响¶
无。
安全影响¶
无。此更改本质上允许进行预先策略检查,但不会更改策略的处理方式。而且此更改不会直接暴露任何内容,它只是允许后续工作在此基础上构建。
通知影响¶
无。
其他最终用户影响¶
无。
性能影响¶
此方案的性能成本在于服务启动时进行策略注册。其机制类似于配置注册,对影响微乎其微。策略检查可能会略微加快,因为在每次检查之前需要读取的策略文件可能更小。
其他部署者影响¶
当所有策略都已注册后,将不再回退到默认规则。当前依赖于它来设置多个策略的部署者需要显式定义这些策略的覆盖。
此外,这将使我们能够设置一个检查,以确保添加新策略时,会伴随一个 reno 添加。部署者应注意,新策略可能会出现在发布说明中。
开发人员影响¶
添加到代码中的任何策略都应在被使用之前进行注册。虽然代码正在将检查切换到 context.can(),但可以使用未注册的策略检查。在某个时候,应添加一个 hacking 检查来禁止使用 oslo_policy.Enforcer.enforce()。
实现¶
负责人¶
- 主要负责人
alaski
- 其他贡献者
claudiub
工作项¶
定义并注册所有策略。
这可以逐步进行
添加 context.can(),它代理到 oslo_policy.policy.Enforcer.authorize()。
更新所有策略检查以使用新的 context.can() 方法。
添加 hacking 检查以禁止 oslo_policy.policy.Enforcer.enforce()。
更新 Devstack 以使用空/无策略文件。
更新部署者文档。
添加示例文件生成配置和 tox 目标。
添加一个 nova-manage 命令来写入合并的策略文件。这将是 Nova 使用的有效策略,是默认值和已配置覆盖的组合。
添加一个 nova-manage 命令来转储策略文件中与编码默认值重复的策略列表。这将帮助部署者去除冗余。
依赖项¶
https://review.openstack.org/#/c/309152/ 允许从代码注册策略 (oslo.policy)。这是此处核心功能的硬依赖项。
https://review.openstack.org/#/c/309153/ 添加生成示例 policy.json 的功能 (oslo.policy)。这适用于“锦上添花”的功能,例如示例文件生成和显示默认覆盖。
测试¶
此规范不打算向最终用户暴露任何内容,因此大多数测试将仅限于树内单元和功能测试。
将添加一个新的 tox 目标用于示例策略文件生成,可用于测试生成是否有效。文档生成作业可以更新为也输出此文件。
Devstack 将更新为在没有策略文件的情况下运行 Nova,以检查默认值是否使用且合理。
文档影响¶
将更新有关策略文件的部署者文档,以提及仅需要包含与默认值不同的策略。
参考资料¶
无
历史¶
发布名称 |
描述 |
|---|---|
Newton |
引入 |