求助:OPA AST库无法反序列化含some关键字的JSON AST
问题:OPA JSON AST反序列化失败(含
some关键字时) 问题背景
将OPA生成的JSON格式AST反序列化为Go的ast.Module结构体时,只要Rego代码中包含some关键字,就会触发错误:panic: ast: unable to unmarshal term.
相关代码与输出
1. Rego策略代码(policy.rego)
package example.authz import rego.v1 allow if { some i input.users[i].role == "admin" }
2. 生成JSON AST的命令
opa parse --v1-compatible --format json policy.rego
3. 生成的JSON AST内容
{ "package": { "path": [ { "type": "var", "value": "data" }, { "type": "string", "value": "example" }, { "type": "string", "value": "authz" } ] }, "imports": [ { "path": { "type": "ref", "value": [ { "type": "var", "value": "rego" }, { "type": "string", "value": "v1" } ] } } ], "rules": [ { "body": [ { "index": 0, "terms": { "symbols": [ { "type": "var", "value": "i" } ] } }, { "index": 1, "terms": [ { "type": "ref", "value": [ { "type": "var", "value": "equal" } ] }, { "type": "ref", "value": [ { "type": "var", "value": "input" }, { "type": "string", "value": "users" }, { "type": "var", "value": "i" }, { "type": "string", "value": "role" } ] }, { "type": "string", "value": "admin" } ] } ], "head": { "name": "allow", "value": { "type": "boolean", "value": true }, "ref": [ { "type": "var", "value": "allow" } ] } } ] }
4. 反序列化的Go代码
var module ast.Module module.SetRegoVersion(ast.RegoV1) if err = module.UnmarshalJSON(b); err != nil { panic(err) }
5. 错误信息
panic: ast: unable to unmarshal term.
解决方案
问题根源是opa parse生成的JSON中,some i的结构不符合ast.Module反序列化的预期格式——some关键字需要被标记为特定类型的term,而非当前的terms.symbols结构。有两种解决方式:
方式1:直接解析Rego源代码(推荐)
跳过JSON转换步骤,用OPA原生API直接解析Rego代码到ast.Module,这是最可靠的方案:
import ( "os" "github.com/open-policy-agent/opa/ast" "github.com/open-policy-agent/opa/parser" ) func main() { // 读取Rego文件内容 regoContent, err := os.ReadFile("policy.rego") if err != nil { panic(err) } // 解析为ast.Module module, err := parser.ParseModule("policy.rego", string(regoContent)) if err != nil { panic(err) } }
方式2:修正JSON AST结构
如果必须使用JSON AST,需要手动调整some i对应的节点结构:
原错误节点:
{ "index": 0, "terms": { "symbols": [ { "type": "var", "value": "i" } ] } }
修改为符合要求的格式:
{ "index": 0, "terms": [ { "type": "some", "value": [ { "type": "var", "value": "i" } ] } ] }
调整后再执行反序列化即可成功。
内容的提问来源于stack exchange,提问作者user27911082
相关产品推荐
相关产品推荐

