如何在OPA Rego中跨文件导入策略及函数?
解决Rego跨包调用函数时"undefined function"错误及相关场景处理
核心问题:跨包函数调用的正确方式
Rego中函数属于包级实体,不属于data命名空间,仅导入data.authorizer只能访问该包下的规则和数据,无法直接调用其中的函数。必须显式导入函数或整个包的函数成员。
示例修正
A.rego(authorizer包)
package authorizer decode_user(token) = user { // 示例解码逻辑:解析JWT格式token parts := split(token, ".") user := json.unbase64url(parts[1]) }
B.rego(user包)
选择以下任一导入方式:
- 直接导入目标函数
package user import data.authorizer.decode_user get_current_user = user { user := decode_user(input.auth_token) }
- 导入整个包并使用别名
package user import data.authorizer as auth get_current_user = user { user := auth.decode_user(input.auth_token) }
执行时的关键注意事项
运行opa eval时必须加载所有相关的Rego文件/目录,不能仅加载B.rego:
# 加载当前目录下所有Rego文件 opa eval -d . "data.user.get_current_user" --input '{"auth_token": "your-token-here"}'
嵌套策略包的处理
如果使用嵌套包结构(如authorizer.v1),需对应调整导入路径:
# 假设A.rego的包为authorizer.v1 import data.authorizer.v1.decode_user # 或 import data.authorizer.v1 as auth_v1
同时确保目录结构与包名匹配(如authorizer/v1/A.rego),OPA会自动识别嵌套包。
Go自定义函数导入场景
若要在Rego中调用Go实现的函数,无需在Rego中导入,需通过OPA的插件机制注册为内置函数:
Go代码中注册函数
package main import ( "encoding/json" "errors" "github.com/open-policy-agent/opa/rego" "github.com/open-policy-agent/opa/types" ) // 自定义解码函数 func decodeUser(token string) (map[string]interface{}, error) { if token == "" { return nil, errors.New("empty token") } // 模拟JWT解码逻辑 return map[string]interface{}{"id": "123", "role": "admin"}, nil } func main() { // 注册为OPA内置函数 rego.RegisterBuiltin(®o.Function{ Name: "decode_user", Decl: types.NewFunction(types.Args(types.String), types.A), // 参数为string,返回任意类型 Impl: decodeUser, }) // 后续可启动OPA服务或编译策略 // 例如编译包含自定义函数的策略:opa build -e data/user/get_current_user -o policy.tar.gz . }
Rego中直接调用
package user get_current_user = user { user := decode_user(input.auth_token) // 直接调用注册的Go函数 }
注意:若Rego包中已有同名函数,会发生冲突,需确保命名唯一。
内容的提问来源于stack exchange,提问作者equatorial_daydreamer
相关产品推荐
相关产品推荐

