135 lines
3.2 KiB
Go
135 lines
3.2 KiB
Go
package state
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"github.com/imdario/mergo"
|
|
"github.com/roboll/helmfile/pkg/maputil"
|
|
"github.com/roboll/helmfile/pkg/tmpl"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
func (st *HelmState) Values() (map[string]interface{}, error) {
|
|
vals := map[string]interface{}{}
|
|
|
|
if err := mergo.Merge(&vals, st.Env.Defaults, mergo.WithOverride); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := mergo.Merge(&vals, st.Env.Values, mergo.WithOverride); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
vals, err := maputil.CastKeysToStrings(vals)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return vals, nil
|
|
}
|
|
|
|
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{
|
|
Environment: st.Env,
|
|
Namespace: st.Namespace,
|
|
Values: st.mustLoadVals(),
|
|
}
|
|
}
|
|
|
|
func getBoolRefFromStringTemplate(templateRef string) (*bool, error) {
|
|
var result bool
|
|
if err := yaml.Unmarshal([]byte(templateRef), &result); err != nil {
|
|
return nil, fmt.Errorf("failed deserialising string %s: %v", templateRef, err)
|
|
}
|
|
return &result, nil
|
|
}
|
|
|
|
func updateBoolTemplatedValues(r *ReleaseSpec) error {
|
|
|
|
if r.InstalledTemplate != nil {
|
|
if installed, err := getBoolRefFromStringTemplate(*r.InstalledTemplate); err != nil {
|
|
return fmt.Errorf("installedTemplate: %v", err)
|
|
} else {
|
|
r.InstalledTemplate = nil
|
|
r.Installed = installed
|
|
}
|
|
}
|
|
|
|
if r.WaitTemplate != nil {
|
|
if wait, err := getBoolRefFromStringTemplate(*r.WaitTemplate); err != nil {
|
|
return fmt.Errorf("waitTemplate: %v", err)
|
|
} else {
|
|
r.WaitTemplate = nil
|
|
r.Wait = wait
|
|
}
|
|
}
|
|
|
|
if r.TillerlessTemplate != nil {
|
|
if tillerless, err := getBoolRefFromStringTemplate(*r.TillerlessTemplate); err != nil {
|
|
return fmt.Errorf("tillerlessTemplate: %v", err)
|
|
} else {
|
|
r.TillerlessTemplate = nil
|
|
r.Tillerless = tillerless
|
|
}
|
|
}
|
|
|
|
if r.VerifyTemplate != nil {
|
|
if verify, err := getBoolRefFromStringTemplate(*r.VerifyTemplate); err != nil {
|
|
return fmt.Errorf("verifyTemplate: %v", err)
|
|
} else {
|
|
r.VerifyTemplate = nil
|
|
r.Verify = verify
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (st *HelmState) ExecuteTemplates() (*HelmState, error) {
|
|
r := *st
|
|
|
|
vals, err := st.Values()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
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,
|
|
}
|
|
renderer := tmpl.NewFileRenderer(st.readFile, st.basePath, tmplData)
|
|
r, err := rt.ExecuteTemplateExpressions(renderer)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %v", st.FilePath, rt.Name, err)
|
|
}
|
|
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, rt.Name, err)
|
|
}
|
|
st.Releases[i] = *r
|
|
break
|
|
}
|
|
prev = r
|
|
}
|
|
if !successFlag {
|
|
return nil, fmt.Errorf("failed executing templates in release \"%s\".\"%s\": %s", st.FilePath, rt.Name,
|
|
"recursive references can't be resolved")
|
|
}
|
|
}
|
|
|
|
return &r, nil
|
|
}
|