mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 05:27:21 +00:00
Merge pull request #123538 from jiahuif-forks/fix/cel/mutation-library-map-support
CEL mutation library: add support for map
This commit is contained in:
commit
286cdad32d
@ -55,7 +55,11 @@ func (v *ObjectVal) ConvertToNative(typeDesc reflect.Type) (any, error) {
|
|||||||
}
|
}
|
||||||
result = make(map[string]any, len(v.fields))
|
result = make(map[string]any, len(v.fields))
|
||||||
for k, v := range v.fields {
|
for k, v := range v.fields {
|
||||||
result[k] = convertField(v)
|
converted, err := convertField(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("fail to convert field %q: %w", k, err)
|
||||||
|
}
|
||||||
|
result[k] = converted
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@ -104,8 +108,12 @@ func (v *ObjectVal) IsZeroValue() bool {
|
|||||||
// convertField converts a referred ref.Val to its expected type.
|
// convertField converts a referred ref.Val to its expected type.
|
||||||
// For objects, the expected type is map[string]any
|
// For objects, the expected type is map[string]any
|
||||||
// For lists, the expected type is []any
|
// For lists, the expected type is []any
|
||||||
|
// For maps, the expected type is map[string]any
|
||||||
// For anything else, it is converted via value.Value()
|
// For anything else, it is converted via value.Value()
|
||||||
func convertField(value ref.Val) any {
|
//
|
||||||
|
// It will return an error if the request type is a map but the key
|
||||||
|
// is not a string.
|
||||||
|
func convertField(value ref.Val) (any, error) {
|
||||||
// special handling for lists, where the elements are converted with Value() instead of ConvertToNative
|
// special handling for lists, where the elements are converted with Value() instead of ConvertToNative
|
||||||
// to allow them to become native value of any type.
|
// to allow them to become native value of any type.
|
||||||
if listOfVal, ok := value.Value().([]ref.Val); ok {
|
if listOfVal, ok := value.Value().([]ref.Val); ok {
|
||||||
@ -113,7 +121,20 @@ func convertField(value ref.Val) any {
|
|||||||
for _, v := range listOfVal {
|
for _, v := range listOfVal {
|
||||||
result = append(result, v.Value())
|
result = append(result, v.Value())
|
||||||
}
|
}
|
||||||
return result
|
return result, nil
|
||||||
}
|
}
|
||||||
return value.Value()
|
// unstructured maps, as seen in annotations
|
||||||
|
// map keys must be strings
|
||||||
|
if mapOfVal, ok := value.Value().(map[ref.Val]ref.Val); ok {
|
||||||
|
result := make(map[string]any)
|
||||||
|
for k, v := range mapOfVal {
|
||||||
|
stringKey, ok := k.Value().(string)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("map key %q is of type %t, not string", k, k)
|
||||||
|
}
|
||||||
|
result[stringKey] = v.Value()
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
return value.Value(), nil
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,17 @@ func TestTypeProvider(t *testing.T) {
|
|||||||
"intList": []any{int64(1), int64(2), int64(3)},
|
"intList": []any{int64(1), int64(2), int64(3)},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "map string-to-string",
|
||||||
|
expression: `Object{
|
||||||
|
annotations: {"foo": "bar"}
|
||||||
|
}`,
|
||||||
|
expectedValue: map[string]any{
|
||||||
|
"annotations": map[string]any{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "field access",
|
name: "field access",
|
||||||
expression: `Object{
|
expression: `Object{
|
||||||
|
Loading…
Reference in New Issue
Block a user