一般運算語言 (CEL) 是一種開放原始碼的非圖靈完備語言,可實作運算式評估的常見語意。Service Extensions 會使用部分 CEL 條件,根據屬性資料做出鏈結評估決策。一般來說,條件運算式是由一或多個陳述式組成,並以邏輯運算子 (&&、|| 或 !) 連結。
屬性
對於任何連線要求,Proxy 都會擷取屬性,也就是一組情境資訊。屬性具有固定型別 (例如 string 或 int),且可能會視情況存在或不存在。在處理相符條件期間,屬性會公開給 CEL 執行階段。
屬性無法傳送至擴充服務。
要求屬性
您可以從要求中擷取下列屬性:
| 屬性 | 屬性類型 | 說明 |
|---|---|---|
request.headers |
map{string,string} | HTTP 要求標頭的字串對字串對應。如果標頭含有多個值,這項對應中的值會是以半形逗號分隔的字串,當中包含標頭的所有值。這項對應中的鍵都是小寫。 |
request.method |
字串 | HTTP 要求方法,例如 GET 或 POST。 |
request.host |
字串 | 功用相當於 request.headers['host']。
|
request.path |
字串 | 要求的 HTTP 網址路徑。 |
request.query |
字串 | HTTP 網址查詢,格式為 未執行任何解碼作業。 |
request.scheme |
字串 | HTTP 網址通訊協定,例如 HTTP 或 HTTPS。這個屬性的值為小寫。 |
request.backend_service_name |
字串 | 要求預計轉送到的後端服務。 不適用於邊緣擴充功能。 |
request.backend_service_project_number |
整數 | 使用共用虛擬私有雲時,要求預計轉送到的後端服務專案數量。 不適用於邊緣擴充功能。 |
連線屬性
您可以從連線擷取下列屬性:
| 屬性 | 屬性類型 | 說明 |
|---|---|---|
source.ip |
字串 | 要求的來源 IP 位址。 |
source.port |
整數 | 下游用戶端的連線埠。 |
connection.sni |
字串 | 下游 TLS 連線中要求的伺服器名稱。 |
connection.tls_version |
字串 | 下游 TLS 連線的 TLS 版本。有效值:TLSv1、TLSv1.1、TLSv1.2 和 TLSv1.3。 |
connection.sha256_peer_certificate_digest |
字串 | 下游 TLS 連線中的對等互連憑證十六進位編碼 SHA256 雜湊 (如有)。 |
運算子
服務擴充功能支援多種運算子,您可以使用這些運算子,從簡單的運算式陳述式建立複雜的相符條件。服務擴充功能支援邏輯運算子 (例如 &&、|| 和 !) 和字串操控運算子 (例如 x.contains('y'))。
字串操控運算子會比對您定義的字串或子字串。舉例來說,如果 HTTP 要求是傳送至結尾為 example.com 的網域,則 request.host.endsWith('.example.com') 的評估結果為 true。
邏輯運算子可讓您在條件運算式中驗證多個變數。舉例來說,request.method == 'GET' && request.host.matches('.example.com') 會結合兩個陳述式,且兩個陳述式都必須為 true,才能產生 true 的整體結果。
邏輯運算子
下表說明服務擴充功能支援的邏輯運算子。
| 運算式範例 | 說明 |
|---|---|
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,系統會傳回錯誤,導致評估中的規則不符。 |
字串操控運算子
下表說明服務擴充功能支援的字串操控運算子。
| 運算式 | 說明 |
|---|---|
x.contains(y) |
如果字串 x 包含子字串 y,就會傳回 true。 |
x.startsWith(y) |
如果字串 x 以子字串 y 開頭,則傳回 true。 |
x.endsWith(y) |
如果字串 x 以子字串 y 結尾,則傳回 true。 |
x.matches(y) |
如果字串 服務擴充功能在編譯 RE2 模式時,會使用 RE2::Latin1 選項,該選項會停用 Unicode 功能。 邊緣擴充功能只允許每個 CEL 運算式使用一個規則運算式。 |
x.lower() |
傳回字串 x 的小寫值。 |
x.upper() |
傳回字串 x 的大寫值。 |
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 的所有要求:
request.path.endsWith("/inventory") && request.headers["Hello"] != ""
限制
為服務擴充功能指定 CEL 運算式時,有以下限制:
- 每個擴充功能的運算式上限:邊緣擴充功能為 1 個,其他擴充功能為 5 個
- 每個規則運算式的字元數上限:100
- 每個 CEL 運算式的字元數上限:500