From e23793120b8ce3deeeede070813cd74689ed729c Mon Sep 17 00:00:00 2001 From: Dan Winter Date: Mon, 19 Nov 2018 09:58:25 -0700 Subject: [PATCH] fix(helm): --set for out of order list values (#4682) When a user specifies value overrides for list values out of order, strvals.listItem panics. Change strvals.listItem to handle this case by re-initializing nil values to a new map. Closes #4503 Co-authored-by: Cameron Childress Co-authored-by: Kevin Collette Co-authored-by: Connor McKelvey Co-authored-by: Dan Winter Signed-off-by: Dan Winter Signed-off-by: Cameron Childress Signed-off-by: Kevin Collette Signed-off-by: Connor McKelvey --- cmd/helm/install_test.go | 8 +++++++- pkg/strvals/parser.go | 8 +++++++- pkg/strvals/parser_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go index 168c53fed..4a2055640 100644 --- a/cmd/helm/install_test.go +++ b/cmd/helm/install_test.go @@ -61,7 +61,13 @@ func TestInstall(t *testing.T) { resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), expected: "virgil", }, - // Install, values from yaml + { + name: "install with multiple unordered list values", + args: []string{"testdata/testcharts/alpine"}, + flags: strings.Split("--name virgil --set foo[1].bar=baz,foo[0].baz=bar", " "), + resp: helm.ReleaseMock(&helm.MockReleaseOptions{Name: "virgil"}), + expected: "virgil", + }, { name: "install with values", args: []string{"testdata/testcharts/alpine"}, diff --git a/pkg/strvals/parser.go b/pkg/strvals/parser.go index 532a8c4ac..9d52f34c0 100644 --- a/pkg/strvals/parser.go +++ b/pkg/strvals/parser.go @@ -288,7 +288,13 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) { // We have a nested object. Send to t.key inner := map[string]interface{}{} if len(list) > i { - inner = list[i].(map[string]interface{}) + var ok bool + inner, ok = list[i].(map[string]interface{}) + if !ok { + // We have indices out of order. Initialize empty value. + list[i] = map[string]interface{}{} + inner = list[i].(map[string]interface{}) + } } // Recurse diff --git a/pkg/strvals/parser_test.go b/pkg/strvals/parser_test.go index e5d878149..a096f16d2 100644 --- a/pkg/strvals/parser_test.go +++ b/pkg/strvals/parser_test.go @@ -294,6 +294,30 @@ func TestParseSet(t *testing.T) { str: "nested[1][1]=1", expect: map[string]interface{}{"nested": []interface{}{nil, []interface{}{nil, 1}}}, }, + { + str: "name1.name2[0].foo=bar,name1.name2[1].foo=bar", + expect: map[string]interface{}{ + "name1": map[string]interface{}{ + "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}}, + }, + }, + }, + { + str: "name1.name2[1].foo=bar,name1.name2[0].foo=bar", + expect: map[string]interface{}{ + "name1": map[string]interface{}{ + "name2": []map[string]interface{}{{"foo": "bar"}, {"foo": "bar"}}, + }, + }, + }, + { + str: "name1.name2[1].foo=bar", + expect: map[string]interface{}{ + "name1": map[string]interface{}{ + "name2": []map[string]interface{}{nil, {"foo": "bar"}}, + }, + }, + }, } for _, tt := range tests {