Merge pull request #2 from natevecc/environment-flags
Environment Variable Support
This commit is contained in:
commit
5cbf194ee4
19
README.md
19
README.md
|
|
@ -29,6 +29,9 @@ charts:
|
||||||
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
|
||||||
|
value: DB_PASSWORD # $DB_PASSOWRD needs to be set in the calling environment ex: export DB_PASSWORD='password1'
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -41,24 +44,24 @@ charts:
|
||||||
|
|
||||||
```
|
```
|
||||||
NAME:
|
NAME:
|
||||||
helmfile
|
helmfile -
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
helmfile [global options] command [command options] [arguments...]
|
main [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
0.0.0
|
0.1.0
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
repos sync repositories from state file (helm repo add && help repo update)
|
repos sync repositories from state file (helm repo add && helm repo update)
|
||||||
charts sync charts from state file (helm repo upgrade --install)
|
charts sync charts from state file (helm repo upgrade --install)
|
||||||
sync sync all resources from state file (repos && charts)
|
sync sync all resources from state file (repos && charts)
|
||||||
delete delete charts from state file (helm delete)
|
delete delete charts from state file (helm delete)
|
||||||
help, h Shows a list of commands or help for one command
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
--file FILE, -f FILE load config from FILE (default: "charts.yaml")
|
--file FILE, -f FILE load config from FILE (default: "charts.yaml")
|
||||||
--quiet, -q silence output
|
--quiet, -q silence output
|
||||||
|
--kube-context value Set kubectl context. Uses current context by default
|
||||||
--help, -h show help
|
--help, -h show help
|
||||||
--version, -v print the version
|
--version, -v print the version
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,15 @@ const (
|
||||||
|
|
||||||
type execer struct {
|
type execer struct {
|
||||||
writer io.Writer
|
writer io.Writer
|
||||||
|
kubeContext string
|
||||||
extra []string
|
extra []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHelmExec(writer io.Writer) Interface {
|
func NewHelmExec(writer io.Writer, kubeContext string) Interface {
|
||||||
return &execer{writer: writer}
|
return &execer{
|
||||||
|
writer: writer,
|
||||||
|
kubeContext: kubeContext,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (helm *execer) SetExtraArgs(args ...string) {
|
func (helm *execer) SetExtraArgs(args ...string) {
|
||||||
|
|
@ -69,6 +73,9 @@ func (helm *execer) exec(args ...string) ([]byte, error) {
|
||||||
if len(helm.extra) > 0 {
|
if len(helm.extra) > 0 {
|
||||||
cmdargs = append(cmdargs, helm.extra...)
|
cmdargs = append(cmdargs, helm.extra...)
|
||||||
}
|
}
|
||||||
|
if helm.kubeContext != "" {
|
||||||
|
cmdargs = append(cmdargs, "--kube-context", helm.kubeContext)
|
||||||
|
}
|
||||||
if helm.writer != nil {
|
if helm.writer != nil {
|
||||||
helm.writer.Write([]byte(fmt.Sprintf("exec: helm %s\n", strings.Join(cmdargs, " "))))
|
helm.writer.Write([]byte(fmt.Sprintf("exec: helm %s\n", strings.Join(cmdargs, " "))))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
main.go
26
main.go
|
|
@ -21,6 +21,7 @@ func main() {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Name = "helmfile"
|
app.Name = "helmfile"
|
||||||
app.Usage = ""
|
app.Usage = ""
|
||||||
|
app.Version = "0.1.0"
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "file, f",
|
Name: "file, f",
|
||||||
|
|
@ -31,6 +32,10 @@ func main() {
|
||||||
Name: "quiet, q",
|
Name: "quiet, q",
|
||||||
Usage: "silence output",
|
Usage: "silence output",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "kube-context",
|
||||||
|
Usage: "Set kubectl context. Uses current context by default",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
|
|
@ -73,6 +78,10 @@ func main() {
|
||||||
Value: "",
|
Value: "",
|
||||||
Usage: "pass args to helm exec",
|
Usage: "pass args to helm exec",
|
||||||
},
|
},
|
||||||
|
cli.StringSliceFlag{
|
||||||
|
Name: "values",
|
||||||
|
Usage: "additional value files to be merged into the command",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
state, helm, err := before(c)
|
state, helm, err := before(c)
|
||||||
|
|
@ -85,7 +94,9 @@ func main() {
|
||||||
helm.SetExtraArgs(strings.Split(args, " ")...)
|
helm.SetExtraArgs(strings.Split(args, " ")...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errs := state.SyncCharts(helm); err != nil && len(errs) > 0 {
|
values := c.StringSlice("values")
|
||||||
|
|
||||||
|
if errs := state.SyncCharts(helm, values); err != nil && len(errs) > 0 {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
fmt.Printf("err: %s", err.Error())
|
fmt.Printf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +108,12 @@ func main() {
|
||||||
{
|
{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Usage: "sync all resources from state file (repos && charts)",
|
Usage: "sync all resources from state file (repos && charts)",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringSliceFlag{
|
||||||
|
Name: "values",
|
||||||
|
Usage: "additional value files to be merged into the command",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
state, helm, err := before(c)
|
state, helm, err := before(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -110,7 +127,9 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if errs := state.SyncCharts(helm); err != nil && len(errs) > 0 {
|
values := c.StringSlice("values")
|
||||||
|
|
||||||
|
if errs := state.SyncCharts(helm, values); err != nil && len(errs) > 0 {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
fmt.Printf("err: %s", err.Error())
|
fmt.Printf("err: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -149,6 +168,7 @@ func main() {
|
||||||
func before(c *cli.Context) (*state.HelmState, helmexec.Interface, error) {
|
func before(c *cli.Context) (*state.HelmState, helmexec.Interface, error) {
|
||||||
file := c.GlobalString("file")
|
file := c.GlobalString("file")
|
||||||
quiet := c.GlobalBool("quiet")
|
quiet := c.GlobalBool("quiet")
|
||||||
|
kubeContext := c.GlobalString("kube-context")
|
||||||
|
|
||||||
state, err := state.ReadFromFile(file)
|
state, err := state.ReadFromFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -160,5 +180,5 @@ func before(c *cli.Context) (*state.HelmState, helmexec.Interface, error) {
|
||||||
writer = os.Stdout
|
writer = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
return state, helmexec.NewHelmExec(writer), nil
|
return state, helmexec.NewHelmExec(writer, kubeContext), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/roboll/helmfile/helmexec"
|
"github.com/roboll/helmfile/helmexec"
|
||||||
|
|
||||||
|
|
@ -32,6 +33,7 @@ type ChartSpec struct {
|
||||||
Namespace string `yaml:"namespace"`
|
Namespace string `yaml:"namespace"`
|
||||||
Values []string `yaml:"values"`
|
Values []string `yaml:"values"`
|
||||||
SetValues []SetValue `yaml:"set"`
|
SetValues []SetValue `yaml:"set"`
|
||||||
|
EnvValues []SetValue `yaml:"env"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SetValue struct {
|
type SetValue struct {
|
||||||
|
|
@ -77,7 +79,7 @@ func (state *HelmState) SyncRepos(helm helmexec.Interface) []error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *HelmState) SyncCharts(helm helmexec.Interface) []error {
|
func (state *HelmState) SyncCharts(helm helmexec.Interface, additonalValues []string) []error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
errs := []error{}
|
errs := []error{}
|
||||||
|
|
||||||
|
|
@ -85,6 +87,14 @@ func (state *HelmState) SyncCharts(helm helmexec.Interface) []error {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(wg *sync.WaitGroup, chart ChartSpec) {
|
go func(wg *sync.WaitGroup, chart ChartSpec) {
|
||||||
flags, err := flagsForChart(&chart)
|
flags, err := flagsForChart(&chart)
|
||||||
|
for _, value := range additonalValues {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
valfile := filepath.Join(wd, value)
|
||||||
|
flags = append(flags, "--values", valfile)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -152,5 +162,17 @@ func flagsForChart(chart *ChartSpec) ([]string, error) {
|
||||||
}
|
}
|
||||||
flags = append(flags, "--set", strings.Join(val, ","))
|
flags = append(flags, "--set", strings.Join(val, ","))
|
||||||
}
|
}
|
||||||
|
if len(chart.EnvValues) > 0 {
|
||||||
|
val := []string{}
|
||||||
|
for _, set := range chart.EnvValues {
|
||||||
|
value, isSet := os.LookupEnv(set.Value)
|
||||||
|
if isSet {
|
||||||
|
val = append(val, fmt.Sprintf("%s=%s", set.Name, value))
|
||||||
|
} else {
|
||||||
|
return nil, errors.New(fmt.Sprintf("Could not find environment var: %s. Please make sure it is set and try again.", set.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flags = append(flags, "--set", strings.Join(val, ","))
|
||||||
|
}
|
||||||
return flags, nil
|
return flags, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue