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 en fonction 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 toute requête de connexion donnée, 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 à l'environnement d'exécution 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 |
chaîne | Méthode de requête HTTP, telle que GET ou POST. |
request.host |
chaîne | Équivalent pratique de request.headers['host'].
|
request.path |
chaîne | Chemin d'URL HTTP demandé. |
request.query |
chaîne | Requête d'URL HTTP au format
Aucun décodage n'est effectué |
request.scheme |
chaîne | Schéma d'URL HTTP tel que HTTP ou HTTPS. Les valeurs de cet attribut sont en minuscules. |
request.backend_service_name |
chaîne | Service de backend auquel la requête est transférée. Ne s'applique pas aux extensions de périphérie. |
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. Ne s'applique pas aux extensions de périphérie. |
Attributs de connexion
Les attributs suivants peuvent être extraits des connexions :
| Attribut | Type d'attribut | Description |
|---|---|---|
source.ip |
chaîne | Adresse IP source de la requête. |
source.port |
int | Port de connexion du client en aval. |
connection.sni |
chaîne | Nom de serveur demandé de la connexion TLS en aval. |
connection.tls_version |
chaîne | Version TLS de la connexion TLS en aval. Valeurs valides :
TLSv1, TLSv1.1, TLSv1.2 et
TLSv1.3.
|
connection.sha256_peer_certificate_digest |
chaîne | Hachage SHA256 du certificat de pair encodé en hexadécimal dans la connexion TLS en aval, le cas échéant. |
Opérateurs
Service Extensions est compatible avec plusieurs opérateurs que vous pouvez utiliser pour créer des conditions de correspondance complexes à partir d'instructions d'expression simples.
Service Extensions prend en charge les opérateurs logiques, tels que &&, || et !, ainsi que les opérateurs de manipulation de chaînes, tels que x.contains('y').
Les opérateurs de manipulation de chaînes mettent en correspondance les chaînes ou les 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 nécessite que les deux soient true pour produire un
résultat global 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 les caractères de séquence. |
x == y |
Renvoie true si x est égal à
y. |
x != y |
Renvoie true si x n'est pas égal à
y. |
x && y |
Renvoie true si x et y
sont 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, renvoie une erreur qui
empêche la règle en cours d'évaluation de correspondre. |
k in m |
Renvoie true si la clé k est présente dans le mappage à clé de chaîne m. Sinon, renvoie
false. |
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 Service Extensions utilise l'option RE2::Latin1 lorsqu'il compile le modèle RE2, ce qui désactive les fonctionnalités Unicode. Les extensions de périphérie 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 la chaîne x en type int. Vous pouvez utiliser la chaîne convertie pour la 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. Notez que les noms d'en-têtes ne sont pas sensibles à la casse pour la correspondance CEL :
request.path.endsWith("/inventory") && "Hello" in request.headers
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 de périphérie 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