[#9136] - Deep copy chart values before coalescing to prevent mutating the chart

Signed-off-by: Elliot Kennedy <me@elken.io>
pull/9138/head
Elliot Kennedy 5 years ago
parent 617c9e1b12
commit 018982f177

@ -146,7 +146,12 @@ func copyMap(src map[string]interface{}) map[string]interface{} {
// //
// Values in v will override the values in the chart. // Values in v will override the values in the chart.
func coalesceValues(c *chart.Chart, v map[string]interface{}) { func coalesceValues(c *chart.Chart, v map[string]interface{}) {
for key, val := range c.Values { valsCopy, err := copystructure.Copy(c.Values)
if err != nil {
log.Printf("warning: could not copy values %+v. Using raw values from chart. Exception:\n%s", c.Values, err)
valsCopy = c.Values
}
for key, val := range valsCopy.(map[string]interface{}) {
if value, ok := v[key]; ok { if value, ok := v[key]; ok {
if value == nil { if value == nil {
// When the YAML value is null, we remove the value's key. // When the YAML value is null, we remove the value's key.

@ -18,6 +18,7 @@ package chartutil
import ( import (
"encoding/json" "encoding/json"
"github.com/mitchellh/copystructure"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -78,11 +79,12 @@ func TestCoalesceValues(t *testing.T) {
"right": "exists", "right": "exists",
"scope": "moby", "scope": "moby",
"top": "nope", "top": "nope",
"pequod": map[string]interface{}{"nested": map[string]interface{}{"bar": nil}},
}, },
}, },
withDeps(&chart.Chart{ withDeps(&chart.Chart{
Metadata: &chart.Metadata{Name: "pequod"}, Metadata: &chart.Metadata{Name: "pequod"},
Values: map[string]interface{}{"name": "pequod", "scope": "pequod"}, Values: map[string]interface{}{"name": "pequod", "scope": "pequod", "nested": map[string]interface{}{"bar": "true"}},
}, },
&chart.Chart{ &chart.Chart{
Metadata: &chart.Metadata{Name: "ahab"}, Metadata: &chart.Metadata{Name: "ahab"},
@ -105,12 +107,15 @@ func TestCoalesceValues(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// taking a copy of the values before passing it // take a copy of the values and chart values before passing
// to CoalesceValues as argument, so that we can // to CoalesceValues, so that we can use for asserting later
// use it for asserting later valsCopy, err := copystructure.Copy(vals)
valsCopy := make(Values, len(vals)) if err != nil {
for key, value := range vals { t.Fatal(err)
valsCopy[key] = value }
chartValsCopy, err := copystructure.Copy(c.Values)
if err != nil {
t.Fatal(err)
} }
v, err := CoalesceValues(c, vals) v, err := CoalesceValues(c, vals)
@ -131,6 +136,7 @@ func TestCoalesceValues(t *testing.T) {
{"{{.global.subject}}", "Queequeg"}, {"{{.global.subject}}", "Queequeg"},
{"{{.global.harpooner}}", "<no value>"}, {"{{.global.harpooner}}", "<no value>"},
{"{{.pequod.name}}", "pequod"}, {"{{.pequod.name}}", "pequod"},
{"{{.pequod.nested.bar}}", "<no value>"},
{"{{.pequod.ahab.name}}", "ahab"}, {"{{.pequod.ahab.name}}", "ahab"},
{"{{.pequod.ahab.scope}}", "whale"}, {"{{.pequod.ahab.scope}}", "whale"},
{"{{.pequod.ahab.nested.foo}}", "true"}, {"{{.pequod.ahab.nested.foo}}", "true"},
@ -177,6 +183,7 @@ func TestCoalesceValues(t *testing.T) {
// CoalesceValues should not mutate the passed arguments // CoalesceValues should not mutate the passed arguments
is.Equal(valsCopy, vals) is.Equal(valsCopy, vals)
is.Equal(chartValsCopy, c.Values)
} }
func TestCoalesceTables(t *testing.T) { func TestCoalesceTables(t *testing.T) {

Loading…
Cancel
Save