copy dependency metadata on aliasing to avoid sharing imported values

imported values are stored in dependency objects, which breaks if a chart dependency is shared among multiple aliases.
By copying the dependency objects in the metadata values can be imported correctly.

Supersedes #10174

Signed-off-by: Daniel Strobusch <1847260+dastrobu@users.noreply.github.com>
pull/9175/head
Daniel Strobusch 2 years ago
parent 26857e0c6d
commit a17f80d3e3
No known key found for this signature in database
GPG Key ID: 305FC1B7491BC270

@ -104,8 +104,7 @@ func getAliasDependency(charts []*chart.Chart, dep *chart.Dependency) *chart.Cha
}
out := *c
md := *c.Metadata
out.Metadata = &md
out.Metadata = copyMetadata(c.Metadata)
// empty dependencies and shallow copy all dependencies, otherwise parent info may be corrupted if
// there is more than one dependency aliasing this chart
@ -116,13 +115,27 @@ func getAliasDependency(charts []*chart.Chart, dep *chart.Dependency) *chart.Cha
}
if dep.Alias != "" {
md.Name = dep.Alias
out.Metadata.Name = dep.Alias
}
return &out
}
return nil
}
func copyMetadata(metadata *chart.Metadata) *chart.Metadata {
md := *metadata
if md.Dependencies != nil {
dependencies := make([]*chart.Dependency, len(md.Dependencies))
for i := range md.Dependencies {
dependency := *md.Dependencies[i]
dependencies[i] = &dependency
}
md.Dependencies = dependencies
}
return &md
}
// processDependencyEnabled removes disabled charts from dependencies
func processDependencyEnabled(c *chart.Chart, v map[string]interface{}, path string) error {
if c.Metadata.Dependencies == nil {

@ -239,6 +239,38 @@ func TestProcessDependencyImportValues(t *testing.T) {
}
}
func TestProcessDependencyImportValuesFromSharedDependencyToAliases(t *testing.T) {
c := loadChart(t, "testdata/chart-with-import-from-aliased-dependencies")
if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("expected no errors but got %q", err)
}
if err := processDependencyImportValues(c); err != nil {
t.Fatalf("processing import values dependencies %v", err)
}
e := make(map[string]string)
e["foo-defaults.defaultValue"] = "42"
e["bar-defaults.defaultValue"] = "42"
e["foo.defaults.defaultValue"] = "42"
e["bar.defaults.defaultValue"] = "42"
e["foo.grandchild.defaults.defaultValue"] = "42"
e["bar.grandchild.defaults.defaultValue"] = "42"
cValues := Values(c.Values)
for kk, vv := range e {
pv, err := cValues.PathValue(kk)
if err != nil {
t.Fatalf("retrieving import values table %v %v", kk, err)
}
if pv != vv {
t.Errorf("failed to match imported value %v with expected %v", pv, vv)
}
}
}
func TestProcessDependencyImportValuesMultiLevelPrecedence(t *testing.T) {
c := loadChart(t, "testdata/three-level-dependent-chart/umbrella")

@ -0,0 +1,20 @@
apiVersion: v2
appVersion: 1.0.0
name: chart-with-dependency-aliased-twice
type: application
version: 1.0.0
dependencies:
- name: child
alias: foo
version: 1.0.0
import-values:
- parent: foo-defaults
child: defaults
- name: child
alias: bar
version: 1.0.0
import-values:
- parent: bar-defaults
child: defaults

@ -0,0 +1,12 @@
apiVersion: v2
appVersion: 1.0.0
name: child
type: application
version: 1.0.0
dependencies:
- name: grandchild
version: 1.0.0
import-values:
- parent: defaults
child: defaults

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 1.0.0
name: grandchild
type: application
version: 1.0.0

@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Chart.Name }}
data:
{{ .Values.defaults | toYaml }}

@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Chart.Name }}
data:
{{ toYaml .Values.defaults | indent 2 }}
Loading…
Cancel
Save