Repository: rancher/fleet

Issue:
Issue #20
Just a reminder... (backport of #3832 to v0.12/Rancher v2.11)

Discussion:
@mmartin24: Please see the verification done [here](https://github.com/rancher/fleet-security/issues/19#issuecomment-3164971500).
If the extend of the verification is ok, please feel free to close this ticket.
Thanks @0xavi0 for the guidance here. 

CC: @kkaempf @kkaempf: Discussed in weekly, closing.

Solution patch:
diff --git a/internal/bundlereader/resources.go b/internal/bundlereader/resources.go
index 4a470a8d..58d4904c 100644
--- a/internal/bundlereader/resources.go
+++ b/internal/bundlereader/resources.go
@@ -99,15 +99,29 @@ type loadOpts struct {
 // * spec.Targets[].Helm.ValuesFiles
 func ignoreApplyConfigs(spec *fleet.HelmOptions, targets ...fleet.BundleTarget) []string {
 	ignore := []string{"fleet.yaml"}
+
+	// Values files may be referenced from `fleet.yaml` files either with their file name
+	// alone, or with a directory prefix, for instance for a chart directory.
+	// Values files must be ignored in both cases, and determining which of the filename or full path will be needed
+	// depends on where the `fleet.yaml` file lives relatively to the values file(s) which it references.
 	if spec != nil {
 		ignore = append(ignore, spec.ValuesFiles...)
+
+		for _, vf := range spec.ValuesFiles {
+			ignore = append(ignore, filepath.Base(vf))
+		}
 	}
 
 	for _, target := range targets {
 		if target.Helm == nil {
 			continue
 		}
+
 		ignore = append(ignore, target.Helm.ValuesFiles...)
+
+		for _, vf := range target.Helm.ValuesFiles {
+			ignore = append(ignore, filepath.Base(vf))
+		}
 	}
 
 	return ignore



Test patch:
diff --git a/integrationtests/cli/apply/apply_test.go b/integrationtests/cli/apply/apply_test.go
index 680fe16b..88977e77 100644
--- a/integrationtests/cli/apply/apply_test.go
+++ b/integrationtests/cli/apply/apply_test.go
@@ -192,6 +192,38 @@ var _ = Describe("Fleet apply", Ordered, func() {
 			})
 		})
 	})
+
+	When("a fleet.yaml located beside a local chart dir references a values file prefixed by its directory", func() {
+		BeforeEach(func() {
+			name = "helm-values-ignore"
+			dirs = []string{cli.AssetsPath + name}
+		})
+
+		It("creates a bundle without the values file", func() {
+			bundle, err := cli.GetBundleFromOutput(buf)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(bundle.Spec.Resources).To(HaveLen(2))
+
+			Expect(cli.AssetsPath + "helm-values-ignore/config-chart/templates/configmap.yaml").To(bePresentInBundleResources(bundle.Spec.Resources))
+			Expect(cli.AssetsPath + "helm-values-ignore/config-chart/Chart.yaml").To(bePresentInBundleResources(bundle.Spec.Resources))
+		})
+	})
+
+	When("a fleet.yaml located within a local chart dir references a values file prefixed by its directory", func() {
+		BeforeEach(func() {
+			name = "helm-in-chart-fleetyaml-values-ignore"
+			dirs = []string{cli.AssetsPath + name}
+		})
+
+		It("creates a bundle without the values file", func() {
+			bundle, err := cli.GetBundleFromOutput(buf)
+			Expect(err).NotTo(HaveOccurred())
+			Expect(bundle.Spec.Resources).To(HaveLen(2))
+
+			Expect(cli.AssetsPath + "helm-in-chart-fleetyaml-values-ignore/config-chart/templates/configmap.yaml").To(bePresentInBundleResources(bundle.Spec.Resources))
+			Expect(cli.AssetsPath + "helm-in-chart-fleetyaml-values-ignore/config-chart/Chart.yaml").To(bePresentInBundleResources(bundle.Spec.Resources))
+		})
+	})
 })
 
 var _ = Describe("Fleet apply with helm charts with dependencies", Ordered, func() {
diff --git a/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/Chart.yaml b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/Chart.yaml
new file mode 100644
index 00000000..7ba744f9
--- /dev/null
+++ b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: config-chart
+description: A test chart that verifies its config
+type: application
+version: 0.1.0
+appVersion: "1.16.0"
diff --git a/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/fleet.yaml b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/fleet.yaml
new file mode 100644
index 00000000..d13c9191
--- /dev/null
+++ b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/fleet.yaml
@@ -0,0 +1,3 @@
+helm:
+  valuesFiles:
+    - config-chart/values.yaml # resolves to `values.yaml` inside the same directory, but looks like an out-of-tree file
diff --git a/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/templates/configmap.yaml b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/templates/configmap.yaml
new file mode 100644
index 00000000..ff4c3e70
--- /dev/null
+++ b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/templates/configmap.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: app-config
+data:
+  test: "value"
+  name: {{ .Values.name }}
diff --git a/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/values.yaml b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/values.yaml
new file mode 100644
index 00000000..1c104ca1
--- /dev/null
+++ b/integrationtests/cli/assets/helm-in-chart-fleetyaml-values-ignore/config-chart/values.yaml
@@ -0,0 +1 @@
+name: global.fleet.clusterLabels.management.cattle.io/cluster-display-name
diff --git a/integrationtests/cli/assets/helm-values-ignore/config-chart/Chart.yaml b/integrationtests/cli/assets/helm-values-ignore/config-chart/Chart.yaml
new file mode 100644
index 00000000..7ba744f9
--- /dev/null
+++ b/integrationtests/cli/assets/helm-values-ignore/config-chart/Chart.yaml
@@ -0,0 +1,6 @@
+apiVersion: v2
+name: config-chart
+description: A test chart that verifies its config
+type: application
+version: 0.1.0
+appVersion: "1.16.0"
diff --git a/integrationtests/cli/assets/helm-values-ignore/config-chart/templates/configmap.yaml b/integrationtests/cli/assets/helm-values-ignore/config-chart/templates/configmap.yaml
new file mode 100644
index 00000000..ff4c3e70
--- /dev/null
+++ b/integrationtests/cli/assets/helm-values-ignore/config-chart/templates/configmap.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: app-config
+data:
+  test: "value"
+  name: {{ .Values.name }}
diff --git a/integrationtests/cli/assets/helm-values-ignore/config-chart/values.yaml b/integrationtests/cli/assets/helm-values-ignore/config-chart/values.yaml
new file mode 100644
index 00000000..1c104ca1
--- /dev/null
+++ b/integrationtests/cli/assets/helm-values-ignore/config-chart/values.yaml
@@ -0,0 +1 @@
+name: global.fleet.clusterLabels.management.cattle.io/cluster-display-name
diff --git a/integrationtests/cli/assets/helm-values-ignore/fleet.yaml b/integrationtests/cli/assets/helm-values-ignore/fleet.yaml
new file mode 100644
index 00000000..b8a0544e
--- /dev/null
+++ b/integrationtests/cli/assets/helm-values-ignore/fleet.yaml
@@ -0,0 +1,4 @@
+helm:
+  chart: config-chart
+  valuesFiles:
+    - config-chart/values.yaml