使用 policy.d 目录进行策略覆盖

目标是提供一种机制,使操作员可以修改 OpenStack 服务的策略,以管理系统租户和用户的权限。本规范所描述的功能并非旨在管理服务本身的权限。这必须完全属于 charm 的范围,此处描述的功能不应被(滥)用。

问题描述

首选方法一直是使用 charm 选项,通过提供选项修改的模板,实现对服务策略进行更受控的修改——即,始终生成一致策略文件的受控方法。

然而,随着时间的推移,情况越来越明显:操作员总会希望调整或更改服务策略的某个方面,而 charm 作者并未考虑到这一点,并且引入该选项的周期时间超出了操作员愿意忍受的延迟预期。

因此,人们认识到,charm 控制的配置文件的一些方面需要操作员更灵活地修改。这些方面通常与部署行为正交,而是与云操作相关。

因此,目标是为操作员提供一种机制,在不(希望)破坏系统功能的情况下,覆盖策略默认值。策略默认值要么通过“代码内策略”在服务中编码,要么通过 charm/服务提供的默认策略 YAML 文件。

提议的变更

  • 此功能将在 Ubuntu Xenial 及更高版本上受支持。

  • 此功能将在 OpenStack Queens 及更高版本上受支持。

  • 资源支持需要 Juju 2.0 或更高版本。

需要在目标 charm 集中提供策略覆盖(见下文)。为了高效地完成此工作,大部分工作需要在 charm-helpers 中完成,每个 charm 中只需进行最少的工作。

配置选项布尔值 use-policyd-override(默认为 False)将控制是否使用资源文件。如果为 False,则忽略资源文件——即,无论它是否存在/损坏,都不重要。

如果配置选项 use-policyd-overrideTrue,则 Juju 状态将以 "PO:" 为前缀,表明策略被附加的资源文件覆盖。这特意保持简短,以便在状态行上也能看到其他信息。Juju 日志中也会生成一条信息日志,指示策略已被覆盖。

Juju 资源将用于使用资源名称 policy-override 将压缩文件(使用 pkzip 或同等工具)附加到 juju 应用程序。与应用程序关联的 charm 将验证压缩文件的内容,并使用压缩资源文件中的文件更新策略目录(默认为 /etc/<service-name>/policy.d)的内容。

资源名称将是 policyd-override

从概念上讲,charm 拥有 /etc/<service-name>/policy.d/。从属 charm 将无法覆盖策略;这应在主 charm 中执行。这种“所有权”的后果是,如果文件不是由 charm 本身(出于其自身的覆盖目的)或通过此策略覆盖系统放置在该目录中,则 charm 从目录中删除这些文件。即,临时将文件放入目录中很可能在下一个 upgrade-charm 钩子期间被删除,从而导致意外结果。对 /etc/<service-name>/policy.d/ 目录的更改将记录到 charm 的调试日志中。

资源文件中的模板

策略覆盖功能本质上分为两部分;charm-helpers(和 charms.openstack)以及从 charm 调用支持函数。一个稍微有争议的问题是关于使用模板来允许上下文变量(由 charm 中的关系数据和配置构建)在放入 policy.d 目录之前烘焙到策略覆盖文件中。

这并非作者首选的机制,作者宁愿使用现有的模板功能将规则渲染到 charm 的默认策略文件中(与 keystone policy.json 文件中 admin_required 的处理方式相同),然后堆栈覆盖文件再引用这些规则。也就是说,模板仍然由 charm 控制,而不是由插入式覆盖控制。

然而,在 charm-helpers 函数中提供字符串替换功能是相当简单的,即使在 charm 调用时并未使用该功能。作者认为这应该是默认条件,并且只在无法通过其他方式满足策略覆盖要求时才允许启用模板功能。

将提供模板和替换功能,以便资源文件中带有 .j2.tmpl.tpl 扩展名的文件将由 charm 提供的字符串替换函数处理,该函数可以是使用上下文的 Jinja 模板函数,也可以是带有某些定义变量的简单文本替换。这将由 charm 控制。由 charm 提供的函数返回的替换字符串将按照静态 yaml 文件的处理方式进行处理,并进行所有后续验证。

验证

charm 将尝试对附加的资源文件进行一些验证

  • 文件是否为有效的 zip 文件(请注意,任何目录都将被忽略。zip 文件将被展平以删除目录)。

  • 不带 .yaml.yml 扩展名的文件将被忽略。这允许在 zip 文件中添加文档。

  • 将检查剩余的、扁平化的、已识别的 yaml 文件是否具有唯一名称。如果不是,则验证失败。

  • 每个文件都将(尝试)使用 Python yaml safe_load 函数加载。如果加载失败,则验证失败。

  • 每个策略覆盖都将对照 charm 维护的黑名单进行检查。该黑名单将基于每个 charm,最初将黑名单化更改 admin_requiredcloud_admin。这是为了确保 charm 本身不会被其维护的 OpenStack 系统锁定。

  • 如果验证失败,则整个策略覆盖失败,并且 charm 将继续执行,就好像 use-policyd-overrideFalse。应用程序/charm 的活动状态将显示 "PO (broken): ..."。请注意,将不会出现钩子错误。理由是策略覆盖是操作员功能,charm 尝试应用它们,但只应指示它们未被应用,以便操作员可以更改策略覆盖。验证失败的解释消息将记录到 charm 的日志中。

如果 charm 验证成功,则 /etc/<service-name>/policy.d/ 目录将被清除(除了其他 charm 固有策略覆盖),然后新文件将写入该目录。负载服务将重新启动。

OpenStack 服务支持

策略覆盖功能出现在 ocata 版本的 oslo.policy 中,并最初由 keystone 和 nova 采用。为了支持它,OpenStack 服务需要支持 Enforcer 类,以便能够利用 policy.d 覆盖目录(这是默认设置)。

以下服务项目(拥有 Canonical charm)已在 Queens 版本中检查并拥有 Enforcer

  • keystone

  • neutron

  • nova

  • glance

  • cinder

  • aodh

  • designate

  • heat

  • horizon (openstack-dashboard)

  • manila

  • octavia

  • panko

  • trove

  • zaqar

以下服务项目目前(Stein 版本)不支持 Enforcer

  • swift

不适用的服务

  • gnocchi

  • ceilometer

这项工作将影响许多 charms。Bug#1741723 记录了(很可能)需要策略覆盖功能的 charm。这项工作范围内的主要 charm 是:

  • cinder

  • designate (reactive charm)

  • glance

  • keystone

  • neutron-api

  • nova-cloud-controller

这种实现方式应该能使其相对容易地在其他 charm 上实现。Designate 被包含在内,以提供 reactive charm 的概念验证。

备选方案

N/A

实现

负责人

主要负责人

ajkavanagh (irc: tinwood)

Gerrit Topic

所有与本规范相关的补丁均使用 Gerrit 主题“policy-overrides”。

git-review -t policy-overrides

工作项

更改将在以下位置实施

  • charm-helpers (contrib.openstack)

  • charms.openstack

  • 各个 charm (keystone, glance, 等等)

已识别出以下工作项

  • charm-helpers

    • 帮助程序读取 zip 文件,执行验证

    • 帮助程序使用经过验证的文件更新 policy.d 目录。

    • 从安装和升级钩子调用的帮助程序

    • 从 config-changed 钩子处理程序调用的帮助程序,用于确定是启用还是禁用策略覆盖。

    • 合并到 update-status 的帮助程序,用于确定策略是否被覆盖。

  • charms.openstack

    • 混合调用 charm-helpers 以执行 policy.d 目录的验证和更新/控制。

    • 集成到安装和升级钩子中的方法,用于调用混合中的相关函数。

    • 与 config-changed 钩子集成的方法,用于确定是启用还是禁用策略覆盖(可能调用 charm-helpers)。

  • keystone charm (首先)

    • 链接到 charm-helpers 中的辅助函数。

    • 功能测试以验证策略可以被覆盖,并且文件出现在 policy.d 目录中。

  • designate charm (响应式示例)

    • 将 mix-in 添加到 designate 主类中,以及任何所需的辅助调用(目前尚不清楚需要多少额外支持)。

    • 功能测试以验证策略可以通过文件覆盖。

仓库

以下存储库将受到影响

以及测试框架

文档

以下文档需要更新

  • charm-guide

  • deployment-guide

  • 受更改影响的 charm 中的 README

安全性

尽管文件被上传到控制器(因此作为资源上传到 charm),但 Python zip 模块用于检查内容,并且潜在的 yaml 文件使用 YAML 模块的 safe_load 读取以验证内容是否为 yaml。然后将其写入 /etc/<service-name>/policy.d/ 目录中的相关文件。因此,zip 文件中的文件不会直接复制到文件目录。因此认为,由于没有使用第三方模块,也没有直接复制文件,这种方法不应存在安全问题。

测试

  • 单元测试将添加到 charm-helpers 和 charms.openstack 中

  • 功能测试将添加到那些支持 zaza 测试框架的 charm 中。这将验证覆盖是否放置在适当的目录中,并且服务已重新启动。服务操作(例如列出用户)将验证为正常工作,然后禁用,然后再次工作。一个框架将放入 zaza-openstack-tests 中以支持此功能。

实际的策略覆盖不予检查。这是负载(服务)的范围,超出此功能测试的范围,此功能仅是将格式正确的 yaml 文件放入 policy.d 目录。

依赖项

没有依赖关系