feat: `helmfile template --skip-cleanup` (#1570)
* feat: `helmfile template --skip-cleanup` Resolves #1517
This commit is contained in:
parent
5a15b65b94
commit
88884b68dc
4
main.go
4
main.go
|
|
@ -256,6 +256,10 @@ func main() {
|
|||
Name: "skip-deps",
|
||||
Usage: "skip running `helm repo update` and `helm dependency build`",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-cleanup",
|
||||
Usage: "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security",
|
||||
},
|
||||
},
|
||||
Action: action(func(run *app.App, c configImpl) error {
|
||||
return run.Template(c)
|
||||
|
|
|
|||
|
|
@ -218,6 +218,9 @@ func (a *App) Diff(c DiffConfigProvider) error {
|
|||
}
|
||||
|
||||
func (a *App) Template(c TemplateConfigProvider) error {
|
||||
|
||||
opts := []LoadOption{SetRetainValuesFiles(c.SkipCleanup())}
|
||||
|
||||
return a.ForEachState(func(run *Run) (ok bool, errs []error) {
|
||||
// `helm template` in helm v2 does not support local chart.
|
||||
// So, we set forceDownload=true for helm v2 only
|
||||
|
|
@ -233,7 +236,7 @@ func (a *App) Template(c TemplateConfigProvider) error {
|
|||
}
|
||||
|
||||
return
|
||||
})
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func (a *App) WriteValues(c WriteValuesConfigProvider) error {
|
||||
|
|
@ -1437,6 +1440,7 @@ func (a *App) template(r *Run, c TemplateConfigProvider) (bool, []error) {
|
|||
Set: c.Set(),
|
||||
IncludeCRDs: c.IncludeCRDs(),
|
||||
OutputDirTemplate: c.OutputDirTemplate(),
|
||||
SkipCleanup: c.SkipCleanup(),
|
||||
}
|
||||
return subst.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency(), c.Validate(), opts)
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -2241,6 +2241,7 @@ type configImpl struct {
|
|||
set []string
|
||||
output string
|
||||
includeCRDs bool
|
||||
skipCleanup bool
|
||||
skipDeps bool
|
||||
}
|
||||
|
||||
|
|
@ -2264,6 +2265,10 @@ func (c configImpl) Validate() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (c configImpl) SkipCleanup() bool {
|
||||
return c.skipCleanup
|
||||
}
|
||||
|
||||
func (c configImpl) SkipDeps() bool {
|
||||
return c.skipDeps
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ type TemplateConfigProvider interface {
|
|||
OutputDirTemplate() string
|
||||
Validate() bool
|
||||
SkipDeps() bool
|
||||
SkipCleanup() bool
|
||||
OutputDir() string
|
||||
IncludeCRDs() bool
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ type execer struct {
|
|||
extra []string
|
||||
decryptedSecretMutex sync.Mutex
|
||||
decryptedSecrets map[string]*decryptedSecret
|
||||
writeTempFile func([]byte) (string, error)
|
||||
}
|
||||
|
||||
func NewLogger(writer io.Writer, logLevel string) *zap.SugaredLogger {
|
||||
|
|
@ -278,16 +279,32 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str
|
|||
defer secret.mutex.RUnlock()
|
||||
}
|
||||
|
||||
tmpFile, err := ioutil.TempFile("", "secret")
|
||||
if err != nil {
|
||||
return "", err
|
||||
tempFile := helm.writeTempFile
|
||||
|
||||
if tempFile == nil {
|
||||
tempFile = func(content []byte) (string, error) {
|
||||
tmpFile, err := ioutil.TempFile("", "secret")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = tmpFile.Write(content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tmpFile.Name(), nil
|
||||
}
|
||||
}
|
||||
_, err = tmpFile.Write(secret.bytes)
|
||||
|
||||
tmpFileName, err := tempFile(secret.bytes)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tmpFile.Name(), err
|
||||
helm.logger.Debugf("Decrypted %s into %s", absPath, tmpFileName)
|
||||
|
||||
return tmpFileName, err
|
||||
}
|
||||
|
||||
func (helm *execer) TemplateRelease(name string, chart string, flags ...string) error {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package helmexec
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
|
@ -257,6 +258,12 @@ func Test_DecryptSecret(t *testing.T) {
|
|||
var buffer bytes.Buffer
|
||||
logger := NewLogger(&buffer, "debug")
|
||||
helm := MockExecer(logger, "dev")
|
||||
|
||||
tmpFilePath := "path/to/temp/file"
|
||||
helm.writeTempFile = func(content []byte) (string, error) {
|
||||
return tmpFilePath, nil
|
||||
}
|
||||
|
||||
helm.DecryptSecret(HelmContext{}, "secretName")
|
||||
cwd, err := filepath.Abs(".")
|
||||
if err != nil {
|
||||
|
|
@ -270,9 +277,10 @@ Decrypting secret %s/secretName
|
|||
exec: helm --kube-context dev secrets dec %s/secretName
|
||||
Preparing to decrypt secret %s/secretName
|
||||
Found secret in cache %s/secretName
|
||||
`, cwd, cwd, cwd, cwd, cwd)
|
||||
if buffer.String() != expected {
|
||||
t.Errorf("helmexec.DecryptSecret()\nactual = %v\nexpect = %v", buffer.String(), expected)
|
||||
Decrypted %s/secretName into path/to/temp/file
|
||||
`, cwd, cwd, cwd, cwd, cwd, cwd)
|
||||
if d := cmp.Diff(expected, buffer.String()); d != "" {
|
||||
t.Errorf("helmexec.DecryptSecret(): want (-), got (+):\n%s", d)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -670,6 +670,10 @@ func (st *HelmState) SyncReleases(affectedReleases *AffectedReleases, helm helme
|
|||
preps, prepErrs := st.prepareSyncReleases(helm, additionalValues, workerLimit, opts)
|
||||
|
||||
defer func() {
|
||||
if opts.SkipCleanup {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range preps {
|
||||
st.removeFiles(p.files)
|
||||
}
|
||||
|
|
@ -1125,6 +1129,7 @@ func (st *HelmState) runHelmDepBuilds(helm helmexec.Interface, concurrency int,
|
|||
|
||||
type TemplateOpts struct {
|
||||
Set []string
|
||||
SkipCleanup bool
|
||||
OutputDirTemplate string
|
||||
IncludeCRDs bool
|
||||
}
|
||||
|
|
@ -1136,7 +1141,9 @@ func (o *TemplateOpts) Apply(opts *TemplateOpts) {
|
|||
}
|
||||
|
||||
// TemplateReleases wrapper for executing helm template on the releases
|
||||
func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, additionalValues []string, args []string, workerLimit int, validate bool, opt ...TemplateOpt) []error {
|
||||
func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string, additionalValues []string, args []string, workerLimit int,
|
||||
validate bool, opt ...TemplateOpt) []error {
|
||||
|
||||
opts := &TemplateOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
|
|
@ -1156,6 +1163,10 @@ func (st *HelmState) TemplateReleases(helm helmexec.Interface, outputDir string,
|
|||
flags, files, err := st.flagsForTemplate(helm, release, 0)
|
||||
|
||||
defer func() {
|
||||
if opts.SkipCleanup {
|
||||
return
|
||||
}
|
||||
|
||||
st.removeFiles(files)
|
||||
}()
|
||||
|
||||
|
|
@ -1571,6 +1582,10 @@ func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []st
|
|||
preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppressSecrets, opts)
|
||||
|
||||
defer func() {
|
||||
if opts.SkipCleanup {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range preps {
|
||||
st.removeFiles(p.files)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue