diff --git a/util/pkg/reflectutils/access.go b/util/pkg/reflectutils/access.go index 67600da9c2453..6c741128e07f6 100644 --- a/util/pkg/reflectutils/access.go +++ b/util/pkg/reflectutils/access.go @@ -134,6 +134,23 @@ func setType(v reflect.Value, newValue string) error { t := v.Type().String() + if v.Type().Kind() == reflect.Map { + if v.IsNil() { + v.Set(reflect.MakeMap(v.Type())) + } + + switch t { + case "map[string]string": + name, value, _ := strings.Cut(newValue, "=") + v.SetMapIndex(reflect.ValueOf(name), reflect.ValueOf(value)) + + default: + return fmt.Errorf("unhandled type %q", t) + } + + return nil + } + var newV reflect.Value switch t { @@ -168,6 +185,7 @@ func setType(v reflect.Value, newValue string) error { default: panic("missing case in int switch") } + case "uint64", "uint32", "uint16", "uint": v, err := strconv.Atoi(newValue) if err != nil { @@ -189,6 +207,7 @@ func setType(v reflect.Value, newValue string) error { default: panic("missing case in uint switch") } + case "intstr.IntOrString": newV = reflect.ValueOf(intstr.Parse(newValue)) diff --git a/util/pkg/reflectutils/access_test.go b/util/pkg/reflectutils/access_test.go index 880dff5400219..a31ce0f04f44e 100644 --- a/util/pkg/reflectutils/access_test.go +++ b/util/pkg/reflectutils/access_test.go @@ -65,6 +65,8 @@ type fakeObjectContainers struct { Enum fakeEnum `json:"enum"` EnumSlice []fakeEnum `json:"enumSlice"` + + StringMap map[string]string `json:"stringMap"` } type fakeObjectPolicy struct { @@ -197,6 +199,27 @@ func TestSet(t *testing.T) { Path: "spec.containers[0].duration", Value: "500ms", }, + { + Name: "set new map key", + Input: "{ 'spec': { 'containers': [ {} ] } }", + Expected: "{ 'spec': { 'containers': [ { 'stringMap': { 'ABC': '' } } ] } }", + Path: "spec.containers[0].stringMap", + Value: "ABC", + }, + { + Name: "set new map key with val", + Input: "{ 'spec': { 'containers': [ {} ] } }", + Expected: "{ 'spec': { 'containers': [ { 'stringMap': { 'ABC': 'DEF' } } ] } }", + Path: "spec.containers[0].stringMap", + Value: "ABC=DEF", + }, + { + Name: "set existing map key with val", + Input: "{ 'spec': { 'containers': [ { 'stringMap': { 'ABC': 'DEF' } } ] } }", + Expected: "{ 'spec': { 'containers': [ { 'stringMap': { 'ABC': 'DEF', 'GHI': 'JKL' } } ] } }", + Path: "spec.containers[0].stringMap", + Value: "GHI=JKL", + }, // Not sure if we should do this... // { // Name: "creating missing array elements", diff --git a/util/pkg/reflectutils/field_path.go b/util/pkg/reflectutils/field_path.go index 3fe1fb34dd853..825e08421165a 100644 --- a/util/pkg/reflectutils/field_path.go +++ b/util/pkg/reflectutils/field_path.go @@ -95,8 +95,7 @@ func ParseFieldPath(s string) (*FieldPath, error) { token: field, }) - case '.': - // TODO: Validate that we don't have two dots? + case '.', '/': // Skip case '[':