Skip to content

Commit

Permalink
Add support for Kustomize components
Browse files Browse the repository at this point in the history
Fix #753

Signed-off-by: Kristian Klausen <kristian@klausen.dk>
  • Loading branch information
klausenbusk committed Nov 15, 2022
1 parent 1e8dc84 commit 9cd7310
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 0 deletions.
4 changes: 4 additions & 0 deletions api/v1beta2/kustomization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ type KustomizationSpec struct {
// +kubebuilder:validation:Enum=none;client;server
// +optional
Validation string `json:"validation,omitempty"`

// Components specifies relative paths to specifications of other Components
// +optional
Components []string `json:"components,omitempty"`
}

// Decryption defines how decryption is handled for Kubernetes manifests.
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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
items:
type: string
type: array
decryption:
description: Decrypt Kubernetes secrets before applying them on the
cluster.
Expand Down
26 changes: 26 additions & 0 deletions docs/spec/v1beta2/kustomization.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ offering support for the following Kustomize directives:
- [namespace](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/namespace/)
- [patches](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/patches/)
- [images](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/images/)
- [components](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/components/)

### Target namespace

Expand Down Expand Up @@ -654,6 +655,31 @@ spec:
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
```

### Components

To add [Kustomize `components` entries](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/components/)
to the configuration, and use reusable pieces of configuration logic that can
be included from multiple overlays, `spec.components` can be defined:

```yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: podinfo
namespace: flux-system
spec:
# ...omitted for brevity
components:
- ingress
- tls
```

**Note:** The component paths must be local and relative.

**Warning:** Components are a alpha feature in Kustomize and are therefore
considered experimental in Flux. No guarantees are provided and the feature may
be modified in backwards incompatible ways or removed without warning.

## Variable substitution

With `spec.postBuild.substitute` you can provide a map of key/value pairs holding the
Expand Down
25 changes: 25 additions & 0 deletions internal/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ func (kg *KustomizeGenerator) WriteFile(dirPath string) (string, error) {
})
}

for _, m := range kg.kustomization.Spec.Components {
if !isLocalRelativePath(m) {
return "", fmt.Errorf("component path '%s' must be local and relative", m)
}
kus.Components = append(kus.Components, m)
}

for _, m := range kg.kustomization.Spec.PatchesStrategicMerge {
kus.PatchesStrategicMerge = append(kus.PatchesStrategicMerge, kustypes.PatchStrategicMerge(m.Raw))
}
Expand Down Expand Up @@ -234,3 +241,21 @@ func adaptSelector(selector *kustomize.Selector) (output *kustypes.Selector) {
}
return
}

func isLocalRelativePath(path string) bool {
// From: https://github.com/kubernetes-sigs/kustomize/blob/84bd402cc0662c5df3f109c4f80c22611243c5f9/api/internal/git/repospec.go#L231-L239
// with "file://" removed/
for _, p := range []string{
// Order matters here.
"git::", "gh:", "ssh://", "https://", "http://",
"git@", "github.com:", "github.com/"} {
if len(p) < len(path) && strings.ToLower(path[:len(p)]) == p {
return false
}
}

if filepath.IsAbs(path) || filepath.IsAbs(strings.TrimPrefix(strings.ToLower(path), "file://")) {
return false
}
return true
}
49 changes: 49 additions & 0 deletions internal/generator/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
components:
- componentA
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml

0 comments on commit 9cd7310

Please sign in to comment.