Skip to content

Commit

Permalink
feat(directives): support writing kustomize output to multiple files
Browse files Browse the repository at this point in the history
Signed-off-by: Hidde Beydals <[email protected]>
  • Loading branch information
hiddeco committed Oct 2, 2024
1 parent 34e599d commit e646bc1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 9 deletions.
48 changes: 39 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,50 @@ 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),
)

Check warning on line 98 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L95-L98

Added lines #L95 - L98 were not covered by tests
}
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

Check warning on line 106 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L106

Added line #L106 was not covered by tests
}
b, err := rm.AsYaml()
if err != nil {
return err

Check warning on line 110 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L110

Added line #L110 was not covered by tests
}
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

Check warning on line 117 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L117

Added line #L117 was not covered by tests
}
for _, r := range rm.Resources() {
kind, name := r.GetKind(), 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())

Check warning on line 122 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L122

Added line #L122 was not covered by tests
}
path := filepath.Join(outPath, fmt.Sprintf("%s-%s.yaml", strings.ToLower(kind), strings.ToLower(name)))
b, err := r.AsYAML()
if err != nil {
return fmt.Errorf("failed to convert %q to YAML: %w", r.CurId(), err)

Check warning on line 127 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L127

Added line #L127 was not covered by tests
}
if err = os.WriteFile(path, b, 0o600); err != nil {
return err

Check warning on line 130 in internal/directives/kustomize_builder.go

View check run for this annotation

Codecov / codecov/patch

internal/directives/kustomize_builder.go#L130

Added line #L130 was not covered by tests
}
}
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 e646bc1

Please sign in to comment.