Common Expression Language(CEL)は、式の評価に共通のセマンティクスを実装するオープンソースの非チューリング完全言語です。サービス拡張機能は、CEL 条件のサブセットを使用して、属性データに基づいてチェーン評価の決定を行います。一般に、条件式は論理演算子(&&、||、または !)で結合された 1 つ以上のステートメントから構成されます。
属性
プロキシは、接続リクエストごとに、コンテキスト情報のセットである属性を抽出します。属性には固定の型(string や int など)があり、コンテキストに応じて存在する場合と存在しない場合があります。属性は、一致条件の処理中に CEL ランタイムに公開されます。属性を拡張サービスに送信することはできません。
リクエストの属性
リクエストから次の属性を抽出できます。
| 属性 | 属性タイプ | 説明 |
|---|---|---|
request.headers |
map{string,string} | HTTP リクエスト ヘッダーの文字列間マップヘッダーに複数の値が含まれている場合、このマップの値はヘッダーのすべての値のカンマ区切り文字列になります。このマップのキーは小文字です。 |
request.method |
文字列 | GET や POST などの HTTP リクエスト メソッド。 |
request.host |
文字列 | request.headers['host'] と同等の利便性。 |
request.path |
文字列 | リクエストした HTTP URL パス。 |
request.query |
文字列 | HTTP リクエストの第 1 行に現れるような、 デコードは行われません。 |
request.scheme |
文字列 | HTTP URL スキーム(HTTP、HTTPS など)。この属性の値はすべて小文字です。 |
request.backend_service_name |
文字列 | リクエストが転送されるバックエンド サービス。 エッジ拡張機能には適用されません。 |
request.backend_service_project_number |
int | 共有 VPC を使用する場合の、リクエストが転送されるバックエンド サービスのプロジェクト番号。 エッジ拡張機能には適用されません。 |
接続属性
接続から次の属性を抽出できます。
| 属性 | 属性タイプ | 説明 |
|---|---|---|
source.ip |
文字列 | リクエストの送信元 IP アドレス。 |
source.port |
int | ダウンストリーム クライアントの接続ポート。 |
connection.sni |
文字列 | ダウンストリーム TLS 接続でリクエストされたサーバー名。 |
connection.tls_version |
文字列 | ダウンストリーム TLS 接続の TLS バージョン。有効な値: TLSv1、TLSv1.1、TLSv1.2、TLSv1.3。 |
connection.sha256_peer_certificate_digest |
文字列 | ダウンストリーム TLS 接続内のピア証明書の SHA256 ハッシュ(16 進数でエンコード)。存在する場合。 |
演算子
サービス拡張機能では、単純な式のステートメントから複雑な一致条件を作成するために使用できる演算子がいくつかサポートされています。Service Extensions では、&&、||、! などの論理演算子と、x.contains('y') などの文字列操作演算子がサポートされています。
文字列操作演算子は、定義した文字列または部分文字列と照合します。たとえば、HTTP リクエストが example.com で終わるドメインに対して行われた場合、request.host.endsWith('.example.com') は true と評価されます。
論理演算子を使用すると、条件式で複数の変数を検証できます。たとえば、request.method == 'GET' && request.host.matches('.example.com') は 2 つのステートメントを結合し、全体的な結果として 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 が存在しない場合は、評価中のルールが一致しないエラーを返します。 |
文字列操作演算子
次の表に、サービス拡張機能がサポートする文字列操作演算子を示します。
| 式 | 説明 |
|---|---|
x.contains(y) |
文字列 x に部分文字列 y が含まれている場合、true を返します。 |
x.startsWith(y) |
文字列 x が部分文字列 y で始まる場合、true を返します。 |
x.endsWith(y) |
文字列 x が部分文字列 y で終わる場合、true を返します。 |
x.matches(y) |
文字列 Service Extensions は、RE2 パターンをコンパイルするときに RE2::Latin1 オプションを使用します。これにより、Unicode 機能が無効になります。 Edge 拡張機能では、CEL 式ごとに 1 つの正規表現のみを使用できます。 |
x.lower() |
文字列 x の小文字の値を返します。 |
x.upper() |
文字列 x の大文字の値を返します。 |
int(x) |
x の文字列の結果を int 型に変換します。変換された文字列は、大なり(>)や小なりイコール(≤)などの標準の算術演算子を使用して整数の比較に使用できます。これは、値が整数とみなされる場合に限り機能します。 |
式のサンプル
123 のバックエンド サービス bs1 を最終宛先とするホスト example.com へのすべてのリクエストにマッチさせる:
request.host == "example.com" && request.backend_service_name == "bs1" && request.backend_service_project_number == 123
HTTP ヘッダー Hello を持つパス */inventory に対するすべてのリクエストをマッチングします。
request.path.endsWith("/inventory") && request.headers["Hello"] != ""
制限事項
サービス拡張機能に指定された CEL 式には、次の制限が適用されます。
- 拡張機能あたりの式の最大数: エッジ拡張機能の場合は 1、その他の拡張機能の場合は 5
- 正規表現あたりの最大文字数: 100
- CEL 式あたりの最大文字数: 500