pull/31847/merge
Julian Siebert 2 days ago committed by GitHub
commit 6be4c3647c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -215,6 +215,27 @@ Loop:
// recursively call self to process sub dependencies
for _, t := range cd {
// When a dependency uses an alias, cvals[path][alias] may be missing keys
// that were instead placed in cvals[t.Metadata.Name] at the current values root by
// earlier CoalesceValues calls (which coalesce against the full values tree, not the
// path-scoped subtable). Backfill any missing keys into the path-scoped entry so
// condition checks see chart defaults; path-scoped values remain authoritative and
// win on conflicts.
if path != "" {
if pt, err := cvals.Table(strings.TrimSuffix(path, ".")); err == nil {
if top, ok := cvals[t.Metadata.Name].(map[string]any); ok {
if v, ok := pt[t.Metadata.Name]; ok && !istable(v) {
slog.Warn("skipping nested path update: value is not a table", "path", path+t.Metadata.Name)
} else {
nested, _ := v.(map[string]any)
if nested == nil {
nested = map[string]any{}
}
pt[t.Metadata.Name] = util.CoalesceTables(nested, top)
}
}
}
}
subpath := path + t.Metadata.Name + "."
if err := processDependencyEnabled(t, cvals, subpath); err != nil {
return err

@ -551,6 +551,73 @@ func validateDependencyTree(t *testing.T, c *chart.Chart) {
}
}
func TestDependencyEnabledAliasNestedCondition(t *testing.T) {
// Chart structure:
// parentchart -> mid (alias: midchart) -> leaf (alias: leafchart) -> util (condition: util.enabled)
//
// leaf/values.yaml sets util.enabled: false.
// No user-provided values override this.
// Expected: util is NOT included in the output.
c := loadChart(t, "testdata/alias-condition-nested")
if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("error processing enabled dependencies: %v", err)
}
names := extractChartNames(c)
expected := []string{"parentchart", "parentchart.midchart", "parentchart.midchart.leafchart"}
sort.Strings(expected)
if len(names) != len(expected) {
t.Fatalf("slice lengths do not match: got %v, expected %v", names, expected)
}
for i := range names {
if names[i] != expected[i] {
t.Fatalf("slice values do not match: got %v, expected %v", names, expected)
}
}
}
// TestDependencyEnabledAliasNestedConditionEnabled tests that overriding util.enabled=true
// through the parent chart's values correctly includes the dependency even when the leaf
// chart's default disables it. This is the complementary positive case to
// TestDependencyEnabledAliasNestedCondition.
func TestDependencyEnabledAliasNestedConditionEnabled(t *testing.T) {
// Chart structure:
// parentchart -> mid (alias: midchart) -> leaf (alias: leafchart) -> util (condition: util.enabled)
//
// leaf/values.yaml sets util.enabled: false by default.
// User-provided values override util.enabled=true via the full alias path.
// Expected: util IS included in the output.
c := loadChart(t, "testdata/alias-condition-nested")
vals := map[string]any{
"midchart": map[string]any{
"enabled": true,
"leafchart": map[string]any{
"enabled": true,
"util": map[string]any{
"enabled": true,
},
},
},
}
if err := processDependencyEnabled(c, vals, ""); err != nil {
t.Fatalf("error processing enabled dependencies: %v", err)
}
names := extractChartNames(c)
expected := []string{"parentchart", "parentchart.midchart", "parentchart.midchart.leafchart", "parentchart.midchart.leafchart.util"}
sort.Strings(expected)
if len(names) != len(expected) {
t.Fatalf("slice lengths do not match: got %v, expected %v", names, expected)
}
for i := range names {
if names[i] != expected[i] {
t.Fatalf("slice values do not match: got %v, expected %v", names, expected)
}
}
}
func TestChartWithDependencyAliasedTwiceAndDoublyReferencedSubDependency(t *testing.T) {
c := loadChart(t, "testdata/chart-with-dependency-aliased-twice")

@ -0,0 +1,9 @@
apiVersion: v3
name: parentchart
version: 0.1.0
dependencies:
- name: mid
repository: http://localhost:10191
version: 0.1.0
alias: midchart
condition: midchart.enabled

@ -0,0 +1,9 @@
apiVersion: v3
name: mid
version: 0.1.0
dependencies:
- name: leaf
repository: http://localhost:10191
version: 0.1.0
alias: leafchart
condition: leafchart.enabled

@ -0,0 +1,8 @@
apiVersion: v3
name: leaf
version: 0.1.0
dependencies:
- name: util
repository: http://localhost:10191
version: 0.1.0
condition: util.enabled

@ -0,0 +1,3 @@
# util is disabled by default in this chart's values
util:
enabled: false

@ -215,6 +215,27 @@ Loop:
// recursively call self to process sub dependencies
for _, t := range cd {
// When processing nested dependencies, CoalesceValues is invoked with the full values tree,
// so defaults for this dependency can be coalesced into cvals[t.Metadata.Name] at the
// current values root instead of into the path-scoped table (under `path`).
// Backfill any missing keys from the root entry into the path-scoped entry so condition
// checks see chart defaults.
// in both, the nested (alias-keyed) value wins.
if path != "" {
if pt, err := cvals.Table(strings.TrimSuffix(path, ".")); err == nil {
if top, ok := cvals[t.Metadata.Name].(map[string]any); ok {
if v, ok := pt[t.Metadata.Name]; ok && !istable(v) {
slog.Warn("skipping nested path update: value is not a table", "path", path+t.Metadata.Name)
} else {
nested, _ := v.(map[string]any)
if nested == nil {
nested = map[string]any{}
}
pt[t.Metadata.Name] = util.CoalesceTables(nested, top)
}
}
}
}
subpath := path + t.Metadata.Name + "."
if err := processDependencyEnabled(t, cvals, subpath); err != nil {
return err

@ -134,6 +134,76 @@ func TestDependencyEnabled(t *testing.T) {
}
}
// TestDependencyEnabledAliasNestedCondition tests that a condition defaulting to false in a
// leaf chart's values.yaml is respected when the leaf chart is accessed through multiple
// levels of aliased dependencies.
func TestDependencyEnabledAliasNestedCondition(t *testing.T) {
// Chart structure:
// parentchart -> mid (alias: midchart) -> leaf (alias: leafchart) -> util (condition: util.enabled)
//
// leaf/values.yaml sets util.enabled: false.
// No user-provided values override this.
// Expected: util is NOT included in the output.
c := loadChart(t, "testdata/alias-condition-nested")
if err := processDependencyEnabled(c, c.Values, ""); err != nil {
t.Fatalf("error processing enabled dependencies: %v", err)
}
names := extractChartNames(c)
expected := []string{"parentchart", "parentchart.midchart", "parentchart.midchart.leafchart"}
sort.Strings(expected)
if len(names) != len(expected) {
t.Fatalf("slice lengths do not match: got %v, expected %v", names, expected)
}
for i := range names {
if names[i] != expected[i] {
t.Fatalf("slice values do not match: got %v, expected %v", names, expected)
}
}
}
// TestDependencyEnabledAliasNestedConditionEnabled tests that overriding util.enabled=true
// through the parent chart's values correctly includes the dependency even when the leaf
// chart's default disables it. This is the complementary positive case to
// TestDependencyEnabledAliasNestedCondition.
func TestDependencyEnabledAliasNestedConditionEnabled(t *testing.T) {
// Chart structure:
// parentchart -> mid (alias: midchart) -> leaf (alias: leafchart) -> util (condition: util.enabled)
//
// leaf/values.yaml sets util.enabled: false by default.
// User-provided values override util.enabled=true via the full alias path.
// Expected: util IS included in the output.
c := loadChart(t, "testdata/alias-condition-nested")
vals := map[string]any{
"midchart": map[string]any{
"enabled": true,
"leafchart": map[string]any{
"enabled": true,
"util": map[string]any{
"enabled": true,
},
},
},
}
if err := processDependencyEnabled(c, vals, ""); err != nil {
t.Fatalf("error processing enabled dependencies: %v", err)
}
names := extractChartNames(c)
expected := []string{"parentchart", "parentchart.midchart", "parentchart.midchart.leafchart", "parentchart.midchart.leafchart.util"}
sort.Strings(expected)
if len(names) != len(expected) {
t.Fatalf("slice lengths do not match: got %v, expected %v", names, expected)
}
for i := range names {
if names[i] != expected[i] {
t.Fatalf("slice values do not match: got %v, expected %v", names, expected)
}
}
}
// extractChartNames recursively searches chart dependencies returning all charts found
func extractChartNames(c *chart.Chart) []string {
var out []string

@ -0,0 +1,9 @@
apiVersion: v2
name: parentchart
version: 0.1.0
dependencies:
- name: mid
repository: http://localhost:10191
version: 0.1.0
alias: midchart
condition: midchart.enabled

@ -0,0 +1,9 @@
apiVersion: v2
name: mid
version: 0.1.0
dependencies:
- name: leaf
repository: http://localhost:10191
version: 0.1.0
alias: leafchart
condition: leafchart.enabled

@ -0,0 +1,8 @@
apiVersion: v2
name: leaf
version: 0.1.0
dependencies:
- name: util
repository: http://localhost:10191
version: 0.1.0
condition: util.enabled

@ -0,0 +1,3 @@
# util is disabled by default in this chart's values
util:
enabled: false
Loading…
Cancel
Save