Fix: Restrict template processing to .gotmpl files only
Co-authored-by: zhaque44 <20215376+zhaque44@users.noreply.github.com>
This commit is contained in:
parent
a7b23ac81c
commit
1bbe2c667f
|
|
@ -3,6 +3,7 @@ package state
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
|
|
@ -110,27 +111,33 @@ func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
|
|||
release.KubeVersion = st.KubeVersion
|
||||
}
|
||||
|
||||
successFlag := false
|
||||
for it, prev := 0, release; it < 6; it++ {
|
||||
tmplData := st.createReleaseTemplateData(prev, vals)
|
||||
renderer := tmpl.NewFileRenderer(st.fs, st.basePath, tmplData)
|
||||
r, err := release.ExecuteTemplateExpressions(renderer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
|
||||
}
|
||||
if reflect.DeepEqual(prev, r) {
|
||||
successFlag = true
|
||||
if err := updateBoolTemplatedValues(r); err != nil {
|
||||
// Only process templates if the file has .gotmpl extension
|
||||
if filepath.Ext(st.FilePath) == ".gotmpl" {
|
||||
successFlag := false
|
||||
for it, prev := 0, release; it < 6; it++ {
|
||||
tmplData := st.createReleaseTemplateData(prev, vals)
|
||||
renderer := tmpl.NewFileRenderer(st.fs, st.basePath, tmplData)
|
||||
r, err := release.ExecuteTemplateExpressions(renderer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
|
||||
}
|
||||
st.Releases[i] = *r
|
||||
break
|
||||
if reflect.DeepEqual(prev, r) {
|
||||
successFlag = true
|
||||
if err := updateBoolTemplatedValues(r); err != nil {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, release.Name, err)
|
||||
}
|
||||
st.Releases[i] = *r
|
||||
break
|
||||
}
|
||||
prev = r
|
||||
}
|
||||
prev = r
|
||||
}
|
||||
if !successFlag {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %s", st.FilePath, release.Name,
|
||||
"recursive references can't be resolved")
|
||||
if !successFlag {
|
||||
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %s", st.FilePath, release.Name,
|
||||
"recursive references can't be resolved")
|
||||
}
|
||||
} else {
|
||||
// For non-.gotmpl files, skip template processing entirely
|
||||
st.Releases[i] = *release
|
||||
}
|
||||
|
||||
if st.Releases[i].Chart == "" {
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ func TestHelmState_executeTemplates(t *testing.T) {
|
|||
fs: &filesystem.FileSystem{
|
||||
Glob: func(s string) ([]string, error) { return nil, nil }},
|
||||
basePath: ".",
|
||||
FilePath: "helmfile.yaml.gotmpl", // Set to .gotmpl to enable template processing
|
||||
ReleaseSetSpec: ReleaseSetSpec{
|
||||
HelmDefaults: HelmSpec{
|
||||
KubeContext: "test_context",
|
||||
|
|
@ -269,6 +270,7 @@ func TestHelmState_recursiveRefsTemplates(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
state := &HelmState{
|
||||
basePath: ".",
|
||||
FilePath: "helmfile.yaml.gotmpl", // Set to .gotmpl to enable template processing for error tests
|
||||
fs: &filesystem.FileSystem{
|
||||
Glob: func(s string) ([]string, error) { return nil, nil },
|
||||
},
|
||||
|
|
@ -294,3 +296,97 @@ func TestHelmState_recursiveRefsTemplates(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelmState_executeTemplates_yaml_vs_gotmpl(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
filePath string
|
||||
input ReleaseSpec
|
||||
want ReleaseSpec
|
||||
}{
|
||||
{
|
||||
name: "YAML file should NOT process templates",
|
||||
filePath: "helmfile.yaml",
|
||||
input: ReleaseSpec{
|
||||
Chart: "test-charts/{{ .Release.Name }}",
|
||||
Version: "{{ .Release.Name }}-0.1",
|
||||
Name: "test-app",
|
||||
Namespace: "test-namespace-{{ .Release.Name }}",
|
||||
Labels: map[string]string{"id": "{{ .Release.Name }}"},
|
||||
},
|
||||
want: ReleaseSpec{
|
||||
Chart: "test-charts/{{ .Release.Name }}", // Template NOT processed
|
||||
Version: "{{ .Release.Name }}-0.1", // Template NOT processed
|
||||
Name: "test-app",
|
||||
Namespace: "test-namespace-{{ .Release.Name }}", // Template NOT processed
|
||||
Labels: map[string]string{"id": "{{ .Release.Name }}"}, // Template NOT processed
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "GOTMPL file should process templates",
|
||||
filePath: "helmfile.yaml.gotmpl",
|
||||
input: ReleaseSpec{
|
||||
Chart: "test-charts/{{ .Release.Name }}",
|
||||
Version: "{{ .Release.Name }}-0.1",
|
||||
Name: "test-app",
|
||||
Namespace: "test-namespace-{{ .Release.Name }}",
|
||||
Labels: map[string]string{"id": "{{ .Release.Name }}"},
|
||||
},
|
||||
want: ReleaseSpec{
|
||||
Chart: "test-charts/test-app", // Template processed
|
||||
Version: "test-app-0.1", // Template processed
|
||||
Name: "test-app",
|
||||
Namespace: "test-namespace-test-app", // Template processed
|
||||
Labels: map[string]string{"id": "test-app"}, // Template processed
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i := range tests {
|
||||
tt := tests[i]
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
state := &HelmState{
|
||||
fs: &filesystem.FileSystem{
|
||||
Glob: func(s string) ([]string, error) { return nil, nil }},
|
||||
basePath: ".",
|
||||
FilePath: tt.filePath, // This is the key difference
|
||||
ReleaseSetSpec: ReleaseSetSpec{
|
||||
HelmDefaults: HelmSpec{
|
||||
KubeContext: "test_context",
|
||||
},
|
||||
Env: environment.Environment{Name: "test_env"},
|
||||
OverrideNamespace: "test-namespace_",
|
||||
Repositories: nil,
|
||||
Releases: []ReleaseSpec{
|
||||
tt.input,
|
||||
},
|
||||
},
|
||||
RenderedValues: map[string]any{},
|
||||
}
|
||||
|
||||
r, err := state.ExecuteTemplates()
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
actual := r.Releases[0]
|
||||
|
||||
if !reflect.DeepEqual(actual.Name, tt.want.Name) {
|
||||
t.Errorf("expected Name %+v, got %+v", tt.want.Name, actual.Name)
|
||||
}
|
||||
if !reflect.DeepEqual(actual.Chart, tt.want.Chart) {
|
||||
t.Errorf("expected Chart %+v, got %+v", tt.want.Chart, actual.Chart)
|
||||
}
|
||||
if !reflect.DeepEqual(actual.Namespace, tt.want.Namespace) {
|
||||
t.Errorf("expected Namespace %+v, got %+v", tt.want.Namespace, actual.Namespace)
|
||||
}
|
||||
if !reflect.DeepEqual(actual.Version, tt.want.Version) {
|
||||
t.Errorf("expected Version %+v, got %+v", tt.want.Version, actual.Version)
|
||||
}
|
||||
if diff := deep.Equal(actual.Labels, tt.want.Labels); diff != nil && len(actual.Labels) > 0 {
|
||||
t.Errorf("Labels differs \n%+v", strings.Join(diff, "\n"))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue