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

@ -214,6 +214,24 @@ 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 coalesced into cvals[originalName] by ancestor CoalesceValues
// calls (which used the original chart name, not the alias). To correct
// this, we backfill any missing keys from the top-level entry into the
// nested path entry. The nested entry is authoritative: if a key exists
// 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]interface{}); 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]interface{})
pt[t.Metadata.Name] = util.CoalesceTables(nested, top)
}
}
}
}
subpath := path + t.Metadata.Name + "."
if err := processDependencyEnabled(t, cvals, subpath); err != nil {
return err

@ -552,6 +552,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]interface{}{
"midchart": map[string]interface{}{
"enabled": true,
"leafchart": map[string]interface{}{
"enabled": true,
"util": map[string]interface{}{
"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

@ -214,6 +214,24 @@ 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 coalesced into cvals[originalName] by ancestor CoalesceValues
// calls (which used the original chart name, not the alias). To correct
// this, we backfill any missing keys from the top-level entry into the
// nested path entry. The nested entry is authoritative: if a key exists
// 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]interface{}); 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]interface{})
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]interface{}{
"midchart": map[string]interface{}{
"enabled": true,
"leafchart": map[string]interface{}{
"enabled": true,
"util": map[string]interface{}{
"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