Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions chartify.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ type ChartifyOpts struct {
// EnableKustomizAlphaPlugins will add the `--enable_alpha_plugins` flag when running `kustomize build`
EnableKustomizeAlphaPlugins bool

// KustomizeBuildArgs are extra arguments to pass to `kustomize build` command
// For example, ["--enable-exec"] for plugins like ksops
KustomizeBuildArgs []string

Injectors []string
Injects []string

Expand Down Expand Up @@ -279,6 +283,7 @@ func (r *Runner) Chartify(release, dirOrChart string, opts ...ChartifyOption) (s
Namespace: u.Namespace,
HelmBinary: r.helmBin(),
SortOptions: u.SortOptions,
ExtraArgs: u.KustomizeBuildArgs,
}
kustomizeFile, err := r.KustomizeBuild(dirOrChart, tempDir, kustomizeOpts)
if err != nil {
Expand Down Expand Up @@ -496,6 +501,7 @@ func (r *Runner) Chartify(release, dirOrChart string, opts ...ChartifyOption) (s
Transformers: u.Transformers,
EnableAlphaPlugins: u.EnableKustomizeAlphaPlugins,
SortOptions: u.SortOptions,
ExtraArgs: u.KustomizeBuildArgs,
}
if err := r.Patch(tempDir, generatedManifestFiles, patchOpts); err != nil {
return "", err
Expand Down
4 changes: 4 additions & 0 deletions cmd/chartify/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func main() {
Namespace: "",
ChartVersion: "",
EnableKustomizeAlphaPlugins: false,
KustomizeBuildArgs: nil,
Injectors: nil,
Injects: nil,
AdhocChartDependencies: nil,
Expand All @@ -43,12 +44,14 @@ func main() {
}

deps := stringSlice{}
kustomizeBuildArgs := stringSlice{}

flag.StringVar(&file, "f", "-", "The path to the input file or stdout(-)")
flag.StringVar(&outDir, "o", "", "The path to the output directory")
flag.Var(&deps, "d", "one or more \"alias=chart:version\" to add adhoc chart dependencies")
flag.BoolVar(&opts.IncludeCRDs, "include-crds", false, "Whether to render CRDs contained in the chart and include the results into the output")
flag.StringVar(&strategicMergePatch, "strategic-merge-patch", "", "Path to a kustomize strategic merge patch file")
flag.Var(&kustomizeBuildArgs, "kustomize-build-arg", "Extra arguments to pass to 'kustomize build' command (e.g. --enable-exec). Can be specified multiple times.")

flag.Parse()

Expand All @@ -61,6 +64,7 @@ func main() {
}

opts.DeprecatedAdhocChartDependencies = deps
opts.KustomizeBuildArgs = kustomizeBuildArgs

c := chartify.New(chartify.HelmBin("helm"))

Expand Down
6 changes: 6 additions & 0 deletions kustomize.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type KustomizeBuildOpts struct {
Namespace string
HelmBinary string
SortOptions *SortOptions
ExtraArgs []string
}

func (o *KustomizeBuildOpts) SetKustomizeBuildOption(opts *KustomizeBuildOpts) error {
Expand Down Expand Up @@ -238,6 +239,11 @@ func (r *Runner) KustomizeBuild(srcDir string, tempDir string, opts ...Kustomize
kustomizeArgs = append(kustomizeArgs, "--helm-command="+u.HelmBinary)
}

// Add any extra arguments provided by the user
if len(u.ExtraArgs) > 0 {
kustomizeArgs = append(kustomizeArgs, u.ExtraArgs...)
}

out, err := r.runInDir(tempDir, bin, append(kustomizeArgs, tempDir)...)
if err != nil {
return "", err
Expand Down
118 changes: 118 additions & 0 deletions kustomize_extra_args_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package chartify

import (
"io"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

type spyCall struct {
name string
args []string
}

// newSpyRunner returns a Runner whose RunCommand captures every invocation
// instead of running a real process. The spy:
// - replies to `kustomize version` so kustomizeLoadRestrictionsNoneFlag /
// kustomizeEnableAlphaPluginsFlag can derive a flag, and
// - honors `--output <path>` (used by Patch) by writing a minimal resource
// YAML there, so callers that read the rendered file succeed.
//
// The kustomize binary name still has to resolve via exec.LookPath, so this
// relies on kustomize being on PATH (already a documented test prerequisite).
func newSpyRunner(t *testing.T, versionOut string) (*Runner, *[]spyCall) {
t.Helper()
var calls []spyCall
r := New()
r.RunCommand = func(name string, args []string, dir string, stdout, stderr io.Writer, env map[string]string) error {
calls = append(calls, spyCall{name: name, args: append([]string{}, args...)})

if len(args) > 0 && args[0] == "version" {
_, _ = io.WriteString(stdout, versionOut)
return nil
}
for i, a := range args {
if a == "--output" && i+1 < len(args) {
_ = os.WriteFile(args[i+1], []byte("kind: ConfigMap\nmetadata:\n name: test\n"), 0644)
}
}
return nil
}
return r, &calls
}

// buildCall returns the first recorded invocation that runs a kustomize "build".
func buildCall(calls []spyCall) (spyCall, bool) {
for _, c := range calls {
for _, a := range c.args {
if a == "build" {
return c, true
}
}
}
return spyCall{}, false
}

func TestKustomizeBuildExtraArgs(t *testing.T) {
r, callsPtr := newSpyRunner(t, "v5.0.0")

srcDir := t.TempDir()
tempDir := t.TempDir()

_, err := r.KustomizeBuild(srcDir, tempDir, &KustomizeBuildOpts{
ExtraArgs: []string{"--enable-exec"},
})
require.NoError(t, err)

build, ok := buildCall(*callsPtr)
require.True(t, ok, "expected a kustomize build invocation; calls=%v", *callsPtr)

// ExtraArgs must be appended to the build command.
require.Contains(t, build.args, "--enable-exec",
"ExtraArgs should be appended to the kustomize build command")
// Standard flags must still be present.
require.Contains(t, build.args, "--enable-helm")
require.Contains(t, build.args, "--load-restrictor=LoadRestrictionsNone")

// ExtraArgs must be inserted before the positional target (tempDir, passed
// last) so a flag is never mistaken for the build target.
require.NotEmpty(t, build.args)
require.Equal(t, tempDir, build.args[len(build.args)-1],
"the kustomize target must remain the last positional arg")
}

func TestKustomizeBuildNoExtraArgsByDefault(t *testing.T) {
r, callsPtr := newSpyRunner(t, "v5.0.0")

_, err := r.KustomizeBuild(t.TempDir(), t.TempDir())
require.NoError(t, err)

build, ok := buildCall(*callsPtr)
require.True(t, ok)
require.NotContains(t, build.args, "--enable-exec",
"no extra flags should be added when ExtraArgs is unset")
}

func TestPatchExtraArgs(t *testing.T) {
r, callsPtr := newSpyRunner(t, "v5.0.0")

tempDir := t.TempDir()
manifest := filepath.Join(tempDir, "templates", "cm.yaml")
require.NoError(t, os.MkdirAll(filepath.Dir(manifest), 0755))
require.NoError(t, os.WriteFile(manifest, []byte("kind: ConfigMap\nmetadata:\n name: test\n"), 0644))

err := r.Patch(tempDir, []string{"templates/cm.yaml"}, &PatchOpts{
ExtraArgs: []string{"--enable-exec"},
})
require.NoError(t, err)

build, ok := buildCall(*callsPtr)
require.True(t, ok, "expected a kustomize build invocation; calls=%v", *callsPtr)
require.Contains(t, build.args, "--enable-exec",
"PatchOpts.ExtraArgs should be appended to the kustomize build command")
require.Equal(t, tempDir, build.args[len(build.args)-1],
"the kustomize target must remain the last positional arg")
}
9 changes: 9 additions & 0 deletions patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ type PatchOpts struct {

// SortOptions configures kustomize's sortOptions for resource ordering.
SortOptions *SortOptions

// ExtraArgs are extra arguments to pass to `kustomize build` command
// For example, ["--enable-exec"] for plugins like ksops
ExtraArgs []string
}

func (o *PatchOpts) SetPatchOption(opts *PatchOpts) error {
Expand Down Expand Up @@ -212,6 +216,11 @@ resources:
kustomizeArgs = append(kustomizeArgs, f)
}

// Add any extra arguments provided by the user
if len(u.ExtraArgs) > 0 {
kustomizeArgs = append(kustomizeArgs, u.ExtraArgs...)
}

// tempDir is the kustomize target, appended last (mirrors KustomizeBuild argument order).
_, err := r.run(nil, bin, append(kustomizeArgs, tempDir)...)
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions tempdir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,29 @@ func TestGenerateID(t *testing.T) {
release: "foo",
chart: "incubator/raw",
opts: ChartifyOpts{},
want: "foo-5586b9d54d",
want: "foo-7bb8758c6f",
})

run(testcase{
release: "foo",
chart: "stable/envoy",
opts: ChartifyOpts{},
want: "foo-748fb9844f",
want: "foo-595bcf5dfd",
})

run(testcase{
release: "bar",
chart: "incubator/raw",
opts: ChartifyOpts{},
want: "bar-77ddc8bd65",
want: "bar-7759488ffd",
})

run(testcase{
release: "foo",
opts: ChartifyOpts{
Namespace: "myns",
},
want: "myns-foo-5dbbf694b5",
want: "myns-foo-54c5cbf858",
})

for id, n := range ids {
Expand Down