From c0f72e1fc6c391f9e9fe083daad77e17924df173 Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Sat, 17 Jul 2021 14:09:49 +0800 Subject: [PATCH 1/2] Treat quoted values as string when targetPath is set Signed-off-by: Zhongcheng Lao --- controllers/helmrelease_controller.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/controllers/helmrelease_controller.go b/controllers/helmrelease_controller.go index 6d0e5f419..55a146bba 100644 --- a/controllers/helmrelease_controller.go +++ b/controllers/helmrelease_controller.go @@ -611,8 +611,19 @@ func (r *HelmReleaseReconciler) composeValues(ctx context.Context, hr v2.HelmRel // TODO(hidde): this is a bit of hack, as it mimics the way the option string is passed // to Helm from a CLI perspective. Given the parser is however not publicly accessible // while it contains all logic around parsing the target path, it is a fair trade-off. - singleValue := v.TargetPath + "=" + string(valuesData) - if err := strvals.ParseInto(singleValue, result); err != nil { + stringValuesData := string(valuesData) + const singleQuote = "'" + const doubleQuote = "\"" + var err error + if (strings.HasPrefix(stringValuesData, singleQuote) && strings.HasSuffix(stringValuesData, singleQuote)) || (strings.HasPrefix(stringValuesData, doubleQuote) && strings.HasSuffix(stringValuesData, doubleQuote)) { + stringValuesData = strings.Trim(stringValuesData, singleQuote+doubleQuote) + singleValue := v.TargetPath + "=" + stringValuesData + err = strvals.ParseIntoString(singleValue, result) + } else { + singleValue := v.TargetPath + "=" + stringValuesData + err = strvals.ParseInto(singleValue, result) + } + if err != nil { return nil, fmt.Errorf("unable to merge value from key '%s' in %s '%s' into target path '%s': %w", v.GetValuesKey(), v.Kind, namespacedName, v.TargetPath, err) } } From 0ceec2d3fc40b6e41e6800a12223a0d07d065ce7 Mon Sep 17 00:00:00 2001 From: Zhongcheng Lao Date: Fri, 23 Jul 2021 08:29:07 +0800 Subject: [PATCH 2/2] Add test case for set with boolean value and set-string behavior Signed-off-by: Zhongcheng Lao --- controllers/helmrelease_controller_test.go | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/controllers/helmrelease_controller_test.go b/controllers/helmrelease_controller_test.go index c1b762460..d18763086 100644 --- a/controllers/helmrelease_controller_test.go +++ b/controllers/helmrelease_controller_test.go @@ -107,6 +107,52 @@ other: values }, }, }, + { + name: "target path with boolean value", + resources: []runtime.Object{ + valuesSecret("values", map[string][]byte{"single": []byte("true")}), + }, + references: []v2.ValuesReference{ + { + Kind: "Secret", + Name: "values", + ValuesKey: "single", + TargetPath: "merge.at.specific.path", + }, + }, + want: chartutil.Values{ + "merge": map[string]interface{}{ + "at": map[string]interface{}{ + "specific": map[string]interface{}{ + "path": true, + }, + }, + }, + }, + }, + { + name: "target path with set-string behavior", + resources: []runtime.Object{ + valuesSecret("values", map[string][]byte{"single": []byte("\"true\"")}), + }, + references: []v2.ValuesReference{ + { + Kind: "Secret", + Name: "values", + ValuesKey: "single", + TargetPath: "merge.at.specific.path", + }, + }, + want: chartutil.Values{ + "merge": map[string]interface{}{ + "at": map[string]interface{}{ + "specific": map[string]interface{}{ + "path": "true", + }, + }, + }, + }, + }, { name: "values reference to non existing secret", references: []v2.ValuesReference{