google / cel-spec

Common Expression Language -- specification and binary representation
https://cel.dev
Apache License 2.0
2.59k stars 216 forks source link

[question] Duplicate/unique check expression #344

Closed AlexanderYastrebov closed 3 months ago

AlexanderYastrebov commented 3 months ago

Hello.

We would like to prohibit duplicate values in a string array in our Custom Resources Definition (CRD). CRD schema supports uniqueItems: true validation but it turns our that Kubernetes deliberately does not support it:

The CustomResourceDefinition "routegroups.zalando.org" is invalid: spec.validation.openAPIV3Schema.properties[spec].properties[hosts].uniqueItems: Forbidden: uniqueItems cannot be set to true since the runtime complexity becomes quadratic

There is a feature https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules that allows CEL validation expressions in CRD.

Here is the CEL expression I came up with to check for duplicate values:

foo:
 - bar
 - baz
 - qux
 - bar
// check duplicates
foo.exists(v, size(foo.filter(w, w==v)) > 1)

See in CEL playground.

It does look a bit complicated for such a simple task. What would be the canonical way in CEL to detect duplicate values in array?

AlexanderYastrebov commented 3 months ago

It does look a bit complicated for such a simple task.

Its cost also exceeds budget by factor of more than 100x, see https://github.com/szuecs/routegroup-client/pull/37

Update: the rule works with both maxItems: 255 for the array and maxLength: 255 for the array item. Nevertheless cost problem exists - CRD runs out of cost budged again if the same rule is added to another field.

AlexanderYastrebov commented 3 months ago

Turns out there is a standard way to mark list as a set via:

// +listType=set

see https://github.com/szuecs/routegroup-client/pull/41