feat: Allow .Release.Name to be used in gotmpl values templates (#1424)
This adds the ability to utilize `.Release` inside of gotmpl files as discussed [here](https://github.com/roboll/helmfile/issues/760). Resolves: https://github.com/roboll/helmfile/issues/760 Co-authored-by: Yusuke Kuoka <ykuoka@gmail.com>
This commit is contained in:
parent
c575587e1f
commit
7b11ce851a
|
|
@ -100,9 +100,11 @@ bar: {{ readFile "bar.txt" }}
|
|||
}
|
||||
|
||||
valuesFile := "/example/path/to/values.yaml.gotmpl"
|
||||
valuesContent := []byte(`env: {{ .Environment.Name }}`)
|
||||
valuesContent := []byte(`env: {{ .Environment.Name }}
|
||||
releaseName: {{ .Release.Name }}`)
|
||||
|
||||
expectedValues := `env: production`
|
||||
expectedValues := `env: production
|
||||
releaseName: myrelease`
|
||||
|
||||
testFs := testhelper.NewTestFs(map[string]string{
|
||||
fooYamlFile: string(fooYamlContent),
|
||||
|
|
@ -124,7 +126,11 @@ bar: {{ readFile "bar.txt" }}
|
|||
t.Errorf("unexpected environment values: expected=%v, actual=%v", expected, actual)
|
||||
}
|
||||
|
||||
actualValuesData, err := state.RenderValuesFileToBytes(valuesFile)
|
||||
var release = ReleaseSpec{
|
||||
Name: "myrelease",
|
||||
}
|
||||
|
||||
actualValuesData, err := state.RenderReleaseValuesFileToBytes(&release, valuesFile)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
|
|||
|
||||
jsonPatches := release.JSONPatches
|
||||
if len(jsonPatches) > 0 {
|
||||
generatedFiles, err := st.generateTemporaryValuesFiles(jsonPatches, release.MissingFileHandler)
|
||||
generatedFiles, err := st.generateTemporaryReleaseValuesFiles(release, jsonPatches, release.MissingFileHandler)
|
||||
if err != nil {
|
||||
return nil, clean, err
|
||||
}
|
||||
|
|
@ -130,7 +130,7 @@ func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSp
|
|||
|
||||
strategicMergePatches := release.StrategicMergePatches
|
||||
if len(strategicMergePatches) > 0 {
|
||||
generatedFiles, err := st.generateTemporaryValuesFiles(strategicMergePatches, release.MissingFileHandler)
|
||||
generatedFiles, err := st.generateTemporaryReleaseValuesFiles(release, strategicMergePatches, release.MissingFileHandler)
|
||||
if err != nil {
|
||||
return nil, clean, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2084,8 +2084,14 @@ func (st *HelmState) flagsForLint(helm helmexec.Interface, release *ReleaseSpec,
|
|||
return flags, files, nil
|
||||
}
|
||||
|
||||
func (st *HelmState) RenderValuesFileToBytes(path string) ([]byte, error) {
|
||||
r := tmpl.NewFileRenderer(st.readFile, filepath.Dir(path), st.valuesFileTemplateData())
|
||||
func (st *HelmState) RenderReleaseValuesFileToBytes(release *ReleaseSpec, path string) ([]byte, error) {
|
||||
vals, err := st.Values()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
templateData := st.createReleaseTemplateData(release, vals)
|
||||
|
||||
r := tmpl.NewFileRenderer(st.readFile, filepath.Dir(path), templateData)
|
||||
rawBytes, err := r.RenderToBytes(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -2164,7 +2170,7 @@ func (st *HelmState) removeFiles(files []string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (st *HelmState) generateTemporaryValuesFiles(values []interface{}, missingFileHandler *string) ([]string, error) {
|
||||
func (st *HelmState) generateTemporaryReleaseValuesFiles(release *ReleaseSpec, values []interface{}, missingFileHandler *string) ([]string, error) {
|
||||
generatedFiles := []string{}
|
||||
|
||||
for _, value := range values {
|
||||
|
|
@ -2183,7 +2189,7 @@ func (st *HelmState) generateTemporaryValuesFiles(values []interface{}, missingF
|
|||
}
|
||||
path := paths[0]
|
||||
|
||||
yamlBytes, err := st.RenderValuesFileToBytes(path)
|
||||
yamlBytes, err := st.RenderReleaseValuesFileToBytes(release, path)
|
||||
if err != nil {
|
||||
return generatedFiles, fmt.Errorf("failed to render values files \"%s\": %v", typedValue, err)
|
||||
}
|
||||
|
|
@ -2240,7 +2246,7 @@ func (st *HelmState) generateVanillaValuesFiles(release *ReleaseSpec) ([]string,
|
|||
return nil, fmt.Errorf("Failed to render values in %s for release %s: type %T isn't supported", st.FilePath, release.Name, valuesMapSecretsRendered["values"])
|
||||
}
|
||||
|
||||
generatedFiles, err := st.generateTemporaryValuesFiles(valuesSecretsRendered, release.MissingFileHandler)
|
||||
generatedFiles, err := st.generateTemporaryReleaseValuesFiles(release, valuesSecretsRendered, release.MissingFileHandler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,19 +12,16 @@ func (st *HelmState) Values() (map[string]interface{}, error) {
|
|||
return st.Env.GetMergedValues()
|
||||
}
|
||||
|
||||
func (st *HelmState) mustLoadVals() map[string]interface{} {
|
||||
vals, err := st.Values()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
func (st *HelmState) valuesFileTemplateData() EnvironmentTemplateData {
|
||||
return EnvironmentTemplateData{
|
||||
func (st *HelmState) createReleaseTemplateData(release *ReleaseSpec, vals map[string]interface{}) releaseTemplateData {
|
||||
return releaseTemplateData{
|
||||
Environment: st.Env,
|
||||
Namespace: st.OverrideNamespace,
|
||||
Values: st.mustLoadVals(),
|
||||
Values: vals,
|
||||
Release: releaseTemplateDataRelease{
|
||||
Name: release.Name,
|
||||
Chart: release.Chart,
|
||||
Namespace: release.Namespace,
|
||||
Labels: release.Labels,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,11 +85,7 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
|
|||
for i, rt := range st.Releases {
|
||||
successFlag := false
|
||||
for it, prev := 0, &rt; it < 6; it++ {
|
||||
tmplData := releaseTemplateData{
|
||||
Environment: st.Env,
|
||||
Release: *prev,
|
||||
Values: vals,
|
||||
}
|
||||
tmplData := st.createReleaseTemplateData(prev, vals)
|
||||
renderer := tmpl.NewFileRenderer(st.readFile, st.basePath, tmplData)
|
||||
r, err := rt.ExecuteTemplateExpressions(renderer)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,28 @@ type EnvironmentTemplateData struct {
|
|||
Values map[string]interface{}
|
||||
}
|
||||
|
||||
// releaseTemplateData provides variables accessible while executing golang text/template expressions in releases of a helmfile YAML file
|
||||
// releaseTemplateData provides variables accessible while executing golang text/template expressions in release templates
|
||||
// and release values templates within a Helmfile YAML file.
|
||||
type releaseTemplateData struct {
|
||||
// Environment is accessible as `.Environment` from any template expression executed by the renderer
|
||||
Environment environment.Environment
|
||||
// Release is accessible as `.Release` from any template expression executed by the renderer
|
||||
Release ReleaseSpec
|
||||
// Release is accessible as `.Release` from any template expression executed by the renderer.
|
||||
// It contains a subset of ReleaseSpec that is known to be useful to dynamically render values.
|
||||
Release releaseTemplateDataRelease
|
||||
// Values is accessible as `.Values` and it contains default state values overrode by environment values and override values.
|
||||
Values map[string]interface{}
|
||||
}
|
||||
|
||||
type releaseTemplateDataRelease struct {
|
||||
// Name is basically ReleaseSpec.Name exposed to the template
|
||||
Name string
|
||||
|
||||
// Namespace is HelmState.OverrideNamespace, or if it's empty, ReleaseSpec.Namespace.
|
||||
Namespace string
|
||||
|
||||
// Labels is ReleaseSpec.Labels
|
||||
Labels map[string]string
|
||||
|
||||
// Chart is ReleaseSpec.Chart
|
||||
Chart string
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue