CEL 匹配器语言参考文档

通用表达式语言 (CEL) 是一种开源的非图灵完备语言,可实现表达式求值的通用语义。Service Extensions 使用 CEL 条件的子集,根据特性数据做出链评估决策。通常,条件表达式由一个或多个使用逻辑运算符(&&、|| 或 !)联接的语句组成。

属性

对于任何给定的连接请求,代理都会提取属性,这些属性是一组上下文信息。属性具有固定类型(例如 string 或 int),并且可能存在或不存在,具体取决于上下文。在匹配条件处理期间,属性会向 CEL 运行时公开。如需将特定属性转发到扩展服务或插件,请使用 forwardAttributes 字段。如需了解详情,请参阅支持的属性。

请求属性

您可以从请求中提取以下属性:

属性 类型 LbEdge LbRoute LbTraffic Authz CdnEdge 说明
request.headers 地图 ✓ ✓ ✓ ✓ ✓ HTTP 请求标头的字符串到字符串映射,其中所有键均为小写。
request.method 字符串 ✓ ✓ ✓ ✓ ✓ HTTP 请求方法(例如 GET、POST)。
request.host 字符串 ✓ ✓ ✓ ✓ ✓ 等同于 request.headers['host']。
request.path 字符串 ✓ ✓ ✓ ✓ ✓ 所请求的 HTTP 网址路径。
request.query 字符串 ✓ ✓ ✓ ✓ ✓ 网址查询字符串 (name1=value&name2=value2)。
request.scheme 字符串 ✓ ✓ ✓ ✓ ✓ 网址协议(http 或 https)。
request.backend_service_name 字符串 — ✓ ✓ — — 后端服务名称。
request.backend_service_project_number 整数 — ✓ ✓ — — 后端服务项目编号。

连接特性

您可以从连接中提取以下属性:

属性 类型 LbEdge LbRoute LbTraffic Authz CdnEdge 说明
source.ip 字符串 ✓ ✓ ✓ ✓ — 客户端 IP 地址。
source.port 整数 ✓ ✓ ✓ ✓ ✓ 客户端连接端口号。
source.client_region 字符串 ✓ — ✓ — ✓ 由两个字母组成的客户端国家/区域代码。
connection.sni 字符串 ✓ — ✓ ✓ ✓ 下游 TLS 服务器名称指示。
connection.tls_version 字符串 ✓ — ✓ ✓ ✓ 下行 TLS 版本(例如 TLSv1.2、TLSv1.3)。
connection.sha256_peer_certificate_digest 字符串 ✓ — ✓ ✓ — 对等证书 SHA-256 摘要。

运算符

Service Extensions 支持多种运算符,您可以使用这些运算符通过简单的表达式语句构建复杂的匹配条件。Service Extensions 支持逻辑运算符(例如 &&、|| 和 !)以及字符串操作运算符(例如 x.contains('y'))。

字符串操作运算符会匹配您定义的字符串或子字符串。例如,如果向以 example.com 结尾的网域发出 HTTP 请求,则 request.host.endsWith('.example.com') 的求值结果为 true。

逻辑运算符可让您在条件表达式中验证多个变量。例如,request.method == 'GET' && request.host.matches('.example.com') 连接了两个语句,并且要求这两个语句都为 true,才能生成总体结果 true。

逻辑运算符

下表介绍了 Service Extensions 支持的逻辑运算符。

示例表达式 说明
x == "foo" 如果 x 等于常量字符串字面量实参,则返回 true。
x == R"fo'o" 如果 x 等于不解释转义序列的指定原始字符串字面量,则返回 true。原始字符串字面量便于表示代码必须使用转义序列字符的字符串。
x == y 如果 x 等于 y,则返回 true。
x != y 如果 x 不等于 y,则返回 true。
x && y 如果 x 和 y 均为 true,则返回 true。
x || y 如果 x、y 或两者均为 true,则返回 true。
!x 如果布尔值 x 为 false,则返回 true;如果布尔值 x 为 true,则返回 false。
m['k'] 如果键 k 存在,则返回字符串到字符串映射 m 中的键 k 处的值。如果键 k 不存在,则返回一个错误,导致正在评估的规则不匹配。
k in m 如果键 k 存在于字符串键控映射 m 中,则返回 true。否则,返回 false。

字符串操作运算符

下表介绍了 Service Extensions 支持的字符串操作运算符。

表达式 说明
x.contains(y) 如果字符串 x 包含子字符串 y,则返回 true。
x.startsWith(y) 如果字符串 x 以子字符串 y 开头,则返回 true。
x.endsWith(y) 如果字符串 x 以子字符串 y 结尾,则返回 true。
x.matches(y)

如果字符串 x 与指定的 RE2 模式 y 匹配,则返回 true。

Service Extensions 在编译 RE2 模式时会使用 RE2::Latin1 选项,该选项会停用 Unicode 功能。

Edge 扩展程序仅允许每个 CEL 表达式使用一个正则表达式。

int(x) 将字符串结果 x 转换为 int 类型。您可以使用标准算术运算符(例如大于 [>] 和小于或等于 [≤])将转换后的字符串用于整数比较。这仅适用于可以为整数的值。

示例表达式

匹配发送给主机 example.com 并将 123 中的后端服务 bs1 作为最终目的地的所有请求:

request.host == "example.com" && request.backend_service_name == "bs1" &&
  request.backend_service_project_number == 123

匹配路径为 */inventory 且包含 HTTP 标头 Hello 的所有请求。请注意,对于 CEL 匹配,标头名称不区分大小写:

request.path.endsWith("/inventory") && "Hello" in request.headers

限制

为 Service Extensions 指定 CEL 表达式时,存在以下限制:

  • 每个扩展程序的表达式数量上限:边缘扩展程序为 1,其他扩展程序为 5
  • 每个正则表达式的字符数上限:100
  • 每个 CEL 表达式的字符数上限:500