Skip to content

Commit

Permalink
chore(backport release-0.9): feat(directives): support writing kustom…
Browse files Browse the repository at this point in the history
…ize output to multiple files (#2632)

Co-authored-by: Hidde Beydals <[email protected]>
Co-authored-by: Kent Rancourt <[email protected]>
  • Loading branch information
3 people authored Oct 2, 2024
1 parent f58e8d7 commit d09859e
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 9 deletions.
55 changes: 46 additions & 9 deletions internal/directives/kustomize_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"

securejoin "github.com/cyphar/filepath-securejoin"
Expand Down Expand Up @@ -88,21 +89,57 @@ func (k *kustomizeBuilder) runPromotionStep(
if err != nil {
return PromotionStepResult{Status: PromotionStatusFailure}, err
}
if err = os.MkdirAll(filepath.Dir(outPath), 0o700); err != nil {
return PromotionStepResult{Status: PromotionStatusFailure}, err
}

// Write the built manifests to the output path.
b, err := rm.AsYaml()
if err != nil {
return PromotionStepResult{Status: PromotionStatusFailure}, err
}
if err = os.WriteFile(outPath, b, 0o600); err != nil {
return PromotionStepResult{Status: PromotionStatusFailure}, err
if err := k.writeResult(rm, outPath); err != nil {
return PromotionStepResult{Status: PromotionStatusFailure}, fmt.Errorf(
"failed to write built manifests to %q: %w", cfg.OutPath,
sanitizePathError(err, stepCtx.WorkDir),
)
}
return PromotionStepResult{Status: PromotionStatusSuccess}, nil
}

func (k *kustomizeBuilder) writeResult(rm resmap.ResMap, outPath string) error {
if ext := filepath.Ext(outPath); ext == ".yaml" || ext == ".yml" {
if err := os.MkdirAll(filepath.Dir(outPath), 0o700); err != nil {
return err
}
b, err := rm.AsYaml()
if err != nil {
return err
}
return os.WriteFile(outPath, b, 0o600)
}

// If the output path is a directory, write each manifest to a separate file.
if err := os.MkdirAll(outPath, 0o700); err != nil {
return err
}
for _, r := range rm.Resources() {
kind, namespace, name := r.GetKind(), r.GetNamespace(), r.GetName()
if kind == "" || name == "" {
return fmt.Errorf("resource kind and name of %q must be non-empty to write to a directory", r.CurId())
}

fileName := fmt.Sprintf("%s-%s", kind, name)
if namespace != "" {
fileName = fmt.Sprintf("%s-%s", namespace, fileName)
}

b, err := r.AsYAML()
if err != nil {
return fmt.Errorf("failed to convert %q to YAML: %w", r.CurId(), err)
}

path := filepath.Join(outPath, fmt.Sprintf("%s.yaml", strings.ToLower(fileName)))
if err = os.WriteFile(path, b, 0o600); err != nil {
return err
}
}
return nil
}

// kustomizeBuild builds the manifests in the given directory using Kustomize.
func kustomizeBuild(fs filesys.FileSystem, path string) (_ resmap.ResMap, err error) {
kustomizeRenderMutex.Lock()
Expand Down
30 changes: 30 additions & 0 deletions internal/directives/kustomize_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,36 @@ metadata:
assert.Contains(t, string(b), "test-deployment")
},
},
{
name: "successful build with output directory",
setupFiles: func(t *testing.T, dir string) {
require.NoError(t, os.WriteFile(filepath.Join(dir, "kustomization.yaml"), []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
`), 0o600))
require.NoError(t, os.WriteFile(filepath.Join(dir, "deployment.yaml"), []byte(`---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
`), 0o600))
},
config: KustomizeBuildConfig{
Path: ".",
OutPath: "output/",
},
assertions: func(t *testing.T, dir string, result PromotionStepResult, err error) {
require.NoError(t, err)
assert.Equal(t, PromotionStepResult{Status: PromotionStatusSuccess}, result)

assert.DirExists(t, filepath.Join(dir, "output"))
b, err := os.ReadFile(filepath.Join(dir, "output", "deployment-test-deployment.yaml"))
require.NoError(t, err)
assert.Contains(t, string(b), "test-deployment")
},
},
{
name: "kustomization file not found",
setupFiles: func(*testing.T, string) {},
Expand Down

0 comments on commit d09859e

Please sign in to comment.