From ef4401e8ed2ed11a08a032ee41724ca2be819b5a Mon Sep 17 00:00:00 2001 From: Jabar Asadi Date: Tue, 10 Oct 2023 13:35:01 +0200 Subject: [PATCH] feat: add kustomization --- apptests/kustomize/kustomize.go | 86 +++++++++++++++++++ apptests/kustomize/kustomize_test.go | 41 +++++++++ .../kustomize/testdata/kustomization.yaml | 4 + apptests/kustomize/testdata/sample.yaml | 10 +++ 4 files changed, 141 insertions(+) create mode 100644 apptests/kustomize/kustomize.go create mode 100644 apptests/kustomize/kustomize_test.go create mode 100644 apptests/kustomize/testdata/kustomization.yaml create mode 100644 apptests/kustomize/testdata/sample.yaml diff --git a/apptests/kustomize/kustomize.go b/apptests/kustomize/kustomize.go new file mode 100644 index 000000000..a49ef3e9b --- /dev/null +++ b/apptests/kustomize/kustomize.go @@ -0,0 +1,86 @@ +package kustomize + +import ( + "os" + + "github.com/drone/envsubst" + "sigs.k8s.io/kustomize/api/krusty" + "sigs.k8s.io/kustomize/api/resmap" + "sigs.k8s.io/kustomize/api/resource" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +type Kustomize struct { + directory string // The directory where the kustomization file is located + substitutes map[string]string // The map of environment variables to substitute in the resources + resources resmap.ResMap // The map of resources generated by the kustomization process +} + +// New creates a new Kustomize instance with the given directory and substitutes. +func New(dir string, subs map[string]string) *Kustomize { + return &Kustomize{ + directory: dir, + substitutes: subs, + resources: resmap.New(), + } +} + +// Build runs the kustomization process on the directory and substitutes the +// environment variables in the resources. +func (k *Kustomize) Build() error { + for k, v := range k.substitutes { + os.Setenv(k, v) + } + + opts := krusty.MakeDefaultOptions() + opts.Reorder = krusty.ReorderOptionLegacy + + kustomizer := krusty.MakeKustomizer(opts) + + // Run the kustomizer on the directory and get the resource map + resourceMap, err := kustomizer.Run(filesys.MakeFsOnDisk(), k.directory) + if err != nil { + return err + } + + for _, r := range resourceMap.Resources() { + yaml, err := r.AsYAML() + if err != nil { + return err + } + + out, err := envsubst.EvalEnv(string(yaml)) + if err != nil { + return err + } + + // Convert the output string to a resource and append it to the resources map + res, err := newResourceFromString(out) + if err != nil { + return err + } + k.resources.Append(res) + } + + return nil +} + +// Output returns the YAML representation of the resources map as a string. +func (k *Kustomize) Output() (string, error) { + yml, err := k.resources.AsYaml() + if err != nil { + return "", err + } + return string(yml), nil +} + +// newResourceFromString converts a given string to a Kubernetes resource. +func newResourceFromString(str string) (*resource.Resource, error) { + fc := resmap.NewFactory(&resource.Factory{}) + resource, err := fc.NewResMapFromBytes([]byte(str)) + if err != nil { + return nil, err + } + + return resource.Resources()[0], nil +} diff --git a/apptests/kustomize/kustomize_test.go b/apptests/kustomize/kustomize_test.go new file mode 100644 index 000000000..378d70d8d --- /dev/null +++ b/apptests/kustomize/kustomize_test.go @@ -0,0 +1,41 @@ +package kustomize + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBuild(t *testing.T) { + wd, err := os.Getwd() + assert.NoError(t, err) + + builder := New( + filepath.Join(wd, "testdata"), + map[string]string{ + "name": "test-name", + "namespace": "kommander", + }, + ) + err = builder.Build() + assert.NoError(t, err) + + output, err := builder.Output() + assert.NoError(t, err) + + // define the expected output + expected := `apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: test-name + namespace: kommander +spec: + interval: 10m + timeout: 1m + url: https://charts.bitnami.com/bitnami/ +` + + assert.Equal(t, output, expected) +} diff --git a/apptests/kustomize/testdata/kustomization.yaml b/apptests/kustomize/testdata/kustomization.yaml new file mode 100644 index 000000000..12d16695a --- /dev/null +++ b/apptests/kustomize/testdata/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- sample.yaml diff --git a/apptests/kustomize/testdata/sample.yaml b/apptests/kustomize/testdata/sample.yaml new file mode 100644 index 000000000..966b54da6 --- /dev/null +++ b/apptests/kustomize/testdata/sample.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: ${name} + namespace: ${namespace} +spec: + interval: 10m + timeout: 1m + url: "${helmMirrorURL:=https://charts.bitnami.com/bitnami/}"