Allow env var interpolation in `set` and `values` (#20)
* Allow env var interpolation in `set` and `values` * Use go templating instead of regex * Re-add 'env' section for backwards compatibility * Fix typo
This commit is contained in:
parent
12b8b7237b
commit
5da5cd1c39
24
README.md
24
README.md
|
|
@ -23,23 +23,25 @@ repositories:
|
||||||
|
|
||||||
charts:
|
charts:
|
||||||
# Published chart example
|
# Published chart example
|
||||||
- name: vault # helm deployment name
|
- name: vault # helm deployment name
|
||||||
namespace: vault # target namespace
|
namespace: vault # target namespace
|
||||||
chart: roboll/vault-secret-manager # chart reference (repository)
|
chart: roboll/vault-secret-manager # chart reference (repository)
|
||||||
values: [ vault.yaml ] # value files (--values)
|
values: [ vault.yaml ] # value files (--values)
|
||||||
set: # values (--set)
|
set: # values (--set)
|
||||||
- name: address
|
- name: address
|
||||||
value: https://vault.example.com
|
value: https://vault.example.com
|
||||||
env: # values (--set) but value will be pulled from environment variables. Will throw an error if the environment variable is not set.
|
|
||||||
- name: db.password
|
- name: db.password
|
||||||
value: DB_PASSWORD # $DB_PASSOWRD needs to be set in the calling environment ex: export DB_PASSWORD='password1'
|
value: {{ env "DB_PASSWORD" }} # value taken from environment variable. Will throw an error if the environment variable is not set. $DB_PASSWORD needs to be set in the calling environment ex: export DB_PASSWORD='password1'
|
||||||
|
- name: proxy.domain
|
||||||
|
value: "{{ env \"PLATFORM_ID\" }}.my-domain.com" # Interpolate environment variable with a fixed string
|
||||||
|
|
||||||
# Local chart example
|
# Local chart example
|
||||||
- name: grafana # helm deployment name
|
- name: grafana # helm deployment name
|
||||||
namespace: another # target namespace
|
namespace: another # target namespace
|
||||||
chart: ../my-charts/grafana # chart reference (relative path to manifest)
|
chart: ../my-charts/grafana # chart reference (relative path to manifest)
|
||||||
values:
|
values:
|
||||||
- ../../my-values/grafana/values.yaml # Values file (relative path to manifest)
|
- "../../my-values/grafana/values.yaml" # Values file (relative path to manifest)
|
||||||
|
- "./values/{{ env \"PLATFORM_ENV\" }}/config.yaml" # Values file taken from path with environment variable. $PLATFORM_ENV must be set in the calling environment.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,14 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/roboll/helmfile/helmexec"
|
"github.com/roboll/helmfile/helmexec"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v1"
|
yaml "gopkg.in/yaml.v1"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"bytes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HelmState struct {
|
type HelmState struct {
|
||||||
|
|
@ -28,14 +30,16 @@ type RepositorySpec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChartSpec struct {
|
type ChartSpec struct {
|
||||||
Chart string `yaml:"chart"`
|
Chart string `yaml:"chart"`
|
||||||
Version string `yaml:"version"`
|
Version string `yaml:"version"`
|
||||||
Verify bool `yaml:"verify"`
|
Verify bool `yaml:"verify"`
|
||||||
|
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Namespace string `yaml:"namespace"`
|
Namespace string `yaml:"namespace"`
|
||||||
Values []string `yaml:"values"`
|
Values []string `yaml:"values"`
|
||||||
SetValues []SetValue `yaml:"set"`
|
SetValues []SetValue `yaml:"set"`
|
||||||
|
|
||||||
|
// The 'env' section is not really necessary any longer, as 'set' would now provide the same functionality
|
||||||
EnvValues []SetValue `yaml:"env"`
|
EnvValues []SetValue `yaml:"env"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,6 +63,41 @@ func ReadFromFile(file string) (*HelmState, error) {
|
||||||
return &state, nil
|
return &state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var /* const */
|
||||||
|
stringTemplateFuncMap = template.FuncMap{
|
||||||
|
"env": getEnvVar,
|
||||||
|
}
|
||||||
|
|
||||||
|
var /* const */
|
||||||
|
stringTemplate = template.New("stringTemplate").Funcs(stringTemplateFuncMap)
|
||||||
|
|
||||||
|
func getEnvVar(envVarName string) (string, error) {
|
||||||
|
envVarValue, isSet := os.LookupEnv(envVarName)
|
||||||
|
|
||||||
|
if !isSet {
|
||||||
|
errMsg := fmt.Sprintf("Environment Variable '%s' is not set. Please make sure it is set and try again.", envVarName)
|
||||||
|
return "", errors.New(errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return envVarValue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderTemplateString(s string) (string, error) {
|
||||||
|
var t, parseErr = stringTemplate.Parse(s)
|
||||||
|
if parseErr != nil {
|
||||||
|
return "", parseErr
|
||||||
|
}
|
||||||
|
|
||||||
|
var tplString bytes.Buffer
|
||||||
|
var execErr = t.Execute(&tplString, nil)
|
||||||
|
|
||||||
|
if execErr != nil {
|
||||||
|
return "", execErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return tplString.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (state *HelmState) SyncRepos(helm helmexec.Interface) []error {
|
func (state *HelmState) SyncRepos(helm helmexec.Interface) []error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
errs := []error{}
|
errs := []error{}
|
||||||
|
|
@ -203,15 +242,28 @@ func flagsForChart(basePath string, chart *ChartSpec) ([]string, error) {
|
||||||
}
|
}
|
||||||
for _, value := range chart.Values {
|
for _, value := range chart.Values {
|
||||||
valfile := filepath.Join(basePath, value)
|
valfile := filepath.Join(basePath, value)
|
||||||
flags = append(flags, "--values", valfile)
|
valfileRendered, err := renderTemplateString(valfile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
flags = append(flags, "--values", valfileRendered)
|
||||||
}
|
}
|
||||||
if len(chart.SetValues) > 0 {
|
if len(chart.SetValues) > 0 {
|
||||||
val := []string{}
|
val := []string{}
|
||||||
for _, set := range chart.SetValues {
|
for _, set := range chart.SetValues {
|
||||||
val = append(val, fmt.Sprintf("%s=%s", set.Name, set.Value))
|
renderedValue, err := renderTemplateString(set.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
val = append(val, fmt.Sprintf("%s=%s", set.Name, renderedValue))
|
||||||
}
|
}
|
||||||
flags = append(flags, "--set", strings.Join(val, ","))
|
flags = append(flags, "--set", strings.Join(val, ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********
|
||||||
|
* START 'env' section for backwards compatibility
|
||||||
|
***********/
|
||||||
|
// The 'env' section is not really necessary any longer, as 'set' would now provide the same functionality
|
||||||
if len(chart.EnvValues) > 0 {
|
if len(chart.EnvValues) > 0 {
|
||||||
val := []string{}
|
val := []string{}
|
||||||
envValErrs := []string{}
|
envValErrs := []string{}
|
||||||
|
|
@ -231,5 +283,9 @@ func flagsForChart(basePath string, chart *ChartSpec) ([]string, error) {
|
||||||
}
|
}
|
||||||
flags = append(flags, "--set", strings.Join(val, ","))
|
flags = append(flags, "--set", strings.Join(val, ","))
|
||||||
}
|
}
|
||||||
|
/**************
|
||||||
|
* END 'env' section for backwards compatibility
|
||||||
|
**************/
|
||||||
|
|
||||||
return flags, nil
|
return flags, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue