diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 99f6ac64323b2..4e6465528cd95 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -1394,7 +1394,10 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, kustomizeBinary = q.KustomizeOptions.BinaryPath } k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary) - targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env) + targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env, &kustomize.BuildOpts{ + KubeVersion: q.KubeVersion, + APIVersions: q.ApiVersions, + }) case v1alpha1.ApplicationSourceTypePlugin: pluginName := "" if q.ApplicationSource.Plugin != nil { @@ -2145,7 +2148,7 @@ func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apicl ApplicationSource: q.Source, } env := newEnv(&fakeManifestRequest, reversion) - _, images, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env) + _, images, err := k.Build(q.Source.Kustomize, q.KustomizeOptions, env, nil) if err != nil { return err } diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index 0884ec935f9c8..6bd09394f97e9 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -28,10 +28,15 @@ import ( // represents a Docker image in the format NAME[:TAG]. type Image = string +type BuildOpts struct { + KubeVersion string + APIVersions []string +} + // Kustomize provides wrapper functionality around the `kustomize` command. type Kustomize interface { // Build returns a list of unstructured objects from a `kustomize build` command and extract supported parameters - Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env) ([]*unstructured.Unstructured, []Image, error) + Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts) ([]*unstructured.Unstructured, []Image, error) } // NewKustomizeApp create a new wrapper to run commands on the `kustomize` command-line tool. @@ -88,7 +93,7 @@ func mapToEditAddArgs(val map[string]string) []string { return args } -func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env) ([]*unstructured.Unstructured, []Image, error) { +func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env, buildOpts *BuildOpts) ([]*unstructured.Unstructured, []Image, error) { env := os.Environ() if envVars != nil { env = append(env, envVars.Environ()...) @@ -300,7 +305,7 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp var cmd *exec.Cmd if kustomizeOptions != nil && kustomizeOptions.BuildOptions != "" { - params := parseKustomizeBuildOptions(k.path, kustomizeOptions.BuildOptions) + params := parseKustomizeBuildOptions(k.path, kustomizeOptions.BuildOptions, buildOpts) cmd = exec.Command(k.getBinaryPath(), params...) } else { cmd = exec.Command(k.getBinaryPath(), "build", k.path) @@ -320,8 +325,23 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp return objs, getImageParameters(objs), nil } -func parseKustomizeBuildOptions(path, buildOptions string) []string { - return append([]string{"build", path}, strings.Fields(buildOptions)...) +func parseKustomizeBuildOptions(path string, buildOptions string, buildOpts *BuildOpts) []string { + buildOptsParams := append([]string{"build", path}, strings.Fields(buildOptions)...) + + if buildOpts != nil && !getSemverSafe().LessThan(semver.MustParse("v5.3.0")) && isHelmEnabled(buildOptions) { + if buildOpts.KubeVersion != "" { + buildOptsParams = append(buildOptsParams, "--helm-kube-version", buildOpts.KubeVersion) + } + for _, v := range buildOpts.APIVersions { + buildOptsParams = append(buildOptsParams, "--helm-api-versions", v) + } + } + + return buildOptsParams +} + +func isHelmEnabled(buildOptions string) bool { + return strings.Contains(buildOptions, "--enable-helm") } var KustomizationNames = []string{"kustomization.yaml", "kustomization.yml", "Kustomization"} diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index 0178d6bb32bc4..cae3a62cfb23e 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -72,7 +72,9 @@ func TestKustomizeBuild(t *testing.T) { }, }, } - objs, images, err := kustomize.Build(&kustomizeSource, nil, env) + objs, images, err := kustomize.Build(&kustomizeSource, nil, env, &BuildOpts{ + KubeVersion: "1.27", APIVersions: []string{"foo", "bar"}, + }) require.NoError(t, err) if err != nil { assert.Len(t, objs, 2) @@ -135,7 +137,7 @@ func TestFailKustomizeBuild(t *testing.T) { }, }, } - _, _, err = kustomize.Build(&kustomizeSource, nil, nil) + _, _, err = kustomize.Build(&kustomizeSource, nil, nil, nil) assert.EqualError(t, err, "expected integer value for count. Received: garbage") } @@ -159,10 +161,26 @@ func TestIsKustomization(t *testing.T) { } func TestParseKustomizeBuildOptions(t *testing.T) { - built := parseKustomizeBuildOptions("guestbook", "-v 6 --logtostderr") + built := parseKustomizeBuildOptions("guestbook", "-v 6 --logtostderr", &BuildOpts{ + KubeVersion: "1.27", APIVersions: []string{"foo", "bar"}, + }) + // Helm is not enabled so helm options are not in the params assert.Equal(t, []string{"build", "guestbook", "-v", "6", "--logtostderr"}, built) } +func TestParseKustomizeBuildHelmOptions(t *testing.T) { + built := parseKustomizeBuildOptions("guestbook", "-v 6 --logtostderr --enable-helm", &BuildOpts{ + KubeVersion: "1.27", + APIVersions: []string{"foo", "bar"}, + }) + assert.Equal(t, []string{ + "build", "guestbook", + "-v", "6", "--logtostderr", "--enable-helm", + "--helm-kube-version", "1.27", + "--helm-api-versions", "foo", "--helm-api-versions", "bar", + }, built) +} + func TestVersion(t *testing.T) { ver, err := Version(false) require.NoError(t, err) @@ -226,7 +244,7 @@ func TestKustomizeBuildForceCommonLabels(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") - objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env) + objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) switch tc.ExpectErr { case true: require.Error(t, err) @@ -318,7 +336,7 @@ func TestKustomizeBuildForceCommonAnnotations(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") - objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env) + objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) switch tc.ExpectErr { case true: require.Error(t, err) @@ -385,7 +403,7 @@ func TestKustomizeLabelWithoutSelector(t *testing.T) { appPath, err := testDataDir(t, tc.TestData) require.NoError(t, err) kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") - objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env) + objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env, nil) switch tc.ExpectErr { case true: @@ -421,7 +439,7 @@ func TestKustomizeCustomVersion(t *testing.T) { env := &v1alpha1.Env{ &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: "argo-cd-tests"}, } - objs, images, err := kustomize.Build(&kustomizeSource, nil, env) + objs, images, err := kustomize.Build(&kustomizeSource, nil, env, nil) require.NoError(t, err) if err != nil { assert.Len(t, objs, 2) @@ -441,7 +459,7 @@ func TestKustomizeBuildComponents(t *testing.T) { kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Components: []string{"./components"}, } - objs, _, err := kustomize.Build(&kustomizeSource, nil, nil) + objs, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil) require.NoError(t, err) obj := objs[0] assert.Equal(t, "nginx-deployment", obj.GetName()) @@ -474,7 +492,7 @@ func TestKustomizeBuildPatches(t *testing.T) { }, }, } - objs, _, err := kustomize.Build(&kustomizeSource, nil, nil) + objs, _, err := kustomize.Build(&kustomizeSource, nil, nil, nil) require.NoError(t, err) obj := objs[0] containers, found, err := unstructured.NestedSlice(obj.Object, "spec", "template", "spec", "containers")