Le CEL (Common Expression Language) est un langage Open Source non Turing-complet qui implémente une sémantique commune pour l'évaluation des expressions. Les extensions de service utilisent un sous-ensemble de conditions CEL pour prendre des décisions d'évaluation de chaîne basées sur des données d'attribut. En général, une expression de condition contient une ou plusieurs instructions qui sont combinées par des opérateurs logiques (&&, || ou !).
Attributs
Pour chaque demande de connexion, le proxy extrait des attributs, qui sont un ensemble d'informations contextuelles. Les attributs ont un type fixe (tel que string ou int) et peuvent être absents ou présents, selon le contexte.
Les attributs sont exposés au runtime CEL lors du traitement des conditions de correspondance.
Les attributs ne peuvent pas être envoyés à un service d'extension.
Attributs de requête
Les attributs suivants peuvent être extraits des requêtes :
| Attribut | Type d'attribut | Description |
|---|---|---|
request.headers |
map{string,string} | Mappage chaîne à chaîne des en-têtes de requête HTTP. Si un en-tête contient plusieurs valeurs, la valeur de ce mappage est une chaîne comportant toutes les valeurs de l'en-tête séparées par une virgule. Les clés de ce mappage sont en minuscules. |
request.method |
string | Méthode de requête HTTP, telle que GET ou POST. |
request.host |
string | Équivalent de commodité à request.headers['host'].
|
request.path |
string | Chemin d'URL HTTP demandé. |
request.query |
string | Requête d'URL HTTP au format Aucun décodage n'est effectué |
request.scheme |
string | Schéma d'URL HTTP tel que HTTP ou HTTPS. Les valeurs de cet attribut sont en minuscules. |
request.backend_service_name |
string | Service de backend auquel la requête est transférée. Non applicable aux extensions Edge. |
request.backend_service_project_number |
int | Lorsqu'un VPC partagé est utilisé, il s'agit du numéro de projet du service de backend auquel la requête est transférée. Non applicable aux extensions Edge. |
Attributs de connexion
Les attributs suivants peuvent être extraits des connexions :
| Attribut | Type d'attribut | Description |
|---|---|---|
source.ip |
string | Adresse IP source de la requête. |
source.port |
int | Port de connexion du client en aval. |
connection.sni |
string | Nom de serveur demandé de la connexion TLS en aval. |
connection.tls_version |
string | Version TLS de la connexion TLS en aval. Valeurs valides : TLSv1, TLSv1.1, TLSv1.2 et TLSv1.3.
|
connection.sha256_peer_certificate_digest |
string | Hachage SHA256 du certificat de pair dans la connexion TLS en aval, encodé en hexadécimal, le cas échéant. |
Opérateurs
Les extensions de service sont compatibles avec plusieurs opérateurs que vous pouvez utiliser pour créer des conditions de correspondance complexes à partir d'instructions d'expression simples.
Les extensions de service sont compatibles avec les opérateurs logiques (&&, || et !, par exemple) et les opérateurs de manipulation de chaînes (x.contains('y'), par exemple).
Les opérateurs de manipulation de chaînes correspondent aux chaînes ou sous-chaînes que vous définissez. Par exemple, request.host.endsWith('.example.com') renvoie true si la requête HTTP a été envoyée à un domaine se terminant par example.com.
Les opérateurs logiques vous permettent de vérifier plusieurs variables dans une expression conditionnelle. Par exemple, request.method == 'GET' && request.host.matches('.example.com') combine deux instructions et exige que les deux instructions soient true pour produire un résultat global de true.
Opérateurs logiques
Le tableau suivant décrit les opérateurs logiques compatibles avec les extensions de service.
| Exemple d'expression | Description |
|---|---|
x == "foo" |
Renvoie true si x est égal à l'argument littéral de chaîne constante. |
x == R"fo'o" |
Renvoie true si x est égal au littéral de chaîne brute donné qui n'interprète pas les séquences d'échappement. Les littéraux de chaîne brute sont pratiques pour exprimer des chaînes que le code doit utiliser pour échapper aux caractères de séquence. |
x == y |
Renvoie true si x est égal à y. |
x != y |
Renvoie true si la valeur de x n'est pas égale à y. |
x && y |
Renvoie true si x et y sont tous les deux true. |
x || y |
Renvoie true si x, y ou les deux sont true. |
!x |
Renvoie true si la valeur booléenne x est false, ou renvoie false si la valeur booléenne x est true. |
m['k'] |
Si la clé k est présente, renvoie la valeur à la clé k dans le mappage chaîne à chaîne m. Si la clé k n'est pas présente, une erreur est renvoyée, ce qui empêche la règle en cours d'évaluation de correspondre. |
Opérateurs de manipulation de chaînes
Le tableau suivant décrit les opérateurs de manipulation de chaînes compatibles avec les extensions de service.
| Expression | Description |
|---|---|
x.contains(y) |
Renvoie true si la chaîne x contient la sous-chaîne y. |
x.startsWith(y) |
Renvoie true si la chaîne x commence par la sous-chaîne y. |
x.endsWith(y) |
Renvoie true si la chaîne x se termine par la sous-chaîne y. |
x.matches(y) |
Renvoie Les extensions de service utilisent l'option RE2::Latin1 lorsqu'elles compilent le modèle RE2, ce qui désactive les fonctionnalités Unicode. Les extensions Edge ne vous permettent d'utiliser qu'une seule expression régulière par expression CEL. |
x.lower() |
Renvoie la valeur en minuscules de la chaîne x. |
x.upper() |
Renvoie la valeur en majuscules de la chaîne x. |
int(x) |
Convertit le résultat de chaîne de x en type int. Vous pouvez utiliser la chaîne convertie pour établir une comparaison d'entiers à l'aide d'opérateurs arithmétiques standards, tels que supérieur à (>) et inférieur ou égal à (≤). Cela ne fonctionne que pour les valeurs qui peuvent être des entiers. |
Exemples d'expressions
Faire correspondre toutes les requêtes adressées à l'hôte example.com avec le service de backend bs1 de la région 123, lequel fait office de destination finale :
request.host == "example.com" && request.backend_service_name == "bs1" && request.backend_service_project_number == 123
Faire correspondre toutes les requêtes liées au chemin d'accès */inventory avec un en-tête HTTP Hello :
request.path.endsWith("/inventory") && request.headers["Hello"] != ""
Limites
Les limites suivantes s'appliquent aux expressions CEL lorsqu'elles sont spécifiées pour les extensions de service :
- Nombre maximal d'expressions par extension : 1 pour les extensions Edge et 5 pour les autres extensions
- Nombre maximal de caractères par expression régulière : 100
- Nombre maximal de caractères par expression CEL : 500