Open Policy Agent(OPA) 【1】介绍(3)

简介: Open Policy Agent(OPA) 【1】介绍(3)

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


相关文章
|
存储 JSON Kubernetes
Open Policy Agent(OPA) 【2】rego 语法
Open Policy Agent(OPA) 【2】rego 语法
|
存储 SQL JSON
Open Policy Agent(OPA) 【1】介绍(2)
Open Policy Agent(OPA) 【1】介绍(2)
|
JSON Kubernetes Cloud Native
Open Policy Agent(OPA) 【1】介绍(1)
Open Policy Agent(OPA) 【1】介绍(1)
Open Policy Agent(OPA) 【1】介绍(1)
|
Cloud Native
Open Policy Agent (OPA) 【3】实战
Open Policy Agent (OPA) 【3】实战
Open Policy Agent (OPA) 【3】实战
|
6天前
|
人工智能 数据安全/隐私保护 UED
Agent AI智能体的未来
Agent AI智能体的未来
|
18天前
|
存储 人工智能 测试技术
【AI智能体】SuperAGI-开源AI Agent 管理平台
【4月更文挑战第9天】智能体管理平台SuperAGI简介及实践
|
20天前
|
人工智能 API 决策智能
【AI Agent系列】【阿里AgentScope框架】实战1:利用AgentScope实现动态创建Agent和自由组织讨论
【AI Agent系列】【阿里AgentScope框架】实战1:利用AgentScope实现动态创建Agent和自由组织讨论
131 2
|
20天前
|
人工智能 决策智能 C++
【AI Agent系列】【阿里AgentScope框架】5. Pipeline模块的组合使用及Pipeline模块总结
【AI Agent系列】【阿里AgentScope框架】5. Pipeline模块的组合使用及Pipeline模块总结
58 1
|
20天前
|
人工智能 决策智能
【AI Agent系列】【阿里AgentScope框架】4. 深入源码:Pipeline模块如何组织多智能体间的数据流?- 循环结构
【AI Agent系列】【阿里AgentScope框架】4. 深入源码:Pipeline模块如何组织多智能体间的数据流?- 循环结构
46 0
|
20天前
|
人工智能 决策智能
【AI Agent系列】【阿里AgentScope框架】3. 深入源码:Pipeline模块如何组织多智能体间的数据流?- 顺序结构与条件分支
【AI Agent系列】【阿里AgentScope框架】3. 深入源码:Pipeline模块如何组织多智能体间的数据流?- 顺序结构与条件分支
44 2