3. Rego 语法基础:包声明、导入语句、规则定义、标量值与复合值
Rego 是 OPA 的策略语言,其语法设计围绕“策略即代码”的核心思想展开。理解 Rego 的语法基础是构建资源配额模型的前提。本章将系统讲解 Rego 的四大语法支柱:包声明、导入语句、规则定义以及标量值与复合值。
3.1 包声明(Package Declaration)
包是 Rego 中组织策略的逻辑单元,类似于命名空间。每个 Rego 文件必须以 package 关键字开头,声明该文件所属的包。包名使用点号(.)分隔层级,形成树状结构。
核心作用:避免策略规则之间的命名冲突,支持模块化复用。
# 声明一个名为 "kubernetes.admission" 的包
package kubernetes.admission
# 声明一个名为 "resource.quota" 的包
package resource.quota
| 包声明示例 | 说明 |
|---|---|
package kubernetes.admission |
用于 Kubernetes 准入控制策略 |
package resource.quota |
用于资源配额管理策略 |
package system |
OPA 系统内置包,用于定义决策入口 |
3.2 导入语句(Import Statement)
导入语句允许在当前包中引用其他包中定义的规则或数据。使用 import 关键字,支持导入整个包或包中的特定规则。
最佳实践:优先导入具体规则而非整个包,以提高策略的可读性和性能。
# 导入整个包
import data.kubernetes.namespaces
# 导入包中的特定规则
import data.resource.quota.max_cpu
# 为导入的规则设置别名
import data.resource.quota.max_memory as mem_limit
3.3 规则定义(Rule Definition)
规则是 Rego 策略的核心,用于定义决策逻辑。规则由头部(head)和体部(body)组成。头部定义规则名称和输出值,体部包含条件表达式。
3.3.1 完整规则(Complete Rule)
完整规则只有一个输出值,体部所有条件必须同时满足。
# 完整规则:如果命名空间有标签 "env=prod",则允许创建
allow_create {
input.metadata.labels.env == "prod"
}
3.3.2 部分规则(Partial Rule)
部分规则可以生成多个输出值,常用于集合或对象构建。
# 部分规则:返回所有允许的命名空间
allowed_namespaces[name] {
name := input.namespaces[_]
name != "default"
}
3.3.3 默认规则(Default Rule)
为规则提供默认值,避免未定义错误。
# 默认规则:默认允许
default allow = true
# 显式拒绝规则
allow = false {
input.cpu_requests > 1000
}
3.4 标量值与复合值
Rego 支持多种数据类型,分为标量值和复合值两大类。
3.4.1 标量值(Scalar Values)
标量值是单一数据单元,包括字符串、数字、布尔值和 null。
| 类型 | 示例 | 说明 |
|---|---|---|
| 字符串 | "production" |
双引号包裹 |
| 数字 | 1024、3.14 |
整数和浮点数 |
| 布尔值 | true、false |
逻辑判断 |
| null | null |
空值 |
3.4.2 复合值(Composite Values)
复合值由多个标量值或其他复合值组合而成,包括数组、对象和集合。
# 数组(Array):有序列表
["cpu", "memory", "storage"]
# 对象(Object):键值对
{"name": "quota-a", "limit": 1000}
# 集合(Set):无序唯一值
{"prod", "staging", "dev"}
注意:集合中的元素必须是唯一的,且不能包含重复值。集合常用于去重和成员关系检查。
3.5 语法结构总览
以下 SVG 图展示了 Rego 语法基础的整体结构,包括包声明、导入、规则定义以及数据类型之间的关系。
3.6 规则类型对比
理解不同规则类型的适用场景,有助于在资源配额模型中做出正确选择。
| 规则类型 | 输出值数量 | 典型用途 | 示例 |
|---|---|---|---|
| 完整规则 | 1 个 | 布尔决策(允许/拒绝) | allow = true { ... } |
| 部分规则 | 多个 | 生成集合或对象 | quota[name] = limit { ... } |
| 默认规则 | 1 个(兜底) | 提供默认行为 | default allow = false |
3.7 复合值操作示例
在资源配额模型中,复合值常用于描述资源规格和约束条件。以下示例展示了如何在规则中使用复合值。
# 定义资源配额对象
quota_limits := {
"cpu": {"max": 8, "min": 0.5},
"memory": {"max": "32Gi", "min": "1Gi"},
"pods": {"max": 100, "min": 1}
}
# 检查 CPU 请求是否在配额范围内
cpu_in_range {
input.resources.cpu <= quota_limits.cpu.max
input.resources.cpu >= quota_limits.cpu.min
}
# 检查命名空间是否在允许列表中
allowed_ns := {"prod", "staging", "dev"}
ns_allowed {
input.namespace in allowed_ns
}
关键要点:Rego 的复合值支持嵌套和模式匹配,能够灵活表达复杂的资源配额约束。掌握标量值与复合值的组合使用,是编写高效策略的基础。