Documentation de référence sur le langage du comparateur CEL

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 name1=value&name2=value2, telle qu'elle apparaît sur la première ligne de la requête HTTP.

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 true si la chaîne x correspond au modèle y RE2 spécifié.

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