Skip to content

Commit

Permalink
Merge pull request #102 from puzzle/support-multiple-kustomize-versions
Browse files Browse the repository at this point in the history
feat: Support Multiple Kustomize Versions
  • Loading branch information
ioboi authored Apr 8, 2024
2 parents f79f33b + 7a8b16d commit 1f1136a
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 58 deletions.
4 changes: 4 additions & 0 deletions ci/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,14 @@ func buildAndPushDevImage(ctx context.Context, golang *dagger.Container, g *Goff
goffBin := goffGitlab.File("/app/goff")
glabBin := goffGitlab.File("/go/bin/glab")

kustomizeContainer := daggerClient.Container().
From("registry.k8s.io/kustomize/kustomize:v5.4.1")

goffContainer := daggerClient.Container().
From("docker.io/alpine:3.18").
WithExec([]string{"addgroup", "-g", "1001", "goff"}).
WithExec([]string{"adduser", "-D", "-u", "1001", "-G", "goff", "goff"}).
WithFile("/usr/local/bin/kustomize", kustomizeContainer.File("/app/kustomize")).
WithFile("/bin/goff", goffBin).
WithFile("/bin/glab", glabBin).
WithExec([]string{"apk", "add", "git", "helm"})
Expand Down
12 changes: 11 additions & 1 deletion ci/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ func testMainBranch(ctx context.Context, t *testing.T, daggerClient *dagger.Clie

_, err = daggerClient.Container().From(gpMain.getImageFullUrl("goff")).WithExec([]string{"--help"}).Sync(ctx)
assert.Nil(t, err, "container '%s' should exists and be functional", gpMain.getImageFullUrl("goff"))

_, err = daggerClient.Container().From(gpMain.getImageFullUrl("goff")).WithExec([]string{"kustomize", "--version"}).Sync(ctx)
assert.Nil(t, err, "container '%s' should exists and be functional", gpMain.getImageFullUrl("goff"))

// Test custom `kustomize`
goffContainer := daggerClient.Container().From(gpMain.getImageFullUrl("goff"))
kustomize4 := daggerClient.Container().
From("registry.k8s.io/kustomize/kustomize:v4.5.7")
goffContainer = goffContainer.WithFile("/opt/kustomize4", kustomize4.File("/app/kustomize"))
_, err = goffContainer.WithExec([]string{"kustomize", "--binary=/opt/kustomize4", "--version"}).Sync(ctx)
assert.Nil(t, err, "container '%s' should exists and be functional", gpMain.getImageFullUrl("goff"))
}

func testNonReleaseTag(ctx context.Context, t *testing.T, daggerClient *dagger.Client) {
Expand Down Expand Up @@ -136,5 +147,4 @@ func testReleaseTag(ctx context.Context, t *testing.T, daggerClient *dagger.Clie

_, err = daggerClient.Container().From(gprelease.getImageFullUrl("goff")).WithExec([]string{"--help"}).Sync(ctx)
assert.Nil(t, err, "container with name '%s' should exists", gprelease.getImageFullUrl("goff"))

}
39 changes: 31 additions & 8 deletions cmd/kustomize.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,55 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"fmt"
"os/exec"

"github.com/puzzle/goff/cmd/kustomize"
"github.com/puzzle/goff/kustomize/kustomizationgraph"

"github.com/spf13/cobra"
)

var outputDotDir *string
var version *bool
var binary *string

// kustomizeCmd represents the kustomize command
var kustomizeCmd = &cobra.Command{
Use: "kustomize [rootDir]",
Short: "Generate a DOT file to visualize the dependencies between your kustomize components",
Args: cobra.ExactArgs(1),
Long: `Generate a DOT file to visualize the dependencies between your kustomize components`,
Run: func(cmd *cobra.Command, args []string) {
Args: func(cmd *cobra.Command, args []string) error {
if *version {
return nil
}
return cobra.ExactArgs(1)(cmd, args)
},
Long: `Generate a DOT file to visualize the dependencies between your kustomize components`,
RunE: func(cmd *cobra.Command, args []string) error {
kustomizeCmd := "kustomize"
if *binary != "" {
kustomizeCmd = *binary
}

if *version {
kustomizeCmd := exec.CommandContext(cmd.Context(), kustomizeCmd, "version")
kustomizeCmd.Stdout = cmd.OutOrStdout()
kustomizeCmd.Stderr = cmd.OutOrStderr()
if err := kustomizeCmd.Run(); err != nil {
return fmt.Errorf("unable to run kustomize: %w", err)
}
return nil
}

kustomizationgraph.Graph(args[0], *outputDotDir)
return nil
},
}

func init() {
kustomizeCmd.AddCommand(kustomize.KustomizeBuildCmd)
rootCmd.AddCommand(kustomizeCmd)

binary = kustomizeCmd.Flags().String("binary", "", "Alternative kustomize binary")
version = kustomizeCmd.Flags().BoolP("version", "v", false, "Display version of kustomize")
outputDotDir = kustomizeCmd.Flags().StringP("output-dir", "o", ".", "Output directory")
}
6 changes: 5 additions & 1 deletion cmd/kustomize/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ var KustomizeBuildCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Long: `Build all kustomize file within parent directory`,
RunE: func(cmd *cobra.Command, args []string) error {
return kustomize.BuildAll(args[0], *outputBuildDir)
kustomizeCommand, err := cmd.Flags().GetString("binary")
if err != nil {
return err
}
return kustomize.BuildAll(kustomizeCommand, args[0], *outputBuildDir)
},
}

Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ require (
github.com/argoproj/argo-cd/v2 v2.10.5
github.com/ghodss/yaml v1.0.0
github.com/go-godo/godo v2.0.9+incompatible
sigs.k8s.io/kustomize/kustomize/v4 v4.5.7
)

require (
Expand Down Expand Up @@ -203,7 +202,7 @@ require (
k8s.io/kubectl v0.26.4 // indirect
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.12.1
sigs.k8s.io/kustomize/api v0.12.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Expand Down
15 changes: 0 additions & 15 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -600,8 +600,6 @@ cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcP
code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
dagger.io/dagger v0.9.8 h1:f8bzcI9pHoWsnBlm/d+PXneXINSUEAQ5K3/Kc/PuJYw=
dagger.io/dagger v0.9.8/go.mod h1:aq9P87v4apEOXKPXzn35uK+by5dUplSU5ZeXm+E8Sgw=
dagger.io/dagger v0.9.10 h1:pwFPbTL0yEGmFCkoEALXxSE6s5jfaRGz6gi6RYDBalI=
dagger.io/dagger v0.9.10/go.mod h1:aq9P87v4apEOXKPXzn35uK+by5dUplSU5ZeXm+E8Sgw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
Expand Down Expand Up @@ -660,10 +658,6 @@ github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0I
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/argoproj/argo-cd/v2 v2.10.0 h1:PEq3UVjXiOuDViJdRS+g+VMSKLqRnDN8Nj65YXmiUk8=
github.com/argoproj/argo-cd/v2 v2.10.0/go.mod h1:SK1uGZ9xWVzxuyg079MaO6+hz/Oz9wSDkGyT0gEkYSs=
github.com/argoproj/argo-cd/v2 v2.10.1 h1:VD06GPeoq14Bo7IfiW+EKim3T1C9xaMElVrEtw+zll0=
github.com/argoproj/argo-cd/v2 v2.10.1/go.mod h1:SK1uGZ9xWVzxuyg079MaO6+hz/Oz9wSDkGyT0gEkYSs=
github.com/argoproj/argo-cd/v2 v2.10.5 h1:2YSZPjNY3KyE1kme2U54uAAicEn/4zyQ3aAkqkyW8UA=
github.com/argoproj/argo-cd/v2 v2.10.5/go.mod h1:nujAuswdQvB6yWI8HubQjfUiLdiIlKlG0ihx2Ht1D28=
github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc h1:Fv94Mi2WvtvPkEH5WoWC3iy/VoQRLeSsE0hyg0n2UkY=
Expand All @@ -676,8 +670,6 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E=
github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs=
github.com/aws/aws-sdk-go v1.44.290/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.317 h1:+8XWrLmGMwPPXSRSLPzhgcGnzJ2mYkgkrcB9C/GnSOU=
github.com/aws/aws-sdk-go v1.44.317/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.50.8 h1:gY0WoOW+/Wz6XmYSgDH9ge3wnAevYDSQWPxxJvqAkP4=
github.com/aws/aws-sdk-go v1.50.8/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
Expand Down Expand Up @@ -885,8 +877,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
Expand Down Expand Up @@ -2035,7 +2025,6 @@ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
Expand Down Expand Up @@ -2145,17 +2134,13 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA=
sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
sigs.k8s.io/controller-runtime v0.14.7 h1:Vrnm2vk9ZFlRkXATHz0W0wXcqNl7kPat8q2JyxVy0Q8=
sigs.k8s.io/controller-runtime v0.14.7/go.mod h1:ErTs3SJCOujNUnTz4AS+uh8hp6DHMo1gj6fFndJT1X8=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM=
sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s=
sigs.k8s.io/kustomize/kustomize/v4 v4.5.7 h1:cDW6AVMl6t/SLuQaezMET8hgnadZGIAr8tUrxFVOrpg=
sigs.k8s.io/kustomize/kustomize/v4 v4.5.7/go.mod h1:VSNKEH9D9d9bLiWEGbS6Xbg/Ih0tgQalmPvntzRxZ/Q=
sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk=
sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
Expand Down
63 changes: 32 additions & 31 deletions kustomize/kustomize.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,64 @@
package kustomize

import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/puzzle/goff/util"

"github.com/puzzle/goff/kustomize/kustomizationfile"

"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kustomize/v4/commands/build"
"github.com/puzzle/goff/util"
)

func BuildAll(sourceDir, targetDir string) error {
func BuildAll(kustomizeCommand, sourceDir, targetDir string) error {

dirs, err := kustomizationfile.New().GetDirectories(sourceDir)
if err != nil {
return err
}

fSys := filesys.MakeFsOnDisk()
absoluteSourceDirPath, _ := filepath.Abs(sourceDir)

for _, dir := range dirs {
absoluteKustomizationPath, _ := filepath.Abs(dir)

buffy := new(bytes.Buffer)
cmd := build.NewCmdBuild(fSys, build.MakeHelp("foo", "bar"), buffy)
if err := cmd.RunE(cmd, []string{dir}); err != nil {
return err
var stdout strings.Builder

// TODO: Make customizable
cmd := exec.Command(kustomizeCommand, "build", absoluteKustomizationPath)
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
return fmt.Errorf("error running kustomize: %w", err)
}

if buffy.Len() == 0 {
if stdout.Len() == 0 {
// TODO: May log warning that there was no output for the directory.
continue
}

ad, _ := filepath.Abs(dir)
asd, _ := filepath.Abs(sourceDir)
base := strings.TrimPrefix(ad, asd)
outPath := filepath.Join(targetDir, base)
// Remove the source directory to the found directory of the `Kustomization`.
//
// Example: If source is `/dir/to/kustomization` and the found kustomization is `/dir/to/kustomization/overlays/x`,
// the basePath will be `overlays/x`.
basePath := strings.TrimPrefix(absoluteKustomizationPath, absoluteSourceDirPath)
outputPath := filepath.Join(targetDir, basePath)
log.Println(absoluteKustomizationPath, " -> ", outputPath)

err = os.MkdirAll(outPath, 0777)
if err != nil {
return err
if err := os.MkdirAll(outputPath, 0777); err != nil {
return fmt.Errorf("unable to create target direcories: %w", err)
}

outFiles := bytes.Split(buffy.Bytes(), []byte("---"))

for _, f := range outFiles {
content := string(f)
fileName, err := util.FileNameFromManifest(content)
manifests := strings.Split(stdout.String(), "---")
for _, manifest := range manifests {
fileName, err := util.FileNameFromManifest(manifest)
if err != nil {
return err
return fmt.Errorf("cannot get name of manifest: %w", err)
}

outFile := filepath.Join(outPath, fileName)

err = os.WriteFile(outFile, f, 0777)
if err != nil {
return err
if err := os.WriteFile(filepath.Join(outputPath, fileName), []byte(manifest), 0777); err != nil {
return fmt.Errorf("unable to write manifest to file: %w", err)
}
}
}
Expand Down

0 comments on commit 1f1136a

Please sign in to comment.