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 语法基础的整体结构,包括包声明、导入、规则定义以及数据类型之间的关系。

Rego 语法基础结构总览 包声明 package kubernetes.admission 导入语句 import data.resource.quota 规则定义 allow = true { ... } 数据类型 标量值 字符串、数字、布尔、null 复合值 数组、对象、集合 代码示例: # 标量值 cpu_limit := 1000 env := "production" # 复合值 resources := {"cpu": 2, "memory": "4Gi"}

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 的复合值支持嵌套和模式匹配,能够灵活表达复杂的资源配额约束。掌握标量值与复合值的组合使用,是编写高效策略的基础。