Fix bug where CEL listOfString.join() results in unexpected error

This commit is contained in:
Joe Betz 2023-04-25 10:21:41 -04:00
parent 3125009dd1
commit e115d5234c
2 changed files with 43 additions and 2 deletions

View File

@ -338,6 +338,21 @@ func TestValidationExpressions(t *testing.T) {
"self.val1 + self.val2 == [1, 2, 3, 1, 2, 3]",
"self.val1 + [4, 5] == [1, 2, 3, 4, 5]",
},
errors: map[string]string{
// Mixed type lists are not allowed since we have HomogeneousAggregateLiterals enabled
"[1, 'a', false].filter(x, string(x) == 'a')": "expected type 'int' but found 'string'",
},
},
{name: "string lists",
obj: objs([]interface{}{"a", "b", "c"}),
schema: schemas(listType(&stringType)),
valid: []string{
// Join function
"self.val1.join('-') == 'a-b-c'",
"['a', 'b', 'c'].join('-') == 'a-b-c'",
"self.val1.join() == 'abc'",
"['a', 'b', 'c'].join() == 'abc'",
},
},
{name: "listSets",
obj: objs([]interface{}{"a", "b", "c"}, []interface{}{"a", "c", "b"}),
@ -351,6 +366,12 @@ func TestValidationExpressions(t *testing.T) {
"!('x' in self.val1)",
"self.val1 + self.val2 == ['a', 'b', 'c']",
"self.val1 + ['c', 'd'] == ['a', 'b', 'c', 'd']",
// Join function
"self.val1.join('-') == 'a-b-c'",
"['a', 'b', 'c'].join('-') == 'a-b-c'",
"self.val1.join() == 'abc'",
"['a', 'b', 'c'].join() == 'abc'",
},
},
{name: "listMaps",
@ -403,6 +424,10 @@ func TestValidationExpressions(t *testing.T) {
"!('k3' in self.val1)",
"self.val1 == {'k1': 'a', 'k2': 'b'}",
},
errors: map[string]string{
// Mixed type maps are not allowed since we have HomogeneousAggregateLiterals enabled
"{'k1': 'a', 'k2': 1, 'k2': false}": "expected type 'string' but found 'int'",
},
},
{name: "objects",
obj: map[string]interface{}{

View File

@ -26,9 +26,10 @@ import (
"github.com/google/cel-go/common/types/ref"
"github.com/google/cel-go/common/types/traits"
"k8s.io/kube-openapi/pkg/validation/strfmt"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apiserver/pkg/cel"
"k8s.io/kube-openapi/pkg/validation/strfmt"
)
// UnstructuredToVal converts a Kubernetes unstructured data element to a CEL Val.
@ -425,7 +426,22 @@ var _ = traits.Lister(&unstructuredList{})
func (t *unstructuredList) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
switch typeDesc.Kind() {
case reflect.Slice:
return t.elements, nil
switch t.itemsSchema.Type() {
// Workaround for https://github.com/kubernetes/kubernetes/issues/117590 until we
// resolve the desired behavior in cel-go via https://github.com/google/cel-go/issues/688
case "string":
var result []string
for _, e := range t.elements {
s, ok := e.(string)
if !ok {
return nil, fmt.Errorf("unexpected all elements to be of type string, but got %T", e)
}
result = append(result, s)
}
return result, nil
default:
return t.elements, nil
}
}
return nil, fmt.Errorf("type conversion error from '%s' to '%s'", t.Type(), typeDesc)
}