Common Expression Language in Kubernetes [page]deterministic
The [Common Expression Language (CEL)](https://github.com/google/cel-go) is used in the Kubernetes API to declare validation rules, policy rules, and other constraints or conditions.
CEL expressions are evaluated directly in the [API server](#gloss:kube-apiserver), making CEL a convenient alternative to out-of-process mechanisms, such as webhooks, for many extensibility use cases. Your CEL expressions continue to execute so long as the control plane's API server component remains available.
## Language overview
The [CEL language](https://github.com/google/cel-spec/blob/master/doc/langdef.md) has a straightforward syntax that is similar to the expressions in C, C++, Java, JavaScript and Go.
CEL was designed to be embedded into applications. Each CEL "program" is a single expression that evaluates to a single value. CEL expressions are typically short "one-liners" that inline well into the string fields of Kubernetes API resources.
Inputs to a CEL program are "variables". Each Kubernetes API field that contains CEL declares in the API documentation which variables are available to use for that field. For example, in the `x-kubernetes-validations[i].rules` field of CustomResourceDefinitions, the `self` and `oldSelf` variables are available and refer to the previous and current state of the custom resource data to be validated by the CEL expression. Other Kubernetes API fields may declare different variables. See the API documentation of the API fields to learn which variables are available for that field.
Example CEL expressions:
<table> <caption>Examples of CEL expressions and the purpose of each</caption> <thead> <tr> <th>Rule</th> <th>Purpose</th> </tr> </thead> <tbody> <tr> <td><tt>self.minReplicas <= self.replicas && self.replicas <= self.maxReplicas</tt></td> <td>Validate that the three fields defining replicas are ordered appropriately</td> </tr> <tr> <td><tt>'Available' in self.stateCounts</tt></td> <td>Validate that an entry with the 'Available' key exists in a map</td> </tr> <tr> <td><tt>(self.list1.size() == 0) != (self.list2.size() == 0)</tt></td> <td>Validate that one of two lists is non-empty, but not both</td> </tr> <tr> <td><tt>self.envars.filter(e, e.name = 'MY_ENV').all(e, e.value.matches('^[a-zA-Z]*$'))</tt></td> <td>Validate the 'value' field of a listMap entry where key field 'name' is 'MY_ENV'</td> </tr> <tr> <td><tt>has(self.expired) && self.created + self.ttl < self.expired</tt></td> <td>Validate that 'expired' date is after a 'create' date plus a 'ttl' duration</td> </tr> <tr> <td><tt>self.health.startsWith('ok')</tt></td> <td>Validate a 'health' string field has the prefix 'ok'</td> </tr> <tr> <td><tt>self.widgets.exists(w, w.key == 'x' && w.foo < 10)</tt></td> <td>Validate that the 'foo' property of a listMap item with a key 'x' is less than 10</td> </tr> <tr> <td><tt>type(self) == string ? self == '99%' : self == 42</tt></td> <td>Validate an int-or-string field for both the int and string cases</td> </tr> <tr> <td><tt>self.metadata.name == 'singleton'</tt></td> <td>Validate that an object's name matches a specific value (making it a singleton)</td> </tr> <tr> <td><tt>self.set1.all(e, !(e in self.set2))</tt></td> <td>Validate that two listSets are disjoint</td> </tr> <tr> <td><tt>self.names.size() == self.details.size() && self.names.all(n, n in self.details)</tt></td> <td>Validate the 'details' map is keyed by the items in the 'names' listSet</td> </tr> <tr> <td><tt>self.details.all(key, key.matches('^[a-zA-Z]*$'))</tt></td> <td>Validate the keys of the 'details' map</td> </tr> <tr> <td><tt>self.details.all(key, self.details[key].matches('^[a-zA-Z]*$'))</tt></td> <td>Validate the values of the 'details' map</td> </tr> </tbody> </table>
## CEL options, language features, and libraries
CEL is configured with the following options, libraries and language features, introduced at the specified Kubernetes versions:
<table> <the …(trimmed)