ARTICLE DETAIL

资讯详情

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

Open Policy Agent 错误解析:`rego_type_error` 多个 default 规则(multiple default rules)的成因与修复

Open Policy Agent 错误解析:`rego_type_error` 多个 default 规则(multiple default rules)的成因与修复 后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载default关键字用于为 Rego 规则定义兜底默认值当同名规则的所有条件分支均不匹配时该默认值才会生效。本文以 OPA 官方错误文档《multiple default rules》为核心讲解编译器在编译阶段compilationstage报出rego_type_error: multiple default rules rule found错误的成因、复现方式、跨文件排查技巧与修复方法并对照 OPA 源码v1/ast/compile.go与编译测试v1/ast/compile_test.go解释其底层检测逻辑帮助你在大规模策略中快速定位重复定义。错误概览是什么触发了这条错误OPA 的类型检查器在编译阶段会扫描同一个规则名下的全部default定义。按照 Rego 语义一条规则最多只能有一个default定义——default是特殊存在只允许为每个规则定义一个兜底值。当检测到同一规则存在多个default定义时编译器会抛出rego_type_error类别下的如下错误StageCategoryMessagecompilationrego_type_errormultiple default rules rule found需要注意两个关键点报错信息中的规则名是完整引用路径例如data.example.allow它会直接指出哪条规则出了问题错误信息中的行号只会显示第一个default定义的位置另一个重复定义并不会体现在行号里。这也是为什么单看报错行号往往定位不全必须配合全文搜索去查找。最小复现同一文件内的重复 default最简单的触发方式是在同一个 Rego 文件中为allow规则定义两次默认值package example default allow : false allow if input.admin default allow : false编译该策略会产生如下错误注意行号指向第一个default所在的位置policy.rego:5实际是第二个 default 的位置这里以官方示例为准展示错误文本形态1 error occurred: policy.rego:5: rego_type_error: multiple default rules data.example.allow found这类示例因为两处default相邻肉眼很容易发现。但在大型策略中两份default定义之间可能隔着几十行甚至上百行规则逻辑重复定义会变得非常隐蔽。跨文件场景default 分布在不同 Rego 文件中更隐蔽的情况是重复的default定义分别位于不同的 Rego 文件里而这些文件恰好处于同一个包package之下。例如# example1.rego package example default allow : false# example2.rego package example default allow : true使用opa eval同时加载两个文件$ opa eval data.example.allow -d example1.rego -d example2.rego 1 error occurred: example1.rego:3: rego_type_error: multiple default rules data.example.allow found这里再次印证报错指向的是example1.rego中第一个default的位置而真正重复的example2.rego并不会出现在错误行号里。排查技巧利用文件按字典序加载的特性:::info OPA 会按字典序lexicographical order加载文件因此在排查时可以临时重命名报错信息里提到的那个文件让加载顺序发生变化从而帮助定位另一份重复的default定义。 :::举例来说如果报错指向example1.rego而你怀疑重复定义在example2.rego中可以尝试把example1.rego临时改名为aaa_example1.rego或zzz_example1.rego再次运行同样的加载命令。由于加载顺序改变错误信息中显示的文件名/行号位置也会随之变化从而暴露出另一处default所在的位置。源码视角编译器如何检测多个 default 规则OPA 编译器对规则的冲突检查集中在StageCheckRuleConflicts阶段相关实现位于 v1/ast/compile.go仓库中该逻辑的完整实现可参见v1/ast/compile.go的checkRuleConflicts相关代码段。从源码结构看检测过程大致如下编译器按规则引用路径rule ref将同名规则聚合到同一节点统计该节点下所有规则头Head的类型单值完整规则SingleValue、多值集合规则MultiValue等专门统计default规则的个数即defaultRules列表的长度当len(defaultRules) 1时构造multiple default rules name found at ...的错误信息并将错误位置指向第一个default定义的模块包位置。源码中错误信息的拼接逻辑v1/ast/compile.go中len(defaultRules) 1分支会依次追加所有default定义的位置形如found at mod3.rego:3, mod3.rego:4这说明编译器实际上能够收集到全部重复定义的位置只是文档中示例展示的单行错误文本仅呈现了首个位置。测试用例佐证仓库中的编译测试 v1/ast/compile_test.go 对多种重复default场景做了覆盖同一文件内两条default相邻定义rego_type_error: multiple default rules data.badrules.defkw.foo found at mod3.rego:3, mod3.rego:4跨模块、通过引用路径ref rule与普通规则形成的重复defaultrego_type_error: multiple default rules data.pkg.p.q.r found at mod0.rego:2, mod1.rego:2rego_type_error: multiple default rules data.pkg.p.q.w.r found at mod0.rego:2, mod1.rego:2从这些测试可以看出多个 default 的检测是编译期compilation行为发生在求值eval之前因此使用opa eval、opa run、opa test或通过 SDK 编译策略时都会在启动阶段直接暴露该错误。如何修复修复通常分两种情况1. 两份 default 想设置相同的默认值 —— 删除重复定义如果两处default的值一致例如都是false直接删除其中一份即可。同时检查包内其他文件确保没有残留的第二份default# example1.rego保留 package example default allow : false# example2.rego删除其中的 default 行 package example allow if input.admin2. 两份 default 想设置不同的默认值 —— 拆分为两条不同的规则如果业务上确实需要两个不同的默认值default并不适合表达这种需求。官方建议改用两条不同的规则来实现差异化逻辑。例如将不同默认行为拆成allow_admin与allow_user两个独立规则再在调用侧按需引用。通用排查步骤以报错信息中的规则名为线索如data.example.allow在对应包内搜索default allow通常能直接命中所有重复定义记住重复定义可能分布在多个文件中搜索范围不要局限在报错提到的单个文件仅关注错误信息中package所指向的那个包避免被其他包中同名规则干扰。小结multiple default rules是 OPA 编译阶段常见的类型错误之一根因是同名规则被重复声明default。它的排查难点在于错误行号只指向首个定义位置因此需要借助全文搜索与文件按字典序加载的特性来定位另一处重复定义。理解其底层实现v1/ast/compile.go的规则冲突检查与测试用例v1/ast/compile_test.go后你可以在编写、评审或迁移大型 Rego 策略时快速识别并修复这类错误保持策略库的可编译性与可维护性。赞分享后端认证鉴权云原生【免费下载链接】opaOpen Policy Agent (OPA) is an open source, general-purpose policy engine.项目地址https://gitcode.com/gh_mirrors/op/opa点击查看免费下载相关推荐Open Policy Agent Rego 类型错误解析conflicting rules {name} found 的成因与修复Open Policy Agent Rego 类型错误解析conflicting rules {name} found 的成因与修复 导读 本篇文章聚焦 O后端认证鉴权云原生Cordis错误处理最佳实践ValidationError与配置校验全攻略Cordis错误处理最佳实践ValidationError与配置校验全攻略 Cordis 是一个以时空可组合性Spatiotemporal Composab后端认证鉴权云原生深入解析 Open Policy Agent Rego 编译错误 rego_recursion_errorrule is recursive 的成因、原理与修复深入解析 Open Policy Agent Rego 编译错误 rego_recursion_errorrule is recursive 的成因、原理与修后端认证鉴权云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表