From bb6cbadb2fa06a402d4228bb1438408ae77132aa Mon Sep 17 00:00:00 2001 From: Kermit Alexander Date: Wed, 27 Jul 2022 04:47:44 +0000 Subject: [PATCH] Add examples of matchExpressions validations. --- .../apiserver/schema/cel/validation_test.go | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation_test.go b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation_test.go index 7086e71fd58..09810a947de 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation_test.go +++ b/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/cel/validation_test.go @@ -1948,6 +1948,58 @@ func TestValidationExpressionsAtSchemaLevels(t *testing.T) { }), errors: []string{"Invalid value: \"object\": failed rule: self.m == 2"}, }, + {name: "matchExpressions - 'values' must be specified when 'operator' is 'In' or 'NotIn'", + obj: map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "tier", + "operator": "In", + "values": []interface{}{}, + }, + }, + }, + schema: genMatchSelectorSchema(`self.matchExpressions.all(rule, (rule.operator != "In" && rule.operator != "NotIn") || ((has(rule.values) && size(rule.values) > 0)))`), + errors: []string{"failed rule"}, + }, + {name: "matchExpressions - 'values' may not be specified when 'operator' is 'Exists' or 'DoesNotExist'", + obj: map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "tier", + "operator": "Exists", + "values": []interface{}{"somevalue"}, + }, + }, + }, + schema: genMatchSelectorSchema(`self.matchExpressions.all(rule, (rule.operator != "Exists" && rule.operator != "DoesNotExist") || ((!has(rule.values) || size(rule.values) == 0)))`), + errors: []string{"failed rule"}, + }, + {name: "matchExpressions - invalid selector operator", + obj: map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "tier", + "operator": "badop", + "values": []interface{}{}, + }, + }, + }, + schema: genMatchSelectorSchema(`self.matchExpressions.all(rule, rule.operator == "In" || rule.operator == "NotIn" || rule.operator == "DoesNotExist")`), + errors: []string{"failed rule"}, + }, + {name: "matchExpressions - invalid label value", + obj: map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "badkey!", + "operator": "Exists", + "values": []interface{}{}, + }, + }, + }, + schema: genMatchSelectorSchema(`self.matchExpressions.all(rule, size(rule.key) <= 63 && rule.key.matches("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$"))`), + errors: []string{"failed rule"}, + }, } for _, tt := range tests { @@ -1987,6 +2039,17 @@ func TestValidationExpressionsAtSchemaLevels(t *testing.T) { } } +func genMatchSelectorSchema(rule string) *schema.Structural { + s := withRule(objectType(map[string]schema.Structural{ + "matchExpressions": listType(objectTypePtr(map[string]schema.Structural{ + "key": stringType, + "operator": stringType, + "values": listType(&stringType), + })), + }), rule) + return &s +} + func TestCELValidationLimit(t *testing.T) { tests := []struct { name string