From c3c4cc13ac71a767469b683ad2ea35f33e7a1199 Mon Sep 17 00:00:00 2001 From: Max Jonas Werner Date: Tue, 4 Oct 2022 13:32:19 +0200 Subject: [PATCH] support alternative kustomization file names `KustomizeGenerator.WriteFile` now detects alternative kustomization file names such as `kustomization.yml` and `Kustomization`. closes #737 Signed-off-by: Max Jonas Werner --- controllers/kustomization_controller.go | 4 +- controllers/kustomization_generator.go | 39 +++++----- controllers/kustomization_generator_test.go | 72 +++++++++++++++++++ .../Kustomization/Kustomization | 4 ++ .../Kustomization/deployment.yaml | 19 +++++ .../different-filenames/yaml/deployment.yaml | 19 +++++ .../yaml/kustomization.yaml | 4 ++ .../different-filenames/yml/deployment.yaml | 19 +++++ .../different-filenames/yml/kustomization.yml | 4 ++ go.mod | 3 +- go.sum | 7 ++ 11 files changed, 171 insertions(+), 23 deletions(-) create mode 100644 controllers/testdata/different-filenames/Kustomization/Kustomization create mode 100644 controllers/testdata/different-filenames/Kustomization/deployment.yaml create mode 100644 controllers/testdata/different-filenames/yaml/deployment.yaml create mode 100644 controllers/testdata/different-filenames/yaml/kustomization.yaml create mode 100644 controllers/testdata/different-filenames/yml/deployment.yaml create mode 100644 controllers/testdata/different-filenames/yml/kustomization.yml diff --git a/controllers/kustomization_controller.go b/controllers/kustomization_controller.go index 5ced97c1..bf4c202a 100644 --- a/controllers/kustomization_controller.go +++ b/controllers/kustomization_controller.go @@ -592,8 +592,8 @@ func (r *KustomizationReconciler) getSource(ctx context.Context, kustomization k } func (r *KustomizationReconciler) generate(kustomization kustomizev1.Kustomization, workDir string, dirPath string) error { - gen := NewGenerator(workDir, kustomization) - return gen.WriteFile(dirPath) + _, err := NewGenerator(workDir, kustomization).WriteFile(dirPath) + return err } func (r *KustomizationReconciler) build(ctx context.Context, workDir string, kustomization kustomizev1.Kustomization, dirPath string) ([]byte, error) { diff --git a/controllers/kustomization_generator.go b/controllers/kustomization_generator.go index 00762743..bae39885 100644 --- a/controllers/kustomization_generator.go +++ b/controllers/kustomization_generator.go @@ -24,12 +24,12 @@ import ( "strings" "sync" - "sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/krusty" "sigs.k8s.io/kustomize/api/provider" "sigs.k8s.io/kustomize/api/resmap" kustypes "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/yaml" "github.com/fluxcd/pkg/apis/kustomize" @@ -50,16 +50,15 @@ func NewGenerator(root string, kustomization kustomizev1.Kustomization) *Kustomi } } -func (kg *KustomizeGenerator) WriteFile(dirPath string) error { - if err := kg.generateKustomization(dirPath); err != nil { - return err +func (kg *KustomizeGenerator) WriteFile(dirPath string) (string, error) { + kfile, err := kg.generateKustomization(dirPath) + if err != nil { + return "", err } - kfile := filepath.Join(dirPath, konfig.DefaultKustomizationFileName()) - data, err := os.ReadFile(kfile) if err != nil { - return err + return "", err } kus := kustypes.Kustomization{ @@ -70,7 +69,7 @@ func (kg *KustomizeGenerator) WriteFile(dirPath string) error { } if err := yaml.Unmarshal(data, &kus); err != nil { - return err + return "", err } if kg.kustomization.Spec.TargetNamespace != "" { @@ -91,7 +90,7 @@ func (kg *KustomizeGenerator) WriteFile(dirPath string) error { for _, m := range kg.kustomization.Spec.PatchesJSON6902 { patch, err := json.Marshal(m.Patch) if err != nil { - return err + return "", err } kus.PatchesJson6902 = append(kus.PatchesJson6902, kustypes.Patch{ Patch: string(patch), @@ -115,9 +114,9 @@ func (kg *KustomizeGenerator) WriteFile(dirPath string) error { kd, err := yaml.Marshal(kus) if err != nil { - return err + return "", err } - return os.WriteFile(kfile, kd, os.ModePerm) + return kfile, os.WriteFile(kfile, kd, os.ModePerm) } func checkKustomizeImageExists(images []kustypes.Image, imageName string) (bool, int) { @@ -130,17 +129,17 @@ func checkKustomizeImageExists(images []kustypes.Image, imageName string) (bool, return false, -1 } -func (kg *KustomizeGenerator) generateKustomization(dirPath string) error { +func (kg *KustomizeGenerator) generateKustomization(dirPath string) (string, error) { fs, err := securefs.MakeFsOnDiskSecure(kg.root) if err != nil { - return err + return "", err } // Determine if there already is a Kustomization file at the root, // as this means we do not have to generate one. for _, kfilename := range konfig.RecognizedKustomizationFileNames() { if kpath := filepath.Join(dirPath, kfilename); fs.Exists(kpath) && !fs.IsDir(kpath) { - return nil + return kpath, nil } } @@ -188,21 +187,21 @@ func (kg *KustomizeGenerator) generateKustomization(dirPath string) error { abs, err := filepath.Abs(dirPath) if err != nil { - return err + return "", err } files, err := scan(abs) if err != nil { - return err + return "", err } kfile := filepath.Join(dirPath, konfig.DefaultKustomizationFileName()) f, err := fs.Create(kfile) if err != nil { - return err + return "", err } if err = f.Close(); err != nil { - return err + return "", err } kus := kustypes.Kustomization{ @@ -220,10 +219,10 @@ func (kg *KustomizeGenerator) generateKustomization(dirPath string) error { kus.Resources = resources kd, err := yaml.Marshal(kus) if err != nil { - return err + return "", err } - return os.WriteFile(kfile, kd, os.ModePerm) + return kfile, os.WriteFile(kfile, kd, os.ModePerm) } func adaptSelector(selector *kustomize.Selector) (output *kustypes.Selector) { diff --git a/controllers/kustomization_generator_test.go b/controllers/kustomization_generator_test.go index e40f1e8e..a251e4cd 100644 --- a/controllers/kustomization_generator_test.go +++ b/controllers/kustomization_generator_test.go @@ -17,8 +17,16 @@ limitations under the License. package controllers import ( + "os" + "path/filepath" "testing" + "github.com/otiai10/copy" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + kustypes "sigs.k8s.io/kustomize/api/types" + + "github.com/fluxcd/kustomize-controller/api/v1beta2" + "github.com/fluxcd/pkg/apis/kustomize" . "github.com/onsi/gomega" ) @@ -57,3 +65,67 @@ func Test_secureBuildKustomization_rel_basedir(t *testing.T) { _, err := secureBuildKustomization("testdata/relbase", "testdata/relbase/clusters/staging/flux-system", false) g.Expect(err).ToNot(HaveOccurred()) } + +func TestGeneratorWriteFile(t *testing.T) { + tests := []struct { + name string + dir string + }{ + { + name: "detects kustomization.yml", + dir: "yml", + }, + { + name: "detects Kustomization", + dir: "Kustomization", + }, + { + name: "detects kustomization.yaml", + dir: "yaml", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + tmpDir := t.TempDir() + g.Expect(copy.Copy("./testdata/different-filenames", tmpDir)).To(Succeed()) + ks := v1beta2.Kustomization{ + Spec: v1beta2.KustomizationSpec{ + PatchesStrategicMerge: []apiextv1.JSON{ + { + Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"patch4":"strategic-merge"}}}`), + }, + }, + Patches: []kustomize.Patch{ + { + Patch: `- op: add + path: /metadata/labels/patch1 + value: inline-json`, + Target: kustomize.Selector{ + LabelSelector: "app=podinfo", + }, + }, + }, + PatchesJSON6902: []kustomize.JSON6902Patch{ + { + Patch: []kustomize.JSON6902{ + {Op: "add", Path: "/metadata/labels/patch3", Value: &apiextv1.JSON{Raw: []byte(`"json6902"`)}}, + }, + }, + }, + }, + } + kfile, err := NewGenerator(filepath.Join(tmpDir, tt.dir), ks).WriteFile(filepath.Join(tmpDir, tt.dir)) + g.Expect(err).ToNot(HaveOccurred()) + + kfileYAML, err := os.ReadFile(kfile) + g.Expect(err).ToNot(HaveOccurred()) + var k kustypes.Kustomization + g.Expect(k.Unmarshal(kfileYAML)).To(Succeed()) + g.Expect(k.Patches).To(HaveLen(1), "unexpected number of patches in kustomization file") + g.Expect(k.PatchesStrategicMerge).To(HaveLen(1), "unexpected number of strategic merge patches in kustomization file") + g.Expect(k.PatchesJson6902).To(HaveLen(1), "unexpected number of RFC 6902 patches in kustomization file") + }) + } +} diff --git a/controllers/testdata/different-filenames/Kustomization/Kustomization b/controllers/testdata/different-filenames/Kustomization/Kustomization new file mode 100644 index 00000000..42835f53 --- /dev/null +++ b/controllers/testdata/different-filenames/Kustomization/Kustomization @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml diff --git a/controllers/testdata/different-filenames/Kustomization/deployment.yaml b/controllers/testdata/different-filenames/Kustomization/deployment.yaml new file mode 100644 index 00000000..73eabc01 --- /dev/null +++ b/controllers/testdata/different-filenames/Kustomization/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podinfo + labels: + app: podinfo +spec: + replicas: 1 + selector: + matchLabels: + app: podinfo + template: + metadata: + labels: + app: podinfo + spec: + containers: + - name: podinfo + image: podinfo diff --git a/controllers/testdata/different-filenames/yaml/deployment.yaml b/controllers/testdata/different-filenames/yaml/deployment.yaml new file mode 100644 index 00000000..73eabc01 --- /dev/null +++ b/controllers/testdata/different-filenames/yaml/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podinfo + labels: + app: podinfo +spec: + replicas: 1 + selector: + matchLabels: + app: podinfo + template: + metadata: + labels: + app: podinfo + spec: + containers: + - name: podinfo + image: podinfo diff --git a/controllers/testdata/different-filenames/yaml/kustomization.yaml b/controllers/testdata/different-filenames/yaml/kustomization.yaml new file mode 100644 index 00000000..42835f53 --- /dev/null +++ b/controllers/testdata/different-filenames/yaml/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml diff --git a/controllers/testdata/different-filenames/yml/deployment.yaml b/controllers/testdata/different-filenames/yml/deployment.yaml new file mode 100644 index 00000000..73eabc01 --- /dev/null +++ b/controllers/testdata/different-filenames/yml/deployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: podinfo + labels: + app: podinfo +spec: + replicas: 1 + selector: + matchLabels: + app: podinfo + template: + metadata: + labels: + app: podinfo + spec: + containers: + - name: podinfo + image: podinfo diff --git a/controllers/testdata/different-filenames/yml/kustomization.yml b/controllers/testdata/different-filenames/yml/kustomization.yml new file mode 100644 index 00000000..42835f53 --- /dev/null +++ b/controllers/testdata/different-filenames/yml/kustomization.yml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- deployment.yaml diff --git a/go.mod b/go.mod index d59fa253..ee154362 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( github.com/hashicorp/vault/api v1.8.0 github.com/onsi/gomega v1.20.2 github.com/ory/dockertest v3.3.5+incompatible + github.com/otiai10/copy v1.7.0 github.com/spf13/pflag v1.0.5 go.mozilla.org/sops/v3 v3.7.3 golang.org/x/net v0.0.0-20220927171203-f486391704dc @@ -48,6 +49,7 @@ require ( sigs.k8s.io/cli-utils v0.33.0 sigs.k8s.io/controller-runtime v0.13.0 sigs.k8s.io/kustomize/api v0.12.1 + sigs.k8s.io/kustomize/kyaml v0.13.9 sigs.k8s.io/yaml v1.3.0 ) @@ -228,6 +230,5 @@ require ( k8s.io/kubectl v0.24.0 // indirect k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect - sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect ) diff --git a/go.sum b/go.sum index 7c6773c5..e5e39b39 100644 --- a/go.sum +++ b/go.sum @@ -688,6 +688,13 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.m github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= +github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.3 h1:7JgpsBaN0uMkyju4tbYHu0mnM55hNKVYLsXmwr15NQI= +github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=