luet/pkg/helpers/helm.go
Ettore Di Giacinto 57c769b4a5 Refactor compiler and annotate buildoptions into compiler metadata
This allows to later pick up values used during build of each package
2021-04-16 13:57:54 +02:00

98 lines
2.5 KiB
Go

package helpers
import (
"io/ioutil"
"github.com/imdario/mergo"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/engine"
)
// RenderHelm renders the template string with helm
func RenderHelm(template string, values, d map[string]interface{}) (string, error) {
c := &chart.Chart{
Metadata: &chart.Metadata{
Name: "",
Version: "",
},
Templates: []*chart.File{
{Name: "templates", Data: []byte(template)},
},
Values: map[string]interface{}{"Values": values},
}
v, err := chartutil.CoalesceValues(c, map[string]interface{}{"Values": d})
if err != nil {
return "", errors.Wrap(err, "while rendering template")
}
out, err := engine.Render(c, v)
if err != nil {
return "", errors.Wrap(err, "while rendering template")
}
return out["templates"], nil
}
type templatedata map[string]interface{}
// UnMarshalValues unmarshal values files and joins them into a unique templatedata
// the join happens from right to left, so any rightmost value file overwrites the content of the ones before it.
func UnMarshalValues(values []string) (templatedata, error) {
dst := templatedata{}
if len(values) > 0 {
for _, bv := range reverse(values) {
current := templatedata{}
defBuild, err := ioutil.ReadFile(bv)
if err != nil {
return nil, errors.Wrap(err, "rendering file "+bv)
}
err = yaml.Unmarshal(defBuild, &current)
if err != nil {
return nil, errors.Wrap(err, "rendering file "+bv)
}
if err := mergo.Merge(&dst, current); err != nil {
return nil, errors.Wrap(err, "merging values file "+bv)
}
}
}
return dst, nil
}
func reverse(s []string) []string {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}
func RenderFiles(toTemplate, valuesFile string, defaultFile ...string) (string, error) {
raw, err := ioutil.ReadFile(toTemplate)
if err != nil {
return "", errors.Wrap(err, "reading file "+toTemplate)
}
if !Exists(valuesFile) {
return "", errors.Wrap(err, "file not existing "+valuesFile)
}
val, err := ioutil.ReadFile(valuesFile)
if err != nil {
return "", errors.Wrap(err, "reading file "+valuesFile)
}
var values templatedata
if err = yaml.Unmarshal(val, &values); err != nil {
return "", errors.Wrap(err, "unmarshalling file "+toTemplate)
}
dst, err := UnMarshalValues(defaultFile)
if err != nil {
return "", errors.Wrap(err, "unmarshalling values")
}
return RenderHelm(string(raw), values, dst)
}