Make .Environment values available in .gotmpl files. (#2000)
Currently it's not possible to use `.Environment` values in `*.gomtpl` files. The documentation states the opposite: https://github.com/roboll/helmfile#environment (2nd paragraph). The problem is already described in #1090. This PR fixes this bug. Fixes #1090 Co-authored-by: Peter Aichinger <petera@topdesk.com>
This commit is contained in:
		
							parent
							
								
									9354c38a0a
								
							
						
					
					
						commit
						ca6dd7a60f
					
				|  | @ -52,7 +52,7 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e | |||
| 		storage := state.NewStorage(opts.CalleePath, ld.logger, ld.glob) | ||||
| 		envld := state.NewEnvironmentValuesLoader(storage, ld.readFile, ld.logger, ld.remote) | ||||
| 		handler := state.MissingFileHandlerError | ||||
| 		vals, err := envld.LoadEnvironmentValues(&handler, args) | ||||
| 		vals, err := envld.LoadEnvironmentValues(&handler, args, &environment.EmptyEnvironment) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  |  | |||
|  | @ -153,7 +153,7 @@ func (c *StateCreator) LoadEnvValues(target *HelmState, env string, ctxEnv *envi | |||
| 		return nil, &StateLoadError{fmt.Sprintf("failed to read %s", state.FilePath), err} | ||||
| 	} | ||||
| 
 | ||||
| 	newDefaults, err := state.loadValuesEntries(nil, state.DefaultValues, c.remote) | ||||
| 	newDefaults, err := state.loadValuesEntries(nil, state.DefaultValues, c.remote, ctxEnv) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -227,7 +227,7 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn | |||
| 	envSpec, ok := st.Environments[name] | ||||
| 	if ok { | ||||
| 		var err error | ||||
| 		envVals, err = st.loadValuesEntries(envSpec.MissingFileHandler, envSpec.Values, c.remote) | ||||
| 		envVals, err = st.loadValuesEntries(envSpec.MissingFileHandler, envSpec.Values, c.remote, ctxEnv) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -363,13 +363,13 @@ func (c *StateCreator) scatterGatherEnvSecretFiles(st *HelmState, envSecretFiles | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []interface{}, remote *remote.Remote) (map[string]interface{}, error) { | ||||
| func (st *HelmState) loadValuesEntries(missingFileHandler *string, entries []interface{}, remote *remote.Remote, ctxEnv *environment.Environment) (map[string]interface{}, error) { | ||||
| 	envVals := map[string]interface{}{} | ||||
| 
 | ||||
| 	valuesEntries := append([]interface{}{}, entries...) | ||||
| 	ld := NewEnvironmentValuesLoader(st.storage(), st.readFile, st.logger, remote) | ||||
| 	var err error | ||||
| 	envVals, err = ld.LoadEnvironmentValues(missingFileHandler, valuesEntries) | ||||
| 	envVals, err = ld.LoadEnvironmentValues(missingFileHandler, valuesEntries, ctxEnv) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ import ( | |||
| 	"reflect" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/roboll/helmfile/pkg/environment" | ||||
| 	"github.com/roboll/helmfile/pkg/remote" | ||||
| 
 | ||||
| 	"github.com/roboll/helmfile/pkg/testhelper" | ||||
|  | @ -117,6 +118,7 @@ baz: "{{ readFile \"baz.txt\" }}"`) | |||
| 	barYamlFile := "/example/path/to/bar.yaml.gotmpl" | ||||
| 	barYamlContent := []byte(`foo: FOO | ||||
| bar: {{ readFile "bar.txt" }} | ||||
| env: {{ .Environment.Name }} | ||||
| `) | ||||
| 
 | ||||
| 	barTextFile := "/example/path/to/bar.txt" | ||||
|  | @ -127,6 +129,7 @@ bar: {{ readFile "bar.txt" }} | |||
| 		"bar": "BAR", | ||||
| 		// As the file doesn't have an file extension ".gotmpl", this template expression should not be evaluated
 | ||||
| 		"baz": "{{ readFile \"baz.txt\" }}", | ||||
| 		"env": "production", | ||||
| 	} | ||||
| 
 | ||||
| 	valuesFile := "/example/path/to/values.yaml.gotmpl" | ||||
|  | @ -149,8 +152,11 @@ releaseNamespace: mynamespace | |||
| 	testFs.Cwd = "/example/path/to" | ||||
| 
 | ||||
| 	r := remote.NewRemote(logger, testFs.Cwd, testFs.ReadFile, testFs.DirectoryExistsAt, testFs.FileExistsAt) | ||||
| 	env := environment.Environment{ | ||||
| 		Name: "production", | ||||
| 	} | ||||
| 	state, err := NewCreator(logger, testFs.ReadFile, testFs.FileExists, testFs.Abs, testFs.Glob, testFs.DirectoryExistsAt, nil, nil, "", r). | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, nil) | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, &env) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("unexpected error: %v", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -2,6 +2,8 @@ package state | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"github.com/imdario/mergo" | ||||
| 	"github.com/roboll/helmfile/pkg/environment" | ||||
| 	"github.com/roboll/helmfile/pkg/maputil" | ||||
|  | @ -9,7 +11,6 @@ import ( | |||
| 	"github.com/roboll/helmfile/pkg/tmpl" | ||||
| 	"go.uber.org/zap" | ||||
| 	"gopkg.in/yaml.v2" | ||||
| 	"path/filepath" | ||||
| ) | ||||
| 
 | ||||
| type EnvironmentValuesLoader struct { | ||||
|  | @ -31,7 +32,7 @@ func NewEnvironmentValuesLoader(storage *Storage, readFile func(string) ([]byte, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *string, valuesEntries []interface{}) (map[string]interface{}, error) { | ||||
| func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *string, valuesEntries []interface{}, ctxEnv *environment.Environment) (map[string]interface{}, error) { | ||||
| 	result := map[string]interface{}{} | ||||
| 
 | ||||
| 	for _, entry := range valuesEntries { | ||||
|  | @ -54,7 +55,13 @@ func (ld *EnvironmentValuesLoader) LoadEnvironmentValues(missingFileHandler *str | |||
| 			} | ||||
| 
 | ||||
| 			for _, f := range files { | ||||
| 				tmplData := EnvironmentTemplateData{environment.EmptyEnvironment, "", map[string]interface{}{}} | ||||
| 				var env environment.Environment | ||||
| 				if ctxEnv == nil { | ||||
| 					env = environment.EmptyEnvironment | ||||
| 				} else { | ||||
| 					env = *ctxEnv | ||||
| 				} | ||||
| 				tmplData := EnvironmentTemplateData{env, "", map[string]interface{}{}} | ||||
| 				r := tmpl.NewFileRenderer(ld.readFile, filepath.Dir(f), tmplData) | ||||
| 				bytes, err := r.RenderToBytes(f) | ||||
| 				if err != nil { | ||||
|  |  | |||
|  | @ -1,12 +1,13 @@ | |||
| package state | ||||
| 
 | ||||
| import ( | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| 	"github.com/roboll/helmfile/pkg/remote" | ||||
| 	"go.uber.org/zap" | ||||
| 	"io/ioutil" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
| 	"github.com/roboll/helmfile/pkg/remote" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
| 
 | ||||
| func newLoader() *EnvironmentValuesLoader { | ||||
|  | @ -34,7 +35,7 @@ func newLoader() *EnvironmentValuesLoader { | |||
| func TestEnvValsLoad_SingleValuesFile(t *testing.T) { | ||||
| 	l := newLoader() | ||||
| 
 | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.5.yaml"}) | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.5.yaml"}, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -52,7 +53,7 @@ func TestEnvValsLoad_SingleValuesFile(t *testing.T) { | |||
| func TestEnvValsLoad_OverwriteNilValue_Issue1150(t *testing.T) { | ||||
| 	l := newLoader() | ||||
| 
 | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.1.yaml", "testdata/values.2.yaml"}) | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.1.yaml", "testdata/values.2.yaml"}, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -74,7 +75,7 @@ func TestEnvValsLoad_OverwriteNilValue_Issue1150(t *testing.T) { | |||
| func TestEnvValsLoad_OverwriteWithNilValue_Issue1154(t *testing.T) { | ||||
| 	l := newLoader() | ||||
| 
 | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.3.yaml", "testdata/values.4.yaml"}) | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/values.3.yaml", "testdata/values.4.yaml"}, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -97,7 +98,7 @@ func TestEnvValsLoad_OverwriteWithNilValue_Issue1154(t *testing.T) { | |||
| func TestEnvValsLoad_OverwriteEmptyValue_Issue1168(t *testing.T) { | ||||
| 	l := newLoader() | ||||
| 
 | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/issues/1168/addons.yaml", "testdata/issues/1168/addons2.yaml"}) | ||||
| 	actual, err := l.LoadEnvironmentValues(nil, []interface{}{"testdata/issues/1168/addons.yaml", "testdata/issues/1168/addons2.yaml"}, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue