From 220e503116ff09412a3beb68ad3dd008fe2da983 Mon Sep 17 00:00:00 2001 From: Kristian Klausen Date: Fri, 28 Oct 2022 14:14:57 +0200 Subject: [PATCH] Add support for Kustomize components Fix #753 Signed-off-by: Kristian Klausen --- api/v1beta2/kustomization_types.go | 5 ++ api/v1beta2/zz_generated.deepcopy.go | 5 ++ ...mize.toolkit.fluxcd.io_kustomizations.yaml | 6 +++ internal/generator/generator.go | 4 ++ internal/generator/generator_test.go | 49 +++++++++++++++++++ .../components/components/configmap.yaml | 8 +++ .../components/components/kustomization.yaml | 7 +++ .../components/zero-components/configmap.yaml | 8 +++ .../zero-components/kustomization.yaml | 5 ++ 9 files changed, 97 insertions(+) create mode 100644 internal/generator/testdata/components/components/configmap.yaml create mode 100644 internal/generator/testdata/components/components/kustomization.yaml create mode 100644 internal/generator/testdata/components/zero-components/configmap.yaml create mode 100644 internal/generator/testdata/components/zero-components/kustomization.yaml diff --git a/api/v1beta2/kustomization_types.go b/api/v1beta2/kustomization_types.go index 09a5739b0..b6b9caa31 100644 --- a/api/v1beta2/kustomization_types.go +++ b/api/v1beta2/kustomization_types.go @@ -153,6 +153,11 @@ type KustomizationSpec struct { // +kubebuilder:validation:Enum=none;client;server // +optional Validation string `json:"validation,omitempty"` + + // Components specifies relative paths to specifications of other Components + // via relative paths, absolute paths, or URLs. + // +optional + Components []string `json:"components,omitempty"` } // Decryption defines how decryption is handled for Kubernetes manifests. diff --git a/api/v1beta2/zz_generated.deepcopy.go b/api/v1beta2/zz_generated.deepcopy.go index 93ab196c7..0ef46eab1 100644 --- a/api/v1beta2/zz_generated.deepcopy.go +++ b/api/v1beta2/zz_generated.deepcopy.go @@ -187,6 +187,11 @@ func (in *KustomizationSpec) DeepCopyInto(out *KustomizationSpec) { *out = new(v1.Duration) **out = **in } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KustomizationSpec. diff --git a/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml index 0b4cc2a0c..e04f611d1 100644 --- a/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml +++ b/config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml @@ -585,6 +585,12 @@ spec: description: KustomizationSpec defines the configuration to calculate the desired state from a Source using Kustomize. properties: + components: + description: Components specifies relative paths to specifications + of other Components via relative paths, absolute paths, or URLs. + items: + type: string + type: array decryption: description: Decrypt Kubernetes secrets before applying them on the cluster. diff --git a/internal/generator/generator.go b/internal/generator/generator.go index cb7ed9718..10cda620a 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -79,6 +79,10 @@ func (kg *KustomizeGenerator) WriteFile(dirPath string) (string, error) { }) } + for _, m := range kg.kustomization.Spec.Components { + kus.Components = append(kus.Components, m) + } + for _, m := range kg.kustomization.Spec.PatchesStrategicMerge { kus.PatchesStrategicMerge = append(kus.PatchesStrategicMerge, kustypes.PatchStrategicMerge(m.Raw)) } diff --git a/internal/generator/generator_test.go b/internal/generator/generator_test.go index 13a0fc248..787f319fd 100644 --- a/internal/generator/generator_test.go +++ b/internal/generator/generator_test.go @@ -93,3 +93,52 @@ func TestGenerator_WriteFile(t *testing.T) { }) } } + +func TestGenerator_Components(t *testing.T) { + tests := []struct { + name string + dir string + fluxComponents []string + expectedComponents []string + }{ + { + name: "test kustomization.yaml with components and Flux Kustomization without components", + dir: "components", + fluxComponents: []string{}, + expectedComponents: []string{"componentA"}, + }, + { + name: "test kustomization.yaml without components and Flux Kustomization with components", + dir: "zero-components", + fluxComponents: []string{"componentB", "componentC"}, + expectedComponents: []string{"componentB", "componentC"}, + }, + { + name: "test kustomization.yaml with components and Flux Kustomization with components", + dir: "components", + fluxComponents: []string{"componentB", "componentC"}, + expectedComponents: []string{"componentA", "componentB", "componentC"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewWithT(t) + tmpDir := t.TempDir() + g.Expect(copy.Copy("./testdata/components", tmpDir)).To(Succeed()) + ks := v1beta2.Kustomization{ + Spec: v1beta2.KustomizationSpec{ + Components: tt.fluxComponents, + }, + } + 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.Components).Should(Equal(tt.expectedComponents)) + }) + } +} diff --git a/internal/generator/testdata/components/components/configmap.yaml b/internal/generator/testdata/components/components/configmap.yaml new file mode 100644 index 000000000..7cb895340 --- /dev/null +++ b/internal/generator/testdata/components/components/configmap.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm + namespace: foo +data: + key: value diff --git a/internal/generator/testdata/components/components/kustomization.yaml b/internal/generator/testdata/components/components/kustomization.yaml new file mode 100644 index 000000000..a85800f56 --- /dev/null +++ b/internal/generator/testdata/components/components/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - configmap.yaml +components: + - componentA diff --git a/internal/generator/testdata/components/zero-components/configmap.yaml b/internal/generator/testdata/components/zero-components/configmap.yaml new file mode 100644 index 000000000..7cb895340 --- /dev/null +++ b/internal/generator/testdata/components/zero-components/configmap.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm + namespace: foo +data: + key: value diff --git a/internal/generator/testdata/components/zero-components/kustomization.yaml b/internal/generator/testdata/components/zero-components/kustomization.yaml new file mode 100644 index 000000000..bbfab0eaf --- /dev/null +++ b/internal/generator/testdata/components/zero-components/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - configmap.yaml