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

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