From 392917891282e800ebf841796997820162bc1642 Mon Sep 17 00:00:00 2001 From: Seppe Volkaerts Date: Wed, 13 Jul 2022 00:01:20 +0200 Subject: [PATCH] Introduce import-values strategy + revert default strategy for backwards compat Signed-off-by: Seppe Volkaerts --- pkg/chartutil/dependencies.go | 71 ++++++++++++------- pkg/chartutil/dependencies_test.go | 13 ++-- .../subpop/charts/subchart1/Chart.yaml | 4 +- .../subchart1/charts/subchartA/values.yaml | 2 + .../subpop/charts/subchart1/values.yaml | 3 + pkg/chartutil/testdata/subpop/values.yaml | 1 - .../umbrella/Chart.yaml | 3 + .../charts/app1/charts/library/values.yaml | 2 +- .../umbrella/charts/app1/values.yaml | 2 +- .../umbrella/charts/app2/Chart.yaml | 3 +- .../charts/app2/charts/library/values.yaml | 2 +- .../umbrella/charts/app2/values.yaml | 2 +- .../umbrella/charts/app3/Chart.yaml | 11 +++ .../charts/app3/charts/library/Chart.yaml | 5 ++ .../charts/library/templates/service.yaml | 9 +++ .../charts/app3/charts/library/values.yaml | 5 ++ .../charts/app3/templates/service.yaml | 1 + .../umbrella/charts/app3/values.yaml | 3 + .../umbrella/values.yaml | 9 ++- 19 files changed, 112 insertions(+), 39 deletions(-) create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/Chart.yaml create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/Chart.yaml create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/templates/service.yaml create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/values.yaml create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/templates/service.yaml create mode 100644 pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/values.yaml diff --git a/pkg/chartutil/dependencies.go b/pkg/chartutil/dependencies.go index e01b95bf7..706a5b419 100644 --- a/pkg/chartutil/dependencies.go +++ b/pkg/chartutil/dependencies.go @@ -226,49 +226,72 @@ func processImportValues(c *chart.Chart) error { if err != nil { return err } - b := make(map[string]interface{}) + c.Values = copyMap(cvals) + overrides := make(map[string]interface{}) // import values from each dependency if specified in import-values for _, r := range c.Metadata.Dependencies { var outiv []interface{} for _, riv := range r.ImportValues { + var strategy string + var values map[string]interface{} + var child string + parent := "." switch iv := riv.(type) { case map[string]interface{}: - child := iv["child"].(string) - parent := iv["parent"].(string) - - outiv = append(outiv, map[string]string{ - "child": child, - "parent": parent, - }) - - // get child table - vv, err := cvals.Table(r.Name + "." + child) - if err != nil { - log.Printf("Warning: ImportValues missing table from chart %s: %v", r.Name, err) - continue + var strategyOk bool + strategy, strategyOk = iv["strategy"].(string) + if !strategyOk { + strategy = "ifNotPresent" + } + if key, ok := iv["key"].(string); ok { + child = "exports." + key + vm, err := cvals.Table(r.Name + "." + child) + if err != nil { + log.Printf("Warning: ImportValues missing table: %v", err) + continue + } + values = vm.AsMap() + } else { + child = iv["child"].(string) + parent = iv["parent"].(string) + vv, err := cvals.Table(r.Name + "." + child) + if err != nil { + log.Printf("Warning: ImportValues missing table from chart %s: %v", r.Name, err) + continue + } + values = pathToMap(parent, vv.AsMap()) } - // create value map from child to be merged into parent - b = CoalesceTables(cvals, pathToMap(parent, vv.AsMap())) case string: + // backwards compat to use the override strategy when using a string + strategy = "override" child := "exports." + iv - outiv = append(outiv, map[string]string{ - "child": child, - "parent": ".", - }) vm, err := cvals.Table(r.Name + "." + child) if err != nil { log.Printf("Warning: ImportValues missing table: %v", err) continue } - b = CoalesceTables(b, vm.AsMap()) + values = vm.AsMap() } + // merge the values from the child into the parent values according to the import strategy + if strategy == "override" { + overrides = CoalesceTables(overrides, values) + } else if strategy == "ifNotPresent" { + c.Values = CoalesceTables(c.Values, values) + } else { + log.Printf("Warning: ImportValues with an invalid import strategy %v", strategy) + continue + } + outiv = append(outiv, map[string]string{ + "child": child, + "parent": parent, + "strategy": strategy, + }) } // set our formatted import values r.ImportValues = outiv } - - // set the new values - c.Values = CoalesceTables(cvals, b) + // merge the overrides into the parent values + c.Values = CoalesceTables(overrides, c.Values) return nil } diff --git a/pkg/chartutil/dependencies_test.go b/pkg/chartutil/dependencies_test.go index 7f5e74956..18c0a3f38 100644 --- a/pkg/chartutil/dependencies_test.go +++ b/pkg/chartutil/dependencies_test.go @@ -206,6 +206,8 @@ func TestProcessDependencyImportValues(t *testing.T) { e["overridden-chartA-B.SCBextra1"] = "13" e["overridden-chartA-B.SC1extra6"] = "77" + e["subchart1.force-overridden-chartA.SCAFbool"] = "false" + // `exports` style e["SCBexported1B"] = "1965" e["SC1extra7"] = "true" @@ -225,15 +227,15 @@ func TestProcessDependencyImportValues(t *testing.T) { switch pv := pv.(type) { case float64: if s := strconv.FormatFloat(pv, 'f', -1, 64); s != vv { - t.Errorf("failed to match imported float value %v with expected %v", s, vv) + t.Errorf("%v: failed to match imported float value %v with expected %v", kk, s, vv) } case bool: if b := strconv.FormatBool(pv); b != vv { - t.Errorf("failed to match imported bool value %v with expected %v", b, vv) + t.Errorf("%v: failed to match imported bool value %v with expected %v", kk, b, vv) } default: if pv != vv { - t.Errorf("failed to match imported string value %q with expected %q", pv, vv) + t.Errorf("%v: failed to match imported string value %q with expected %q", kk, pv, vv) } } } @@ -244,8 +246,9 @@ func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) { e := make(map[string]string) - e["app1.service.port"] = "3456" - e["app2.service.port"] = "8080" + e["app1.service.port"] = "1010" // app1 is the chart with the default import override behavior + e["app2.service.port"] = "2222" // app2 is the chart with the ifNotPresent import behavior + e["app3.service.port"] = "1234" // app3 is the chart with the default import override behavior, but the port is overridden in the umbrella chart if err := processDependencyImportValues(c); err != nil { t.Fatalf("processing import values dependencies %v", err) diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/Chart.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/Chart.yaml index 9d8c03ee1..e57abbe67 100644 --- a/pkg/chartutil/testdata/subpop/charts/subchart1/Chart.yaml +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/Chart.yaml @@ -17,7 +17,9 @@ dependencies: parent: overridden-chartA - child: SCAdata parent: imported-chartA-B - + - child: SCAdata-forced + parent: force-overridden-chartA + strategy: override - name: subchartb repository: http://localhost:10191 version: 0.1.0 diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/charts/subchartA/values.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/charts/subchartA/values.yaml index f0381ae6a..6c2b6061f 100644 --- a/pkg/chartutil/testdata/subpop/charts/subchart1/charts/subchartA/values.yaml +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/charts/subchartA/values.yaml @@ -14,4 +14,6 @@ SCAdata: SCAstring: "jabba" SCAnested1: SCAnested2: true +SCAdata-forced: + SCAFbool: false diff --git a/pkg/chartutil/testdata/subpop/charts/subchart1/values.yaml b/pkg/chartutil/testdata/subpop/charts/subchart1/values.yaml index a974e316a..543c4b2a5 100644 --- a/pkg/chartutil/testdata/subpop/charts/subchart1/values.yaml +++ b/pkg/chartutil/testdata/subpop/charts/subchart1/values.yaml @@ -26,6 +26,9 @@ overridden-chartA: SCAstring: "jabbathehut" SC1extra3: true +force-overridden-chartA: + SCAFbool: true # Will be overridden by the import + imported-chartA-B: SC1extra5: "tiller" diff --git a/pkg/chartutil/testdata/subpop/values.yaml b/pkg/chartutil/testdata/subpop/values.yaml index d611d6a89..aaaadae18 100644 --- a/pkg/chartutil/testdata/subpop/values.yaml +++ b/pkg/chartutil/testdata/subpop/values.yaml @@ -10,7 +10,6 @@ overridden-chart1: SC1string: "pollywog" SPextra2: 42 - imported-chartA: SPextra3: 1.337 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml index 7552e07cd..ff7c37562 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml @@ -11,3 +11,6 @@ dependencies: - name: app2 version: 0.1.0 condition: app2.enabled +- name: app3 + version: 0.1.0 + condition: app3.enabled diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml index 0c08b6cd2..3a315bed6 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml @@ -2,4 +2,4 @@ exports: defaults: service: type: ClusterIP - port: 9090 + port: 1010 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/values.yaml index 3728aa930..1c27e3a3e 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/values.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/values.yaml @@ -1,3 +1,3 @@ service: type: ClusterIP - port: 1234 + port: 1111 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/Chart.yaml index fea2768c7..38048042c 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/Chart.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/Chart.yaml @@ -8,4 +8,5 @@ dependencies: - name: library version: 0.1.0 import-values: - - defaults + - key: defaults + strategy: ifNotPresent diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml index 0c08b6cd2..f9494c203 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml @@ -2,4 +2,4 @@ exports: defaults: service: type: ClusterIP - port: 9090 + port: 2020 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/values.yaml index 98bd6d24b..0d380f03c 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/values.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/values.yaml @@ -1,3 +1,3 @@ service: type: ClusterIP - port: 8080 + port: 2222 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/Chart.yaml new file mode 100644 index 000000000..a42f58773 --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: app3 +description: A Helm chart for Kubernetes +type: application +version: 0.1.0 + +dependencies: +- name: library + version: 0.1.0 + import-values: + - defaults diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/Chart.yaml new file mode 100644 index 000000000..f2f8a90d9 --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: library +description: A Helm chart for Kubernetes +type: library +version: 0.1.0 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/templates/service.yaml new file mode 100644 index 000000000..3fd398b53 --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/templates/service.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/values.yaml new file mode 100644 index 000000000..9bd8427ee --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/charts/library/values.yaml @@ -0,0 +1,5 @@ +exports: + defaults: + service: + type: ClusterIP + port: 3030 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/templates/service.yaml new file mode 100644 index 000000000..8ed8ddf1f --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/templates/service.yaml @@ -0,0 +1 @@ +{{- include "library.service" . }} diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/values.yaml new file mode 100644 index 000000000..274cdbfeb --- /dev/null +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app3/values.yaml @@ -0,0 +1,3 @@ +service: + type: ClusterIP + port: 3333 diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml index 94ee31855..a8f004d7e 100644 --- a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml +++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml @@ -1,8 +1,11 @@ app1: enabled: true - service: - type: ClusterIP - port: 3456 app2: enabled: true + +app3: + enabled: true + service: + type: ClusterIP + port: 1234