8.6.2 部分规则
部分规则是if-then
语句,它们生成一组值并将该组值分配给变量。例如:
package example.rules public_network[net.id] { # net.id is in the public_network set if... net := input.networks[_] # some network exists and... net.public # it is public. }
在上面的示例中public_network[net.id]
是规则头,并且net := input.networks[_]
; net.public
是规则主体。您可以像查询其他任何值一样查询整个值集:
public_network [ "net3", "net4" ]
您可以通过使用变量引用set
元素来遍历值集:
some n; public_network[n] +--------+-------------------+ | n | public_network[n] | +--------+-------------------+ | "net3" | "net3" | | "net4" | "net4" | +--------+-------------------+
最后,您可以使用相同的语法检查集合中是否存在值:
public_network["net3"] "net3"
除了部分定义集合外,您还可以部分定义键/值对(也称为对象)。有关更多信息,请参见 语言指南中的规则。
8.7 语法示例
以上各节介绍了Rego的核心概念。综上所述,让我们回顾一下所需的策略(英语):
Servers reachable from the Internet must not expose the insecure ‘http’ protocol.
从Internet可访问的服务器不能暴露不安全的“http”协议。
Servers are not allowed to expose the ‘telnet’ protocol.
服务器不允许公开’telnet’协议。
在较高级别,该策略需要识别违反某些条件的服务器。为了实施此策略,我们可以定义称为的规则violation ,这些规则生成一组违反的服务器。
例如:
package example allow = true { # allow is true if... count(violation) == 0 # there are zero violations. } violation[server.id] { # a server is in the violation set if... some server public_server[server] # it exists in the 'public_server' set and... server.protocols[_] == "http" # it contains the insecure "http" protocol. } violation[server.id] { # a server is in the violation set if... server := input.servers[_] # it exists in the input.servers collection and... server.protocols[_] == "telnet" # it contains the "telnet" protocol. } public_server[server] { # a server exists in the public_server set if... some i, j server := input.servers[_] # it exists in the input.servers collection and... server.ports[_] == input.ports[i].id # it references a port in the input.ports collection and... input.ports[i].network == input.networks[j].id # the port references a network in the input.networks collection and... input.networks[j].public # the network is public. }
some x; violation[x] +-----------+--------------+ | x | violation[x] | +-----------+--------------+ | "ci" | "ci" | | "busybox" | "busybox" | +-----------+--------------+
9. 将 OPA 用作Go库
OPA可以作为库嵌入到Go程序中。将OPA嵌入为库的最简单方法是导入github.com/open-policy-agent/opa/rego
软件包。
import "github.com/open-policy-agent/opa/rego"
调用该rego.New
函数以创建可以准备或评估的对象:
r := rego.New( rego.Query("x = data.example.allow"), rego.Load([]string{"./example.rego"}, nil))
支持多种选项自定义的评价。有关详细信息,请参见GoDoc页面。构造新rego.Rego对象后,您可以调用 PrepareForEval()以获得可执行查询。如果PrepareForEval()失败,则表明传递给rego.New()调用的选项之一无效(例如,解析错误,编译错误等)
ctx := context.Background() query, err := r.PrepareForEval(ctx) if err != nil { // handle error }
可以将准备好的查询对象缓存在内存中,在多个goroutine
中共享,并使用不同的输入重复调用。调用Eval()
以执行准备好的查询。
bs, err := ioutil.ReadFile("./input.json") if err != nil { // handle error } var input interface{} if err := json.Unmarshal(bs, &input); err != nil { // handle error } rs, err := query.Eval(ctx, rego.EvalInput(input)) if err != nil { // handle error }
该策略决策包含在Eval()调用返回的结果中。您可以检查该决定并进行相应处理:
// In this example we expect a single result (stored in the variable 'x'). fmt.Println("Result:", rs[0].Bindings["x"])
您可以将上述步骤组合到一个简单的命令行程序中,该程序可以评估策略并输出结果:
main.go:
package main import ( "context" "encoding/json" "fmt" "log" "os" "github.com/open-policy-agent/opa/rego" ) func main() { ctx := context.Background() // Construct a Rego object that can be prepared or evaluated. r := rego.New( rego.Query(os.Args[2]), rego.Load([]string{os.Args[1]}, nil)) // Create a prepared query that can be evaluated. query, err := r.PrepareForEval(ctx) if err != nil { log.Fatal(err) } // Load the input document from stdin. var input interface{} dec := json.NewDecoder(os.Stdin) dec.UseNumber() if err := dec.Decode(&input); err != nil { log.Fatal(err) } // Execute the prepared query. rs, err := query.Eval(ctx, rego.EvalInput(input)) if err != nil { log.Fatal(err) } // Do something with the result. fmt.Println(rs) }
运行以下代码,如下所示:
go run main.go example.rego 'data.example.violation' < input.json [{[[ci busybox]] map[]}]
参考:
Open Policy Agent(OPA) 【1】介绍
Open Policy Agent(OPA) 【2】rego语法
Open Policy Agent(OPA) 【3】实战
云原生圣经
openpolicyagent官网
Open Policy Agent: What Is OPA and How It Works (Examples)
Open Policy Agent: Authorization in a Cloud Native World