You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- CEL standard functions, defined in the[list of standard definitions](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#list-of-standard-definitions)
1002
+
- CEL standard functions, defined in the[list of standard definitions](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#list-of-standard-definitions)
1003
1003
- CEL standard [macros](https://github.com/google/cel-spec/blob/v0.7.0/doc/langdef.md#macros)
1004
1004
- CEL [extended string function library](https://pkg.go.dev/github.com/google/[email protected]/ext#Strings)
A rule that contains an expression referencing the identifier `oldSelf` is implicitly considered a
1010
-
"transition rule". Transition rules allow schema authors to prevent certain transitions between two
1010
+
_transition rule_. Transition rules allow schema authors to prevent certain transitions between two
1011
1011
otherwise valid states. For example:
1012
1012
1013
1013
```yaml
@@ -1036,33 +1036,40 @@ Errors will be generated on CRD writes if a schema node contains a transition ru
1036
1036
applied, e.g. "*path*: update rule *rule* cannot be set on schema because the schema or its parent
1037
1037
schema is not mergeable".
1038
1038
1039
-
Transition rules are only allowed on "correlatable" portions of a schema.
1039
+
Transition rules are only allowed on _correlatable portions_ of a schema.
1040
1040
A portion of the schema is correlatable if all `array` parent schemas are of type `x-kubernetes-list-type=map`; any `set`or `atomic`array parent schemas make it impossible to unambiguously correlate a `self` with `oldSelf`.
1041
1041
1042
-
##### Use Cases
1042
+
Here are some examples for transition rules:
1043
1043
1044
+
{{< table caption="Transition rules examples" >}}
1044
1045
| Use Case | Rule
1045
1046
| -------- | --------
1046
1047
| Immutability | `self.foo == oldSelf.foo`
1047
1048
| Prevent modification/removal once assigned | `oldSelf != 'bar' \|\| self == 'bar'` or `!has(oldSelf.field) \|\| has(self.field)`
1048
1049
| Append-only set | `self.all(element, element in oldSelf)`
1049
1050
| If previous value was X, new value can only be A or B, not Y or Z | `oldSelf != 'X' \|\| self in ['A', 'B']`
Resource consumption of validation rules is checked at CustomResourceDefinition creation and update time. If a rule is estimated to be prohibitively expensive to execute, it will result in a validation error. A similar
1055
-
system is used at runtime that observes the actions the interpreter takes. If the interpreter executes
1056
+
When you create or update a CustomResourceDefinition that uses validation rules,
1057
+
the API server checks the likely impact of running those validation rules. If a rule is
1058
+
estimated to be prohibitively expensive to execute, the API server rejects the create
1059
+
or update operation, and returns an error message.
1060
+
A similar system is used at runtime that observes the actions the interpreter takes. If the interpreter executes
1056
1061
too many instructions, execution of the rule will be halted, and an error will result.
1057
1062
Each CustomResourceDefinition is also allowed a certain amount of resources to finish executing all of
1058
1063
its validation rules. If the sum total of its rules are estimated at creation time to go over that limit,
1059
1064
then a validation error will also occur.
1060
1065
1061
-
In general, both systems will allow rules that do not need to iterate; these rules will
1062
-
always take the same amount of time regardless of how large their input is. `self.foo == 1` will be allowed.
1063
-
But if `foo` is a string and we instead have `self.foo.contains("someString")`, our rule will take
1064
-
longer to execute depending on how long `foo` is. Another example would be if `foo` was an array, and we
1065
-
had a rule `self.foo.all(x, x > 5)`. The cost system will always assume the worst-case scenario if
1066
+
You are unlikely to encounter issues with the resource budget for validation if you only
1067
+
specify rules that always take the same amount of time regardless of how large their input is.
1068
+
For example, a rule that asserts that `self.foo == 1` does not by itself have any
1069
+
risk of rejection on validation resource budget groups.
1070
+
But if `foo` is a string and you define a validation rule `self.foo.contains("someString")`, that rule takes
1071
+
longer to execute depending on how long `foo` is.
1072
+
Another example would be if `foo` were an array, and you specified a validation rule `self.foo.all(x, x > 5)`. The cost system always assumes the worst-case scenario if
1066
1073
a limit on the length of `foo` is not given, and this will happen for anything that can be iterated
1067
1074
over (lists, maps, etc.).
1068
1075
@@ -1081,17 +1088,18 @@ openAPIV3Schema:
1081
1088
- rule: "self.all(x, x.contains('a string'))"
1082
1089
```
1083
1090
1084
-
The cost system will not allow this rule. Using `self.all` means calling `contains` on every string in `foo`,
1085
-
which in turn will check the given string to see if it contains `'a string'`. Without limits, this is a very
1086
-
expensive rule:
1087
-
1091
+
then the API server rejects this rule on validation budget grounds with error:
0 commit comments