feat(diff,apply,lint,sync,template): `--set k=v` for setting adhoc chart values (#850)
Resolves #840
This commit is contained in:
parent
94a6fcfb9f
commit
f79db2ec8d
32
main.go
32
main.go
|
|
@ -143,6 +143,10 @@ func main() {
|
|||
Value: "",
|
||||
Usage: "pass args to helm exec",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -166,6 +170,10 @@ func main() {
|
|||
Value: "",
|
||||
Usage: "pass args to helm exec",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -206,6 +214,10 @@ func main() {
|
|||
Value: "",
|
||||
Usage: "pass args to helm template",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -237,6 +249,10 @@ func main() {
|
|||
Value: "",
|
||||
Usage: "pass args to helm exec",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -259,6 +275,10 @@ func main() {
|
|||
Name: "sync",
|
||||
Usage: "sync all resources from state file (repos, releases and chart deps)",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -286,6 +306,10 @@ func main() {
|
|||
Name: "apply",
|
||||
Usage: "apply all resources from state file only when there are changes",
|
||||
Flags: []cli.Flag{
|
||||
cli.StringSliceFlag{
|
||||
Name: "set",
|
||||
Usage: "additional values to be merged into the command",
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "values",
|
||||
Usage: "additional value files to be merged into the command",
|
||||
|
|
@ -467,6 +491,10 @@ func NewUrfaveCliConfigImpl(c *cli.Context) (configImpl, error) {
|
|||
return conf, nil
|
||||
}
|
||||
|
||||
func (c configImpl) Set() []string {
|
||||
return c.c.StringSlice("set")
|
||||
}
|
||||
|
||||
func (c configImpl) Values() []string {
|
||||
return c.c.StringSlice("values")
|
||||
}
|
||||
|
|
@ -539,11 +567,11 @@ func (c configImpl) Selectors() []string {
|
|||
return c.c.GlobalStringSlice("selector")
|
||||
}
|
||||
|
||||
func (c configImpl) Set() map[string]interface{} {
|
||||
func (c configImpl) StateValuesSet() map[string]interface{} {
|
||||
return c.set
|
||||
}
|
||||
|
||||
func (c configImpl) ValuesFiles() []string {
|
||||
func (c configImpl) StateValuesFiles() []string {
|
||||
return c.c.GlobalStringSlice("state-values-file")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ func New(conf ConfigProvider) *App {
|
|||
HelmBinary: conf.HelmBinary(),
|
||||
Args: conf.Args(),
|
||||
FileOrDir: conf.FileOrDir(),
|
||||
ValuesFiles: conf.ValuesFiles(),
|
||||
Set: conf.Set(),
|
||||
ValuesFiles: conf.StateValuesFiles(),
|
||||
Set: conf.StateValuesSet(),
|
||||
helmExecer: helmexec.New(conf.Logger(), conf.KubeContext(), &helmexec.ShellRunner{
|
||||
Logger: conf.Logger(),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1791,6 +1791,11 @@ services:
|
|||
}
|
||||
|
||||
type configImpl struct {
|
||||
set []string
|
||||
}
|
||||
|
||||
func (c configImpl) Set() []string {
|
||||
return c.set
|
||||
}
|
||||
|
||||
func (c configImpl) Values() []string {
|
||||
|
|
@ -1913,8 +1918,8 @@ releases:
|
|||
|
||||
var helm = &mockHelmExec{}
|
||||
var wantReleases = []mockTemplates{
|
||||
{name: "myrelease1", chart: "mychart1", flags: []string{"--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}},
|
||||
{name: "myrelease2", chart: "mychart2", flags: []string{"--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease2"}},
|
||||
{name: "myrelease1", chart: "mychart1", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}},
|
||||
{name: "myrelease2", chart: "mychart2", flags: []string{"--namespace", "testNamespace", "--set", "foo=a", "--set", "bar=b", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease2"}},
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
|
|
@ -1929,7 +1934,7 @@ releases:
|
|||
helmExecer: helm,
|
||||
Namespace: "testNamespace",
|
||||
}, files)
|
||||
app.Template(configImpl{})
|
||||
app.Template(configImpl{set: []string{"foo=a", "bar=b"}})
|
||||
|
||||
for i := range wantReleases {
|
||||
if wantReleases[i].name != helm.templated[i].name {
|
||||
|
|
@ -1939,7 +1944,7 @@ releases:
|
|||
t.Errorf("chart = [%v], want %v", helm.templated[i].chart, wantReleases[i].chart)
|
||||
}
|
||||
for j := range wantReleases[i].flags {
|
||||
if j == 3 {
|
||||
if j == 7 {
|
||||
matched, _ := regexp.Match(wantReleases[i].flags[j], []byte(helm.templated[i].flags[j]))
|
||||
if !matched {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ type ConfigProvider interface {
|
|||
KubeContext() string
|
||||
Namespace() string
|
||||
Selectors() []string
|
||||
Set() map[string]interface{}
|
||||
ValuesFiles() []string
|
||||
StateValuesSet() map[string]interface{}
|
||||
StateValuesFiles() []string
|
||||
Env() string
|
||||
|
||||
loggingConfig
|
||||
|
|
@ -36,6 +36,7 @@ type ApplyConfigProvider interface {
|
|||
Args() string
|
||||
|
||||
Values() []string
|
||||
Set() []string
|
||||
SkipDeps() bool
|
||||
|
||||
SuppressSecrets() bool
|
||||
|
|
@ -52,6 +53,7 @@ type SyncConfigProvider interface {
|
|||
Args() string
|
||||
|
||||
Values() []string
|
||||
Set() []string
|
||||
SkipDeps() bool
|
||||
|
||||
concurrencyConfig
|
||||
|
|
@ -62,6 +64,7 @@ type DiffConfigProvider interface {
|
|||
Args() string
|
||||
|
||||
Values() []string
|
||||
Set() []string
|
||||
SkipDeps() bool
|
||||
|
||||
SuppressSecrets() bool
|
||||
|
|
@ -104,6 +107,7 @@ type LintConfigProvider interface {
|
|||
Args() string
|
||||
|
||||
Values() []string
|
||||
Set() []string
|
||||
SkipDeps() bool
|
||||
|
||||
concurrencyConfig
|
||||
|
|
@ -113,6 +117,7 @@ type TemplateConfigProvider interface {
|
|||
Args() string
|
||||
|
||||
Values() []string
|
||||
Set() []string
|
||||
SkipDeps() bool
|
||||
OutputDir() string
|
||||
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ func (r *Run) Apply(c ApplyConfigProvider) []error {
|
|||
diffOpts := &state.DiffOpts{
|
||||
NoColor: c.NoColor(),
|
||||
Context: c.Context(),
|
||||
Set: c.Set(),
|
||||
}
|
||||
|
||||
releases, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.SuppressSecrets(), false, diffOpts)
|
||||
|
|
@ -201,7 +202,10 @@ Do you really want to apply?
|
|||
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
||||
|
||||
st.Releases = rs
|
||||
return st.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency())
|
||||
syncOpts := &state.SyncOpts{
|
||||
Set: c.Set(),
|
||||
}
|
||||
return st.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -229,7 +233,12 @@ func (r *Run) Diff(c DiffConfigProvider) []error {
|
|||
|
||||
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
||||
|
||||
_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), true)
|
||||
opts := &state.DiffOpts{
|
||||
Context: c.Context(),
|
||||
NoColor: c.NoColor(),
|
||||
Set: c.Set(),
|
||||
}
|
||||
_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), true, opts)
|
||||
return errs
|
||||
}
|
||||
|
||||
|
|
@ -253,30 +262,36 @@ func (r *Run) Sync(c SyncConfigProvider) []error {
|
|||
|
||||
r.helm.SetExtraArgs(argparser.GetArgs(c.Args(), r.state)...)
|
||||
|
||||
errs := st.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency())
|
||||
opts := &state.SyncOpts{
|
||||
Set: c.Set(),
|
||||
}
|
||||
errs := st.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), opts)
|
||||
affectedReleases.DisplayAffectedReleases(c.Logger())
|
||||
return errs
|
||||
}
|
||||
|
||||
func (r *Run) Template(c TemplateConfigProvider) []error {
|
||||
state := r.state
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
ctx := r.ctx
|
||||
|
||||
if !c.SkipDeps() {
|
||||
if errs := ctx.SyncReposOnce(state, helm); errs != nil && len(errs) > 0 {
|
||||
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
if errs := state.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
}
|
||||
if errs := state.PrepareReleases(helm, "template"); errs != nil && len(errs) > 0 {
|
||||
if errs := st.PrepareReleases(helm, "template"); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
args := argparser.GetArgs(c.Args(), state)
|
||||
return state.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency())
|
||||
args := argparser.GetArgs(c.Args(), st)
|
||||
opts := &state.TemplateOpts{
|
||||
Set: c.Set(),
|
||||
}
|
||||
return st.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), opts)
|
||||
}
|
||||
|
||||
func (r *Run) Test(c TestConfigProvider) []error {
|
||||
|
|
@ -290,23 +305,26 @@ func (r *Run) Test(c TestConfigProvider) []error {
|
|||
}
|
||||
|
||||
func (r *Run) Lint(c LintConfigProvider) []error {
|
||||
state := r.state
|
||||
st := r.state
|
||||
helm := r.helm
|
||||
ctx := r.ctx
|
||||
|
||||
values := c.Values()
|
||||
args := argparser.GetArgs(c.Args(), state)
|
||||
args := argparser.GetArgs(c.Args(), st)
|
||||
workers := c.Concurrency()
|
||||
if !c.SkipDeps() {
|
||||
if errs := ctx.SyncReposOnce(state, helm); errs != nil && len(errs) > 0 {
|
||||
if errs := ctx.SyncReposOnce(st, helm); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
if errs := state.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||
if errs := st.BuildDeps(helm); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
}
|
||||
if errs := state.PrepareReleases(helm, "lint"); errs != nil && len(errs) > 0 {
|
||||
if errs := st.PrepareReleases(helm, "lint"); errs != nil && len(errs) > 0 {
|
||||
return errs
|
||||
}
|
||||
return state.LintReleases(helm, values, args, workers)
|
||||
opts := &state.LintOpts{
|
||||
Set: c.Set(),
|
||||
}
|
||||
return st.LintReleases(helm, values, args, workers, opts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -253,7 +253,12 @@ type syncPrepareResult struct {
|
|||
}
|
||||
|
||||
// SyncReleases wrapper for executing helm upgrade on the releases
|
||||
func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValues []string, concurrency int) ([]syncPrepareResult, []error) {
|
||||
func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValues []string, concurrency int, opt ...SyncOpt) ([]syncPrepareResult, []error) {
|
||||
opts := &SyncOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
}
|
||||
|
||||
releases := []*ReleaseSpec{}
|
||||
for i, _ := range st.Releases {
|
||||
releases = append(releases, &st.Releases[i])
|
||||
|
|
@ -318,6 +323,12 @@ func (st *HelmState) prepareSyncReleases(helm helmexec.Interface, additionalValu
|
|||
flags = append(flags, "--values", valfile)
|
||||
}
|
||||
|
||||
if opts.Set != nil {
|
||||
for _, s := range opts.Set {
|
||||
flags = append(flags, "--set", s)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
results <- syncPrepareResult{errors: errs}
|
||||
continue
|
||||
|
|
@ -372,9 +383,24 @@ func (st *HelmState) DetectReleasesToBeDeleted(helm helmexec.Interface) ([]*Rele
|
|||
return detected, nil
|
||||
}
|
||||
|
||||
type SyncOpts struct {
|
||||
Set []string
|
||||
}
|
||||
|
||||
type SyncOpt interface{ Apply(*SyncOpts) }
|
||||
|
||||
func (o *SyncOpts) Apply(opts *SyncOpts) {
|
||||
*opts = *o
|
||||
}
|
||||
|
||||
// SyncReleases wrapper for executing helm upgrade on the releases
|
||||
func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helmexec.Interface, additionalValues []string, workerLimit int) []error {
|
||||
preps, prepErrs := st.prepareSyncReleases(helm, additionalValues, workerLimit)
|
||||
func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helmexec.Interface, additionalValues []string, workerLimit int, opt ...SyncOpt) []error {
|
||||
opts := &SyncOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
}
|
||||
|
||||
preps, prepErrs := st.prepareSyncReleases(helm, additionalValues, workerLimit, opts)
|
||||
if len(prepErrs) > 0 {
|
||||
return prepErrs
|
||||
}
|
||||
|
|
@ -550,8 +576,23 @@ func (st *HelmState) downloadCharts(helm helmexec.Interface, dir string, concurr
|
|||
return temp, nil
|
||||
}
|
||||
|
||||
type TemplateOpts struct {
|
||||
Set []string
|
||||
}
|
||||
|
||||
type TemplateOpt interface{ Apply(*TemplateOpts) }
|
||||
|
||||
func (o *TemplateOpts) Apply(opts *TemplateOpts) {
|
||||
*opts = *o
|
||||
}
|
||||
|
||||
// TemplateReleases wrapper for executing helm template on the releases
|
||||
func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, additionalValues []string, args []string, workerLimit int) []error {
|
||||
func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, additionalValues []string, args []string, workerLimit int, opt ...TemplateOpt) []error {
|
||||
opts := &TemplateOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
}
|
||||
|
||||
// Reset the extra args if already set, not to break `helm fetch` by adding the args intended for `lint`
|
||||
helm.SetExtraArgs()
|
||||
|
||||
|
|
@ -601,6 +642,12 @@ func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string,
|
|||
flags = append(flags, "--values", valfile)
|
||||
}
|
||||
|
||||
if opts.Set != nil {
|
||||
for _, s := range opts.Set {
|
||||
flags = append(flags, "--set", s)
|
||||
}
|
||||
}
|
||||
|
||||
if len(outputDir) > 0 {
|
||||
releaseOutputDir, err := st.GenerateOutputDir(outputDir, release)
|
||||
if err != nil {
|
||||
|
|
@ -630,8 +677,23 @@ func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string,
|
|||
return nil
|
||||
}
|
||||
|
||||
type LintOpts struct {
|
||||
Set []string
|
||||
}
|
||||
|
||||
type LintOpt interface{ Apply(*LintOpts) }
|
||||
|
||||
func (o *LintOpts) Apply(opts *LintOpts) {
|
||||
*opts = *o
|
||||
}
|
||||
|
||||
// LintReleases wrapper for executing helm lint on the releases
|
||||
func (st *HelmState) LintReleases(helm helmexec.Interface, additionalValues []string, args []string, workerLimit int) []error {
|
||||
func (st *HelmState) LintReleases(helm helmexec.Interface, additionalValues []string, args []string, workerLimit int, opt ...LintOpt) []error {
|
||||
opts := &LintOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
}
|
||||
|
||||
// Reset the extra args if already set, not to break `helm fetch` by adding the args intended for `lint`
|
||||
helm.SetExtraArgs()
|
||||
|
||||
|
|
@ -677,6 +739,12 @@ func (st *HelmState) LintReleases(helm helmexec.Interface, additionalValues []st
|
|||
flags = append(flags, "--values", valfile)
|
||||
}
|
||||
|
||||
if opts.Set != nil {
|
||||
for _, s := range opts.Set {
|
||||
flags = append(flags, "--set", s)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) == 0 {
|
||||
if err := helm.Lint(release.Name, temp[release.Name], flags...); err != nil {
|
||||
errs = append(errs, err)
|
||||
|
|
@ -780,6 +848,12 @@ func (st *HelmState) prepareDiffReleases(helm helmexec.Interface, additionalValu
|
|||
flags = append(flags, "--context", fmt.Sprintf("%d", opts.Context))
|
||||
}
|
||||
|
||||
if opts.Set != nil {
|
||||
for _, s := range opts.Set {
|
||||
flags = append(flags, "--set", s)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
rsErrs := make([]*ReleaseError, len(errs))
|
||||
for i, e := range errs {
|
||||
|
|
@ -826,8 +900,9 @@ func (st *HelmState) createHelmContext(spec *ReleaseSpec, workerIndex int) helme
|
|||
}
|
||||
|
||||
type DiffOpts struct {
|
||||
NoColor bool
|
||||
Context int
|
||||
NoColor bool
|
||||
Set []string
|
||||
}
|
||||
|
||||
func (o *DiffOpts) Apply(opts *DiffOpts) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue