mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-05 07:26:55 +00:00
feat: support arrays in jp items() function (#6180)
This commit is contained in:
parent
04e73e0e2f
commit
7540daa906
2 changed files with 35 additions and 26 deletions
|
@ -450,14 +450,14 @@ func GetFunctions() []*FunctionEntry {
|
|||
Entry: &gojmespath.FunctionEntry{
|
||||
Name: items,
|
||||
Arguments: []ArgSpec{
|
||||
{Types: []JpType{JpObject}},
|
||||
{Types: []JpType{JpObject, JpArray}},
|
||||
{Types: []JpType{JpString}},
|
||||
{Types: []JpType{JpString}},
|
||||
},
|
||||
Handler: jpItems,
|
||||
},
|
||||
ReturnType: []JpType{JpArray},
|
||||
Note: "converts a map to an array of objects where each key:value is an item in the array",
|
||||
Note: "converts a map or array to an array of objects where each key:value is an item in the array",
|
||||
},
|
||||
{
|
||||
Entry: &gojmespath.FunctionEntry{
|
||||
|
@ -984,10 +984,6 @@ func jpParseYAML(arguments []interface{}) (interface{}, error) {
|
|||
}
|
||||
|
||||
func jpItems(arguments []interface{}) (interface{}, error) {
|
||||
input, ok := arguments[0].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(invalidArgumentTypeError, arguments, 0, "Object")
|
||||
}
|
||||
keyName, ok := arguments[1].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(invalidArgumentTypeError, arguments, 1, "String")
|
||||
|
@ -996,26 +992,34 @@ func jpItems(arguments []interface{}) (interface{}, error) {
|
|||
if !ok {
|
||||
return nil, fmt.Errorf(invalidArgumentTypeError, arguments, 2, "String")
|
||||
}
|
||||
|
||||
arrayOfObj := make([]map[string]interface{}, 0)
|
||||
|
||||
keys := []string{}
|
||||
|
||||
// Sort the keys so that the output is deterministic
|
||||
for key := range input {
|
||||
keys = append(keys, key)
|
||||
switch input := arguments[0].(type) {
|
||||
case map[string]interface{}:
|
||||
var keys []string
|
||||
// Sort the keys so that the output is deterministic
|
||||
for key := range input {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
var arrayOfObj []map[string]interface{}
|
||||
for _, key := range keys {
|
||||
arrayOfObj = append(arrayOfObj, map[string]interface{}{
|
||||
keyName: key,
|
||||
valName: input[key],
|
||||
})
|
||||
}
|
||||
return arrayOfObj, nil
|
||||
case []interface{}:
|
||||
var arrayOfObj []map[string]interface{}
|
||||
for index, value := range input {
|
||||
arrayOfObj = append(arrayOfObj, map[string]interface{}{
|
||||
keyName: float64(index),
|
||||
valName: value,
|
||||
})
|
||||
}
|
||||
return arrayOfObj, nil
|
||||
default:
|
||||
return nil, fmt.Errorf(invalidArgumentTypeError, arguments, 0, "Object")
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, key := range keys {
|
||||
m := make(map[string]interface{})
|
||||
m[keyName] = key
|
||||
m[valName] = input[key]
|
||||
arrayOfObj = append(arrayOfObj, m)
|
||||
}
|
||||
|
||||
return arrayOfObj, nil
|
||||
}
|
||||
|
||||
func jpObjectFromLists(arguments []interface{}) (interface{}, error) {
|
||||
|
@ -1068,7 +1072,6 @@ func validateArg(f string, arguments []interface{}, index int, expectedType refl
|
|||
if arg.Type().Kind() != expectedType {
|
||||
return reflect.Value{}, fmt.Errorf(invalidArgumentTypeError, f, index+1, expectedType.String())
|
||||
}
|
||||
|
||||
return arg, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1349,6 +1349,12 @@ func Test_Items(t *testing.T) {
|
|||
valName: `"myValue"`,
|
||||
expectedResult: `[{ "myKey": "key1", "myValue": "value1" }, { "myKey": "key2", "myValue": "value2" }]`,
|
||||
},
|
||||
{
|
||||
object: `["A", "B", "C"]`,
|
||||
keyName: `"myKey"`,
|
||||
valName: `"myValue"`,
|
||||
expectedResult: `[{ "myKey": 0, "myValue": "A" }, { "myKey": 1, "myValue": "B" }, { "myKey": 2, "myValue": "C" }]`,
|
||||
},
|
||||
}
|
||||
for i, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
|
|
Loading…
Add table
Reference in a new issue