ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Open Policy Agent (OPA) v1.0 升级完全指南:生产端到消费端的迁移路径与 Rego v1 语法改造

Open Policy Agent (OPA) v1.0 升级完全指南:生产端到消费端的迁移路径与 Rego v1 语法改造 后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载本文以官方 Upgrading to v1.0 指南为骨架结合 v0 向后兼容说明 与仓库源码cmd/flags.go、ast/ast.go、bundle/bundle.go等系统梳理 OPA v1.0 的升级策略、九个生产/消费版本组合场景、Rego v1 语法变更细节以及 Rego 项目与 Go 集成的迁移工具链。读完本文你将能依据自身部署形态选出一条平滑的升级路径并熟练使用opa check --v0-v1、opa fmt --write --v0-v1、--v0-compatible等工具完成迁移。一、升级总体思路先升级 Producer再升级 Consumer所有用户都应规划升级到 OPA v1.0。对自身部署内 Rego 有较强掌控力的团队可以更快完成升级而对 Rego 掌控力较弱、或运行第三方 Rego 的团队可以先升级到 v1.0 并使用 v0 兼容模式 逐步过渡。官方文档采用以下三个概念描述系统角色Bundle ProducerBundle 生产端基于opa build构建 Bundle供消费端加载的系统。Bundle ConsumerBundle 消费端加载并评估系统中 Bundle 内策略的 OPA 实例。Authoring策略编写在 Bundle 被构建与消费之前编写 Rego 策略的过程。在托管系统中这可能是用户与 OPA 的唯一接触点。有些系统不使用 Bundle此时不存在 Producer升级过程会因此简化。官方建议尽可能早地升级到 OPA v1.0在更新 Rego 之前优先使用 v0 兼容功能而不是推迟升级。除非你的 Rego 已经兼容 v1.0否则应参照 升级 Rego 一节先完成策略改造。为什么先升级 Producer升级后的 Producer 能够在 Bundle manifest 中写入 Rego 版本rego_version消费端无需再以--v0-compatible运行同时生产端数量通常远少于消费端先升级生产端能让整体迁移更平滑。当然具备充分测试与验证条件的团队也可以一次性整体迁移由于并非所有步骤对所有人都必要混合式hybrid升级同样可行。二、九个生产/消费版本组合场景总览官方文档将系统按 Producer 与 Consumer 的 OPA 版本划分为 3×3 共九种组合下表直接取自 Upgrading to v1.0供对照定位自己的起点拿不准时Scenario 1 是最常见起点v0.x ConsumerMix Consumerv1.0 Consumerv0.x ProducerScenario 1全 v0.xScenario 4Scenario 7Mix ProducerScenario 2Scenario 5Scenario 8v1.0 ProducerScenario 3Scenario 6Scenario 9全 v1.0官方文档同时给出了一张升级路径流程图mermaid描绘推荐走向与可跳过的路径例如从 Scenario 1 可以直接单步升级到 Scenario 9即一次性整体迁移Scenario 1: 全 v0.x最普遍起点所有 OPA 运行时消费端与生产端均为 v0.x这是从旧版本开始升级最常见的情形。运行方式策略按 v0.x 兼容的方式编写。下一步开始将 Producer 升级到 v1.0Scenario 2直至所有 Producer 均为 v1.0Scenario 3。Scenario 2: Mix Producerv0.x Consumer部分 Producer 为 v1.0其余仍为 v0.x所有 Consumer 均为 v0.x。典型场景是多个租户/用户使用不同 OPA 版本构建 Bundle而你无法控制它们使用的版本。前置条件必须统一 Producer 版本或具备对新 Producer 使用--v0-compatible的控制能力否则无法继续。运行方式策略按 v0.x 兼容编写v0.x Producer 原样运行v1.0 Producer 以--v0-compatible运行或在模块中加入rego.v1importv0.x Consumer 原样运行。下一步继续迁移 Producer 至 v1.0直到全部升级Scenario 3。Scenario 3: v1.0 Producerv0.x ConsumerBundle 由 v1.0 实例构建Consumer 仍在 v0.x。这是先升级生产端策略下的常见中间态。前置条件必须能控制 Producer 设置--v0-compatible或使用rego.v1import。运行方式策略按 v0.x 兼容编写v0.x Consumer 原样运行v1.0 Producer 以--v0-compatible运行或模块带rego.v1import由于策略总是被 v0.x OPA 消费所有策略必须保持 v0.x 兼容。下一步Producer 已全部 v1.0接下来把 Consumer 全部升到 v1.0Scenario 6。Scenario 4: v0.x ProducerMix ConsumerProducer 为 v0.xConsumer 混合 v0.x 与 v1.0。该情形发生在用户已部分升级 OPA 实例但尚未升级 Consumer 时。官方不推荐在可避免时采取此路径应优先升级 Producer。前置条件v1.0 Consumer 必须能以--v0-compatible接受 v0.x Bundle否则此路径无法继续。运行方式策略按 v0.x 兼容编写v0.x Producer 与 v0.x Consumer 原样运行。下一步将 Producer 升级到 v1.0 后继续推进。一般建议先升 Producer但根据现有 v1.0 Consumer 部署情况你也可以选择把所有 Producer 升到 v1.0而非回退 Consumer。Scenario 5: Mix ProducerMix ConsumerBundle 生产与消费均使用混合版本。前置条件由于 Producer 版本混杂必须能对 Producer 设置--v0-compatible同时必须能对 v1.0 Consumer 设置--v0-compatible标志。两个条件都必须满足才能继续。运行方式策略按 v0.x 兼容编写v1.0 Consumer 以--v0-compatible运行v1.0 Producer 以--v0-compatible运行。下一步逐步将 Producer 升级到 v1.0直到全部为 v1.0Scenario 6。Scenario 6: v1.0 ProducerMix Consumer所有 Consumer 可以不带任何标志运行因为 Bundle 中包含rego_version属性可告知 v1.0 OPA 实例接受 v0.x 模块。运行方式策略按 v0.x 兼容编写v0.x Consumer 原样运行Bundle 内为 v0.x 策略v1.0 Consumer 原样运行Bundle 含rego_version属性v0.x 模块被接受。前置条件若无法让 v1.0 Producer 使用--v0-compatible以兼容 v0.x Consumer此路径会被阻塞。下一步最终目标是全部运行 v1.0 Producer 与 ConsumerScenario 9。Scenario 7: v0.x Producerv1.0 Consumer所有 Consumer 均为 v1.0Producer 仍为 v0.x。该情形发生在评估用 OPA 实例先于 Bundle 打包系统升级时。前置条件若 v1.0 Consumer 不能以--v0-compatible运行则加载 v0.x Producer 生成的 Bundle 时由于 Bundle 不含rego_version属性路径会被阻塞直到 Producer 能生成带 Rego 版本的 Bundle 或可使用--v0-compatible。运行方式策略按 v0.x 兼容编写v1.0 Consumer 以--v0-compatible运行。下一步将 Producer 升级到 v1.0Scenario 8直至全部 v1.0Scenario 9。Scenario 8: Mix Producerv1.0 Consumer所有 Consumer 均为 v1.0Producer 混合 v0.x 与 v1.0。运行方式策略按 v0.x 兼容编写v0.x Producer 原样运行v1.0 Consumer 以--v0-compatible运行v1.0 Producer 以--v0-compatible运行。前置条件若使用 v0.x BundleProducer 必须能设置--v0-compatible才能被 v1.0 Consumer 接受。v1.0 Consumer 会接受 v1.0 Producer 构建的 Bundlemanifest 中带有 Rego 版本但不会接受 v0.x Producer 的 Bundle除非设置了--v0-compatible。下一步把 Producer 全部升到 v1.0Scenario 9完成升级。Scenario 9: 全 v1.0升级完成所有 Consumer 与 Producer 均运行 v1.0即完成 OPA v1.0 升级。若使用了--v0-compatible功能接下来应把 OPA 实例加载的 Rego 升级为 Rego v1。无论是否继续升级 Rego都建议运行opa check、opa check --strict并对 Rego 项目做 lint以提前发现问题。三、Rego v1.0 的语言变更将 OPA 实例升级到 v1.0或一次性整体升级后需要把 Rego 策略升级为 Rego v1.0。官方文档明确了以下五个方面的语法变更。1.future.keywords导入成为空操作in、every、if、contains四个关键字是陆续引入的Rego v0.x 要求显式future.keywords导入以避免破坏既有策略opt-in 机制。这些关键字提升了策略可读性并为迭代、成员判断、多值规则等常见操作提供语法糖在 OPA 文档与 Rego Playground 中已被广泛采用。在 OPA v1.0 中这四个关键字默认成为语言的一部分再导入future.keywords.*将成为空操作no-op。在源码层面ast/ast.go 定义了三种RegoVersion常量RegoV0默认的原始 Rego 语法当前 v0 包默认值RegoV0CompatV1同时满足 RegoV0 与 RegoV1 语法如同模块导入了rego.v1的效果RegoV1OPA 1.0 强制执行的 Rego 语法关键字集成为默认且无需导入。而internal/future包如 filter_imports.go负责解析future.keywords与future.keywords.xyz形式的导入将其转换为解析器选项AllFutureKeywords/FutureKeywords。一个使用了这些关键字但未导入的模块在 OPA v1.0 中合法但在旧版本中不合法。2. 强制在规则头部使用if与containsRego v0.x 中a.b {true}与a.b.c {true}存在语义歧义两者语法相似但前者在data.a路径下生成包含条目b的集合后者在data.a.b路径下生成属性c: true的对象。if关键字不只是语法糖——规则头部使用if后该规则不会贡献部分集合partial set除非同时使用contains。例如a.b if {true}在data.a下生成属性b: true的对象。OPA v1.0 要求声明规则时使用if和contains意味着所有规则默认是单值的头部省略值时默认值为true要使规则变为多值即部分集合规则使用contains关键字把值转换为集合。contains用于消除生成单值规则与多值规则的歧义if用于确保规则语义在 v0.x 与 v1.0 之间不发生改变。下表官方文档原文展示了为何必须引入ifruleoutput in v0.xoutput in v1.0p { true }{p: true}compile errorp.a { true }{p: {a}}compile errorp.a.b { true }{p: {a: {b: true}}compile errorp if { true }{p: true}{p: true}p.a if { true }{p:{a: true}}{p:{a: true}}p.a.b if { true }{p: {a: {b: true}}{p: {a: {b: true}}p contains a{p: {a}}{p: {a}}如果语言被改成所有规则默认单值、除非用contains转为多值那么p.a { true }这类规则在 v0.x 与 v1.0 之间的输出会静默改变而不报错。相比改变既有规则语义产生编译错误是更可取的因此 OPA v1.0 强制要求使用if关键字。需要注意if仅对带规则体的规则是必需的常量纯值赋值规则不需要if。以下形式在 v1.0 中仍然合法ruleoutput in v0.xoutput in v1.0p : 1{p: 1}{p: 1}p.a : 1{p: {a: 1}}{p: {a: 1}}p.a.b : 1{p: {a: {b: 1}}}{p: {a: {b: 1}}}由于if只能置于规则体之前没有规则体也没有值赋值的孤立引用solitary reference在 v1.0 语法中不被允许ruleoutput in v0.xoutput in v1.0pcompile errorcompile errorp.a{p: {a}}compile errorp.a.b{p: {a: {b: true}}}compile error下表汇总了 v0.x 合法但在 v1.0 非法的写法及其等价 v1.0 写法invalid in v1.0v1.0 equivalentNotep { true }p if { true }单值规则p.ap contains a多值插入p.a { true }p contains a if { true }多值规则p.a.bp.a.b : true单值赋值p.a.b { true }p.a.b if { true }单值规则生成集合的规则示例package play a contains b if { b : 1 }评估输出JSON 中集合被序列化为数组{ a: [1] }生成对象的规则示例package play a[b] if { b : 1 }评估输出{ a: { 1: true } }if与contains的要求消除了单值/多值规则声明的歧义使 Rego 更易编写、阅读与理解。3. 禁止重复导入shadowing作为 OPA 0.xstrict模式的一部分编译器禁止一个导入遮蔽shadow另一个导入OPA v1.0默认强制执行该检查。导入相互遮蔽极可能是无意的编写错误默认检查有助于避免策略评估产生易错决策。4.input与data成为保留关键字Rego 编译器确保input和data是保留关键字不得用作规则名或变量赋值名同样源自 OPA 0.x 的strict模式。原因在于input文档存放用户提供的输入而推入 OPA 的数据与规则评估结果嵌套在data文档下。若规则或变量遮蔽input/data会在局部作用域内意外抹掉这些信息导致错误的策略决策。v1.0 默认避免此类场景。注意使用with关键字向input或data文档插入/整体替换值如my_func(x) with input as {...}不算遮蔽在 v1.0 中合法。关于with的详细语义可参考 policy-language.md。5. 禁止使用已弃用内置函数作为 OPA 0.xstrict模式的一部分编译器禁止使用已弃用的内置函数在 OPA v1.0 中这些内置函数已被移除。官方列出的弃用内置函数为any、all、re_match、net.cidr_overlap、set_diff、cast_array、cast_set、cast_string、cast_boolean、cast_null、cast_object。其中部分场景已由新内置函数提供至少相近的功能。仓库中 topdown/builtins/builtins.go 的包注释也明确标注该包为旧项目从 v0.x 迁移而保留OPA v1.x 生命周期内可用但不建议使用。四、v1.0 默认执行的编译约束与安全检查以下约束与安全检查在 v1.0 编译期间默认强制执行。它们连同 v1.0strict模式见 policy-language.md中的检查在 OPA 0.x 时期都属于编译器的strict模式NameDescriptionDuplicate imports禁止重复 imports即一个 import 遮蔽另一个。inputanddatareserved keywordsinput与data是保留关键字不得用作规则名与变量赋值名。Use of deprecated built-ins禁止使用已弃用内置函数这些函数将在 OPA 1.0 中被移除。已弃用内置函数any、all、re_match、net.cidr_overlap、set_diff、cast_array、cast_set、cast_string、cast_boolean、cast_null、cast_object五、升级 Rego 的四个步骤v0.x Rego 项目建议按以下流程升级以符合最佳实践并兼容 OPA v1.0。开始前请确保本地有1.0 或更高版本的 OPA 二进制。opa check --v0-v1捕获解析parse与编译compile错误。opa check --v0-v1 --strict进一步指出可能导致与 OPA v1.0 不兼容的问题如使用已弃用内置函数、重复导入等。opa fmt --write --v0-v1自动将代码重排为 OPA v1.0 兼容格式。regal lintRegal linter仓库内文档见 docs/projects/regal提供更多规则用于排查可能导致错误、性能低下或意外行为的 Rego 代码问题。升级过程中遇到问题时可在 OPA Slack 的#help频道求助官方文档建议。配套机制rego.v1导入与--v0-v1标志在正式切换前v0 兼容模式下有三种渐进工具详见 v0-compatibility.mdrego.v1导入让 OPA 应用 v1.0 默认强制执行的全部限制。模块导入rego.v1意味着隐含了适用的future.keywords导入同一模块内同时导入rego.v1与future.keywords.in/every/if/contains是非法的。opa fmt --v0-v1把现有模块中的future.keywords.*导入重写为rego.v1导入。opa check --v0-v1检查模块中只要使用了in、every、if、contains任一关键字就必须存在rego.v1导入或适用的future.keywords.*导入。在命令行实现层面cmd/flags.go 中可以看到这三个标志的真实定义--v0-v1将模块视为同时兼容旧版 0.x 与当前 v1.0 的 Rego 语法用于check/fmt--v0-compatible选择加入 OPA v1.0 之前的功能与行为v1.0 中用于接受 v0.x 模块--v1-compatible选择加入 OPA v1.0 默认启用的功能与行为v1.0 中已隐藏主要用于 v1.0 之前版本产生/消费 Rego v1 Bundle。六、Rego-versioned Bundle带 Rego 版本的 Bundle使用 OPAv0.64.0或更高版本构建的 Bundle其 manifest 中包含rego_version属性消费该 Bundle 的 OPA 会在处理其中模块时使用该版本。Bundle 内部的 rego 版本优先于--v1-compatible标志因此无需事先了解所消费 Bundle 内的 Rego 语法。opa build命令上的--v1-compatible标志以及 v1.0 中的--v0-compatible允许用户控制所构建 Bundle 的 rego 版本。这一机制正是 Scenario 6/8/9 中v1.0 Consumer 可原样运行的基础Bundle 自带版本声明消费端无需猜测。源码层面bundle/bundle.go 的MergeWithRegoVersion在合并 Bundle 时显式接收ast.RegoVersion参数印证了 Bundle 处理与 Rego 版本的深度绑定。七、升级 OPA 实例服务器监听地址的变化OPA 1.0 之前opa run --server/-s默认绑定所有网卡接口OPA 1.0 默认改为绑定localhost。在受信任环境中这并非不安全但如果 OPA 不打算对外暴露默认绑定 localhost 是更稳妥的做法。如需复刻 v0.x 行为可使用--addr标志绑定所有接口opa run --server --addr 0.0.0.0:8181提示在容器中运行 OPA 时若实例需要被宿主机或其他容器访问则必须绑定所有接口。更多细节参见 security.md。相应地v0 兼容模式说明v0-compatibility.md中也指出run命令在--v0-compatible下默认绑定所有接口而非 localhost。八、升级 Go 集成切换到 v1 包官方建议使用 v0 SDK 与 v0 Rego 包的用户升级到新的 v1 包github.com/open-policy-agent/opa/v1/sdkgithub.com/open-policy-agent/opa/v1/rego升级只需修改 import 路径。例如import ( github.com/open-policy-agent/opa/rego )改为import ( github.com/open-policy-agent/opa/v1/rego )这适用于应用依赖的所有OPA 包而不只是rego和sdk其他常用包还包括ast、bundle、compile、types、topdown。自 OPA 1.0 起所有 v0 包均已弃用它们将在 OPA 1.0 的整个生命周期内保留但仍建议尽快升级。需要 v0 功能时仍可使用 v1 包详见 Backwards Compatibility。在 Go 集成中启用 v0.x 兼容若仍需处理 v0.x Rego官方推荐按粒度由粗到细的三种方式详见 v0-compatibility.md在模块上设置 Rego 版本首选粒度最细m : ast.Module{ Package: regoCode, } m.SetRegoVersion(ast.RegoV0)在 Bundle manifest 上设置 Rego 版本b : Bundle{ // ... } b.SetRegoVersion(ast.RegoV0)前两种方式更受推荐因为它们粒度更细允许同一 OPA 实例内混合运行 v0.x 与 v1.0 兼容的 Rego从而支持渐进式升级。使用SetRegoVersionRego 参数仅当前两种不适用时r : rego.New( rego.Query(data.foo.bar), rego.Module(policy.rego, regoCode), rego.SetRegoVersion(ast.RegoV1), // --- )此外也可以直接导入 v0 包github.com/open-policy-agent/opa/rego而非 v1 的.../opa/v1/rego编写程序。警告在同一程序中混用 v0 包与 v1 包被视为反模式不受推荐也不受支持两者间的互操作性没有保证。对于必须支持 v0 Bundle 的 SDK 用户应尽量按上文在 Bundle manifest 上设置 Rego 版本无法做到的用户需使用 v0 SDK 导入github.com/open-policy-agent/opa/sdk并应尽快将 Bundle 版本化以便切换到 v1 SDK。九、快速自查清单起点定位按 九场景矩阵 找到当前组合多数用户从 Scenario 1 起步顺序原则先升级 Producer再升级 Consumer能整体迁移时也允许一次性切换Rego 语法规则体前加if、多值规则用contains、移除孤立引用、检查重复导入、避免input/data遮蔽、替换已弃用内置函数渐进工具rego.v1导入、opa check --v0-v1、opa fmt --write --v0-v1、regal lintBundle 版本优先用v0.64.0构建带rego_version的 Bundle让消费端自动识别服务器行为v1.0 默认绑定 localhost需要对外时用--addr 0.0.0.0:8181Go 集成把rego/sdk/ast/bundle/compile/types/topdown等依赖切换到opa/v1/...路径。遵循上述路径即可在保留 v0.x 兼容性的前提下分阶段、可回滚地完成 OPA v1.0 与 Rego v1 的迁移。赞分享后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载相关推荐OPA 1.0 发布Rego v1 默认语法与 Policy as Code 升级指南OPA 1.0 发布Rego v1 默认语法与 Policy as Code 升级指南 OPAOpen Policy Agent在 2024 年 12 月后端认证鉴权云原生Open Policy Agent 1.0 全面前瞻Rego v1 语法变更、strict 默认化与迁移实践Open Policy Agent 1.0 全面前瞻Rego v1 语法变更、strict 默认化与迁移实践 OPAOpen Policy Agent1.后端认证鉴权云原生MDX Deck 迁移完全指南从 v1 到 v4 的升级路径与代码改造实战MDX Deck 迁移完全指南从 v1 到 v4 的升级路径与代码改造实战 MDX Deck 是一个基于 React 与 MDX 的演示文稿框架历经 v1→开发工具前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表