fix(pkg/chartutil): conditions for alias and umrella charts (#3734)

Enable to use charts with dependencies that have conditions (e.g. in
umbrella charts). Allow aliases for dependencies that have dependencies
with conditions.

Closes #3734

Signed-off-by: Christian Koeberl <christian.koeberl@gmail.com>
pull/4917/head
Christian Koeberl 6 years ago
parent 2207f84964
commit 62533e2b0e

@ -24,14 +24,14 @@ import (
) )
func ProcessDependencies(c *chart.Chart, v Values) error { func ProcessDependencies(c *chart.Chart, v Values) error {
if err := processDependencyEnabled(c, v); err != nil { if err := processDependencyEnabled(c, v, ""); err != nil {
return err return err
} }
return processDependencyImportValues(c) return processDependencyImportValues(c)
} }
// processDependencyConditions disables charts based on condition path value in values // processDependencyConditions disables charts based on condition path value in values
func processDependencyConditions(reqs []*chart.Dependency, cvals Values) { func processDependencyConditions(reqs []*chart.Dependency, cvals Values, cpath string) {
if reqs == nil { if reqs == nil {
return return
} }
@ -40,7 +40,7 @@ func processDependencyConditions(reqs []*chart.Dependency, cvals Values) {
for _, c := range strings.Split(strings.TrimSpace(r.Condition), ",") { for _, c := range strings.Split(strings.TrimSpace(r.Condition), ",") {
if len(c) > 0 { if len(c) > 0 {
// retrieve value // retrieve value
vv, err := cvals.PathValue(c) vv, err := cvals.PathValue(cpath + c)
if err == nil { if err == nil {
// if not bool, warn // if not bool, warn
if bv, ok := vv.(bool); ok { if bv, ok := vv.(bool); ok {
@ -129,7 +129,7 @@ func getAliasDependency(charts []*chart.Chart, dep *chart.Dependency) *chart.Cha
} }
// processDependencyEnabled removes disabled charts from dependencies // processDependencyEnabled removes disabled charts from dependencies
func processDependencyEnabled(c *chart.Chart, v map[string]interface{}) error { func processDependencyEnabled(c *chart.Chart, v map[string]interface{}, path string) error {
if c.Metadata.Dependencies == nil { if c.Metadata.Dependencies == nil {
return nil return nil
} }
@ -170,7 +170,7 @@ Loop:
} }
// flag dependencies as enabled/disabled // flag dependencies as enabled/disabled
processDependencyTags(c.Metadata.Dependencies, cvals) processDependencyTags(c.Metadata.Dependencies, cvals)
processDependencyConditions(c.Metadata.Dependencies, cvals) processDependencyConditions(c.Metadata.Dependencies, cvals, path)
// make a map of charts to remove // make a map of charts to remove
rm := map[string]struct{}{} rm := map[string]struct{}{}
for _, r := range c.Metadata.Dependencies { for _, r := range c.Metadata.Dependencies {
@ -190,7 +190,8 @@ Loop:
// recursively call self to process sub dependencies // recursively call self to process sub dependencies
for _, t := range cd { for _, t := range cd {
if err := processDependencyEnabled(t, cvals); err != nil { subpath := path + t.Metadata.Name + "."
if err := processDependencyEnabled(t, cvals, subpath); err != nil {
return err return err
} }
} }

@ -99,18 +99,22 @@ func TestDependencyEnabled(t *testing.T) {
[]string{"parentchart", "parentchart.subchart1", "parentchart.subchart1.subchartb"}, []string{"parentchart", "parentchart.subchart1", "parentchart.subchart1.subchartb"},
}, { }, {
"tags enabling a parent/child group with condition disabling one child", "tags enabling a parent/child group with condition disabling one child",
M{"subchartc": M{"enabled": false}, "tags": M{"back-end": true}}, M{"subchart2": M{"subchartc": M{"enabled": false}}, "tags": M{"back-end": true}},
[]string{"parentchart", "parentchart.subchart1", "parentchart.subchart1.subcharta", "parentchart.subchart1.subchartb", "parentchart.subchart2", "parentchart.subchart2.subchartb"}, []string{"parentchart", "parentchart.subchart1", "parentchart.subchart1.subcharta", "parentchart.subchart1.subchartb", "parentchart.subchart2", "parentchart.subchart2.subchartb"},
}, { }, {
"tags will not enable a child if parent is explicitly disabled with condition", "tags will not enable a child if parent is explicitly disabled with condition",
M{"subchart1": M{"enabled": false}, "tags": M{"front-end": true}}, M{"subchart1": M{"enabled": false}, "tags": M{"front-end": true}},
[]string{"parentchart"}, []string{"parentchart"},
}, {
"subcharts with alias also respect conditions",
M{"subchart1": M{"enabled": false}, "subchart2alias": M{"enabled": true, "subchartb": M{"enabled": true}}},
[]string{"parentchart", "parentchart.subchart2alias", "parentchart.subchart2alias.subchartb"},
}} }}
for _, tc := range tests { for _, tc := range tests {
c := loadChart(t, "testdata/subpop") c := loadChart(t, "testdata/subpop")
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if err := processDependencyEnabled(c, tc.v); err != nil { if err := processDependencyEnabled(c, tc.v, ""); err != nil {
t.Fatalf("error processing enabled dependencies %v", err) t.Fatalf("error processing enabled dependencies %v", err)
} }
@ -279,7 +283,7 @@ func TestDependentChartAliases(t *testing.T) {
t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies()))
} }
if err := processDependencyEnabled(c, c.Values); err != nil { if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("expected no errors but got %q", err) t.Fatalf("expected no errors but got %q", err)
} }
@ -300,7 +304,7 @@ func TestDependentChartWithSubChartsAbsentInDependency(t *testing.T) {
t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies()))
} }
if err := processDependencyEnabled(c, c.Values); err != nil { if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("expected no errors but got %q", err) t.Fatalf("expected no errors but got %q", err)
} }
@ -332,7 +336,7 @@ func TestDependentChartsWithSubchartsAllSpecifiedInDependency(t *testing.T) {
t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies()))
} }
if err := processDependencyEnabled(c, c.Values); err != nil { if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("expected no errors but got %q", err) t.Fatalf("expected no errors but got %q", err)
} }
@ -352,7 +356,7 @@ func TestDependentChartsWithSomeSubchartsSpecifiedInDependency(t *testing.T) {
t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies())) t.Fatalf("expected 2 dependencies for this chart, but got %d", len(c.Dependencies()))
} }
if err := processDependencyEnabled(c, c.Values); err != nil { if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("expected no errors but got %q", err) t.Fatalf("expected no errors but got %q", err)
} }

@ -33,3 +33,9 @@ dependencies:
tags: tags:
- back-end - back-end
- subchart2 - subchart2
- name: subchart2
alias: subchart2alias
repository: http://localhost:10191
version: 0.1.0
condition: subchart2alias.enabled

@ -6,7 +6,7 @@ dependencies:
- name: subcharta - name: subcharta
repository: http://localhost:10191 repository: http://localhost:10191
version: 0.1.0 version: 0.1.0
condition: subcharta.enabled,subchart1.subcharta.enabled condition: subcharta.enabled
tags: tags:
- front-end - front-end
- subcharta - subcharta

@ -6,7 +6,7 @@ dependencies:
- name: subchartb - name: subchartb
repository: http://localhost:10191 repository: http://localhost:10191
version: 0.1.0 version: 0.1.0
condition: subchartb.enabled,subchart2.subchartb.enabled condition: subchartb.enabled
tags: tags:
- back-end - back-end
- subchartb - subchartb

@ -38,3 +38,6 @@ overridden-chartA-B:
tags: tags:
front-end: true front-end: true
back-end: false back-end: false
subchart2alias:
enabled: false

Loading…
Cancel
Save