The problem I am trying to solve is that I was trying to find another way to use kustomize build within my golang applications

One way to do it is install kustomize and then leverage the os/exec package to execute the kustomize CLI command from within your golang application. I feel this method is a bit hacky and less flexible in the way errors are handled.

Since kustomize is built using golang, why not used the native apis to run kustomize. Kustomize has this krusty API that you can create your own kustomizer. Using the native apis will give me better error handling and integration with leveraging the other cool features that golang has.

I have a Github repository that contains example of using this API. In this example. I do the following

  • Look for folders that have an overlays folder
  • Grab overlays’s subdirectories
  • Validate these subdirectories’ kustomization.yaml is valid

Here is a snippet of the code itself.

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main

import (
 "fmt"
 "os"
 "path/filepath"

 "sigs.k8s.io/kustomize/api/krusty"
 kustypes "sigs.k8s.io/kustomize/api/types"
 "sigs.k8s.io/kustomize/kyaml/filesys"
)

// validateOverlaysFolders checks if the overlay folders are able to run kustomize build
func validateOverlaysFolders(fs filesys.FileSystem, kustomizationDir string) {
 buildOptions := &krusty.Options{
  LoadRestrictions: kustypes.LoadRestrictionsNone,
  PluginConfig:     kustypes.DisabledPluginConfig(),
 }

 k := krusty.MakeKustomizer(buildOptions)
 m, err := k.Run(fs, kustomizationDir)

 if err != nil {
  panic(fmt.Errorf("error with kustomizer.Run: %v", err))
 }

 _, err = m.AsYaml()

 if err != nil {
  panic(fmt.Errorf("error with coverting kustomization output to yaml: %v", err))
 }
}

func main() {
 rootDir := "workloads"
 pattern := "overlays"

 fs := filesys.MakeFsOnDisk()

 folders, err := findFoldersWithPattern(rootDir, pattern)
 if err != nil {
  panic(fmt.Errorf("error finding folders: %v", err))
 }

 for _, folder := range folders {
  parentFolder := filepath.Dir(folder)
  fmt.Printf("Folder: %s\nParent: %s\n\n", folder, parentFolder)
  childFolders,_ := getSubDirectories(folder)

  for _, childFolder := range childFolders {
   validateOverlaysFolders(fs, childFolder)
  }
 }

}

Line 19 - 30 showcase creating a kustomizer where you can read and validate kustomization.yaml file

Nothing to fancy but you can get fancy like Flux Kustomize Controller with their own kubernetes operator listening for kustomize custom resource definitions

Learnings Link to heading

Using the krusty api showed me that extending kustomize functionality is possible and beneficial for Platform teams who manage bulk kustomization files to add their own custom validation and manipulation logic to ensure certain file standards.