/
gosubst.go
100 lines (82 loc) · 2.11 KB
/
gosubst.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package gosubst
import (
"encoding/json"
"io"
"io/ioutil"
"os"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"github.com/pelletier/go-toml"
"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"
)
// Values holds data present in the values file
type Values map[string]interface{}
// Env exports all enviroments variable
func (v *Values) Env() map[string]string {
env := make(map[string]string)
for _, i := range os.Environ() {
sep := strings.Index(i, "=")
env[i[0:sep]] = i[sep+1:]
}
return env
}
// Subst receives a values file, values type, input and renders the template replacing
// all variables present in the values file sending it to the output
type Subst struct {
values *Values
input io.Reader
output io.Writer
}
// NewSubst substitues values
func NewSubst(valuesFile string, valuesType string, input io.Reader, output io.Writer) (*Subst, error) {
values, err := loadValues(valuesFile, valuesType)
if err != nil {
return nil, err
}
return &Subst{
values: &values,
input: input,
output: output,
}, nil
}
// Render render template with the given values
func (s Subst) Render() error {
text, err := ioutil.ReadAll(s.input)
if err != nil {
return err
}
tmpl, err := template.New("base").Option("missingkey=error").Funcs(sprig.TxtFuncMap()).Parse(string(text))
if err != nil {
return err
}
return tmpl.Execute(s.output, s.values)
}
func loadValues(path string, vType string) (Values, error) {
var values Values
if path == "" {
return values, nil
}
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, errors.Wrap(err, "Reading values file failed")
}
switch strings.ToLower(vType) {
case "json":
if err := json.Unmarshal(file, &values); err != nil {
return nil, errors.Wrapf(err, "Parsing %s as json failed", path)
}
case "yaml", "yml":
if err := yaml.Unmarshal(file, &values); err != nil {
return nil, errors.Wrapf(err, "Parsing %s as yaml failed", path)
}
case "toml":
tree, err := toml.Load(string(file))
if err != nil {
return nil, errors.Wrapf(err, "Parsing %s as toml failed", path)
}
values = tree.ToMap()
}
return values, nil
}