mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-05 13:13:31 +02:00
feat: add --output-dir on template command (#693)
It generates templates in a subdirectory named "stateFileName-stateFileHash-releaseName"
This commit is contained in:
+6
-1
@@ -45,6 +45,8 @@ type App struct {
|
||||
chdir func(string) error
|
||||
|
||||
remote *remote.Remote
|
||||
|
||||
helmExecer helmexec.Interface
|
||||
}
|
||||
|
||||
func New(conf ConfigProvider) *App {
|
||||
@@ -59,6 +61,9 @@ func New(conf ConfigProvider) *App {
|
||||
FileOrDir: conf.FileOrDir(),
|
||||
ValuesFiles: conf.ValuesFiles(),
|
||||
Set: conf.Set(),
|
||||
helmExecer: helmexec.New(conf.Logger(), conf.KubeContext(), &helmexec.ShellRunner{
|
||||
Logger: conf.Logger(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -274,7 +279,7 @@ func (a *App) visitStates(fileOrDir string, defOpts LoadOpts, converge func(*sta
|
||||
|
||||
ctx := context{a, st}
|
||||
|
||||
helm := helmexec.New(a.Logger, a.KubeContext)
|
||||
helm := a.helmExecer
|
||||
|
||||
if err != nil {
|
||||
switch stateLoadErr := err.(type) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/roboll/helmfile/pkg/helmexec"
|
||||
"github.com/roboll/helmfile/pkg/state"
|
||||
@@ -8,8 +9,10 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gotest.tools/env"
|
||||
)
|
||||
|
||||
@@ -1738,3 +1741,158 @@ services:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type configImpl struct {
|
||||
}
|
||||
|
||||
func (c configImpl) Values() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (c configImpl) Args() string {
|
||||
return "some args"
|
||||
}
|
||||
|
||||
func (c configImpl) SkipDeps() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (c configImpl) OutputDir() string {
|
||||
return "output/subdir"
|
||||
}
|
||||
|
||||
func (c configImpl) Concurrency() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
// Mocking the command-line runner
|
||||
|
||||
type mockRunner struct {
|
||||
output []byte
|
||||
err error
|
||||
}
|
||||
|
||||
func (mock *mockRunner) Execute(cmd string, args []string, env map[string]string) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func MockExecer(logger *zap.SugaredLogger, kubeContext string) helmexec.Interface {
|
||||
execer := helmexec.New(logger, kubeContext, &mockRunner{})
|
||||
return execer
|
||||
}
|
||||
|
||||
// mocking helmexec.Interface
|
||||
|
||||
type listKey struct {
|
||||
filter string
|
||||
flags string
|
||||
}
|
||||
|
||||
type mockHelmExec struct {
|
||||
templated []mockTemplates
|
||||
|
||||
updateDepsCallbacks map[string]func(string) error
|
||||
}
|
||||
|
||||
type mockTemplates struct {
|
||||
flags []string
|
||||
}
|
||||
|
||||
func (helm *mockHelmExec) TemplateRelease(chart string, flags ...string) error {
|
||||
helm.templated = append(helm.templated, mockTemplates{flags: flags})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (helm *mockHelmExec) UpdateDeps(chart string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (helm *mockHelmExec) BuildDeps(chart string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (helm *mockHelmExec) SetExtraArgs(args ...string) {
|
||||
return
|
||||
}
|
||||
func (helm *mockHelmExec) SetHelmBinary(bin string) {
|
||||
return
|
||||
}
|
||||
func (helm *mockHelmExec) AddRepo(name, repository, certfile, keyfile, username, password string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) UpdateRepo() error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) SyncRelease(context helmexec.HelmContext, name, chart string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) DiffRelease(context helmexec.HelmContext, name, chart string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) ReleaseStatus(context helmexec.HelmContext, release string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) DeleteRelease(context helmexec.HelmContext, name string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) List(context helmexec.HelmContext, filter string, flags ...string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (helm *mockHelmExec) DecryptSecret(context helmexec.HelmContext, name string, flags ...string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (helm *mockHelmExec) TestRelease(context helmexec.HelmContext, name string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) Fetch(chart string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) Lint(chart string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestTemplate_SingleStateFile(t *testing.T) {
|
||||
files := map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
releases:
|
||||
- name: myrelease1
|
||||
chart: mychart1
|
||||
- name: myrelease2
|
||||
chart: mychart1
|
||||
`,
|
||||
}
|
||||
|
||||
var helm = &mockHelmExec{}
|
||||
var wantReleases = []mockTemplates{
|
||||
{[]string{"--name", "myrelease1", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}},
|
||||
{[]string{"--name", "myrelease2", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease2"}},
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
logger := helmexec.NewLogger(&buffer, "debug")
|
||||
|
||||
app := appWithFs(&App{
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
KubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
helmExecer: helm,
|
||||
}, files)
|
||||
app.Template(configImpl{})
|
||||
|
||||
for i := range wantReleases {
|
||||
for j := range wantReleases[i].flags {
|
||||
if j == 3 {
|
||||
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])
|
||||
}
|
||||
} else if wantReleases[i].flags[j] != helm.templated[i].flags[j] {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ type TemplateConfigProvider interface {
|
||||
|
||||
Values() []string
|
||||
SkipDeps() bool
|
||||
OutputDir() string
|
||||
|
||||
concurrencyConfig
|
||||
}
|
||||
|
||||
+1
-1
@@ -270,7 +270,7 @@ func (r *Run) Template(c TemplateConfigProvider) []error {
|
||||
}
|
||||
|
||||
args := argparser.GetArgs(c.Args(), state)
|
||||
return state.TemplateReleases(helm, c.Values(), args, c.Concurrency())
|
||||
return state.TemplateReleases(helm, c.OutputDir(), c.Values(), args, c.Concurrency())
|
||||
}
|
||||
|
||||
func (r *Run) Test(c TestConfigProvider) []error {
|
||||
|
||||
Reference in New Issue
Block a user