Repository: helm/helm
Pull request #10110 (2021-09-07 15:28:48)

Fix value precedence
Fix value precedence when importing values from child, as described in issue https://github.com/helm/helm/issues/9940

**What this PR does / why we need it**:

 Closes https://github.com/helm/helm/issues/9940

**If applicable**:
- [ ] this PR contains documentation
- [x] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility



Patch:
diff --git a/pkg/chartutil/dependencies.go b/pkg/chartutil/dependencies.go
index d2e7d6dc9..e01b95bf7 100644
--- a/pkg/chartutil/dependencies.go
+++ b/pkg/chartutil/dependencies.go
@@ -268,7 +268,7 @@ func processImportValues(c *chart.Chart) error {
 	}
 
 	// set the new values
-	c.Values = CoalesceTables(b, cvals)
+	c.Values = CoalesceTables(cvals, b)
 
 	return nil
 }


Test patch:
diff --git a/pkg/chartutil/dependencies_test.go b/pkg/chartutil/dependencies_test.go
index bcb1d40e5..7f5e74956 100644
--- a/pkg/chartutil/dependencies_test.go
+++ b/pkg/chartutil/dependencies_test.go
@@ -239,6 +239,37 @@ func TestProcessDependencyImportValues(t *testing.T) {
 	}
 }
 
+func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) {
+	c := loadChart(t, "testdata/three-level-dependent-chart/umbrella")
+
+	e := make(map[string]string)
+
+	e["app1.service.port"] = "3456"
+	e["app2.service.port"] = "8080"
+
+	if err := processDependencyImportValues(c); err != nil {
+		t.Fatalf("processing import values dependencies %v", err)
+	}
+	cc := Values(c.Values)
+	for kk, vv := range e {
+		pv, err := cc.PathValue(kk)
+		if err != nil {
+			t.Fatalf("retrieving import values table %v %v", kk, err)
+		}
+
+		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)
+			}
+		default:
+			if pv != vv {
+				t.Errorf("failed to match imported string value %q with expected %q", pv, vv)
+			}
+		}
+	}
+}
+
 func TestProcessDependencyImportValuesForEnabledCharts(t *testing.T) {
 	c := loadChart(t, "testdata/import-values-from-enabled-subchart/parent-chart")
 	nameOverride := "parent-chart-prod"
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/README.md b/pkg/chartutil/testdata/three-level-dependent-chart/README.md
new file mode 100644
index 000000000..a5fed642d
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/README.md
@@ -0,0 +1,16 @@
+# Three Level Dependent Chart
+
+This chart is for testing the processing of multi-level dependencies.
+
+Consists of the following charts:
+
+- Library Chart
+- App Chart (Uses Library Chart as dependecy, 2x: app1/app2)
+- Umbrella Chart (Has all the app charts as dependencies)
+
+The precendence is as follows: `library < app < umbrella`
+
+Catches two use-cases:
+
+- app overwriting library (app2)
+- umbrella overwriting app and library (app1)
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml
new file mode 100644
index 000000000..7552e07cd
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/Chart.yaml
@@ -0,0 +1,13 @@
+apiVersion: v2
+name: umbrella
+description: A Helm chart for Kubernetes
+type: application
+version: 0.1.0
+
+dependencies:
+- name: app1
+  version: 0.1.0
+  condition: app1.enabled
+- name: app2
+  version: 0.1.0
+  condition: app2.enabled
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/Chart.yaml
new file mode 100644
index 000000000..388245e31
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: app1
+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/app1/charts/library/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/Chart.yaml
new file mode 100644
index 000000000..f2f8a90d9
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/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/app1/charts/library/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/templates/service.yaml
new file mode 100644
index 000000000..3fd398b53
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/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/app1/charts/library/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml
new file mode 100644
index 000000000..0c08b6cd2
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/charts/library/values.yaml
@@ -0,0 +1,5 @@
+exports:
+  defaults:
+    service:
+      type: ClusterIP
+      port: 9090
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/templates/service.yaml
new file mode 100644
index 000000000..8ed8ddf1f
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/templates/service.yaml
@@ -0,0 +1,1 @@
+{{- include "library.service" . }}
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
new file mode 100644
index 000000000..3728aa930
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app1/values.yaml
@@ -0,0 +1,3 @@
+service:
+  type: ClusterIP
+  port: 1234
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
new file mode 100644
index 000000000..fea2768c7
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: app2
+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/app2/charts/library/Chart.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/Chart.yaml
new file mode 100644
index 000000000..f2f8a90d9
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/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/app2/charts/library/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/templates/service.yaml
new file mode 100644
index 000000000..3fd398b53
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/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/app2/charts/library/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml
new file mode 100644
index 000000000..0c08b6cd2
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/charts/library/values.yaml
@@ -0,0 +1,5 @@
+exports:
+  defaults:
+    service:
+      type: ClusterIP
+      port: 9090
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/templates/service.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/templates/service.yaml
new file mode 100644
index 000000000..8ed8ddf1f
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/templates/service.yaml
@@ -0,0 +1,1 @@
+{{- include "library.service" . }}
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
new file mode 100644
index 000000000..98bd6d24b
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/charts/app2/values.yaml
@@ -0,0 +1,3 @@
+service:
+  type: ClusterIP
+  port: 8080
diff --git a/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml
new file mode 100644
index 000000000..94ee31855
--- /dev/null
+++ b/pkg/chartutil/testdata/three-level-dependent-chart/umbrella/values.yaml
@@ -0,0 +1,8 @@
+app1:
+  enabled: true
+  service:
+    type: ClusterIP
+    port: 3456
+
+app2:
+  enabled: true