add kustomizationVisitor type and use it when kustomization is enabled

This commit is contained in:
Jingfang Liu 2018-12-12 09:41:42 -08:00
parent 5604a15024
commit 26c07715c7
3 changed files with 63 additions and 8 deletions

View File

@ -35,12 +35,16 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps:go_default_library",
"//staging/src/k8s.io/client-go/discovery:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
"//vendor/golang.org/x/text/transform:go_default_library",
"//vendor/sigs.k8s.io/kustomize/pkg/commands/build:go_default_library",
"//vendor/sigs.k8s.io/kustomize/pkg/constants:go_default_library",
"//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
],
)

View File

@ -130,8 +130,9 @@ func IsUsageError(err error) bool {
}
type FilenameOptions struct {
Filenames []string
Recursive bool
Filenames []string
Recursive bool
EnableKustomization bool
}
type resourceTuple struct {
@ -197,6 +198,7 @@ func (b *Builder) AddError(err error) *Builder {
// recognized will be ignored (but logged at V(2)).
func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *FilenameOptions) *Builder {
recursive := filenameOptions.Recursive
enableKustomization := filenameOptions.EnableKustomization
paths := filenameOptions.Filenames
for _, s := range paths {
switch {
@ -213,7 +215,7 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename
if !recursive {
b.singleItemImplied = true
}
b.Path(recursive, s)
b.Path(recursive, enableKustomization, s)
}
}
@ -332,7 +334,7 @@ func (b *Builder) Stream(r io.Reader, name string) *Builder {
// FileVisitor is streaming the content to a StreamVisitor. If ContinueOnError() is set
// prior to this method being called, objects on the path that are unrecognized will be
// ignored (but logged at V(2)).
func (b *Builder) Path(recursive bool, paths ...string) *Builder {
func (b *Builder) Path(recursive, enableKustomization bool, paths ...string) *Builder {
for _, p := range paths {
_, err := os.Stat(p)
if os.IsNotExist(err) {
@ -344,7 +346,7 @@ func (b *Builder) Path(recursive bool, paths ...string) *Builder {
continue
}
visitors, err := ExpandPathsToFileVisitors(b.mapper, p, recursive, FileExtensions, b.schema)
visitors, err := ExpandPathsToFileVisitors(b.mapper, p, recursive, enableKustomization, FileExtensions, b.schema)
if err != nil {
b.errs = append(b.errs, fmt.Errorf("error reading %q: %v", p, err))
}

View File

@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
@ -38,6 +39,10 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/kustomize/k8sdeps"
"sigs.k8s.io/kustomize/pkg/commands/build"
"sigs.k8s.io/kustomize/pkg/constants"
"sigs.k8s.io/kustomize/pkg/fs"
)
const (
@ -446,13 +451,16 @@ func FileVisitorForSTDIN(mapper *mapper, schema ContentValidator) Visitor {
// ExpandPathsToFileVisitors will return a slice of FileVisitors that will handle files from the provided path.
// After FileVisitors open the files, they will pass an io.Reader to a StreamVisitor to do the reading. (stdin
// is also taken care of). Paths argument also accepts a single file, and will return a single visitor
func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, extensions []string, schema ContentValidator) ([]Visitor, error) {
func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, enableKustomize bool, extensions []string, schema ContentValidator) ([]Visitor, error) {
var visitors []Visitor
err := filepath.Walk(paths, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
if enableKustomize && isKustomizationDir(path) {
visitors = append(visitors, NewKustomizationVisitor(mapper, path, schema))
return filepath.SkipDir
}
if fi.IsDir() {
if path != paths && !recursive {
return filepath.SkipDir
@ -463,7 +471,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
if path != paths && ignoreFile(path, extensions) {
return nil
}
if enableKustomize && filepath.Base(path) == constants.KustomizationFileName {
visitors = append(visitors, NewKustomizationVisitor(mapper, filepath.Dir(path), schema))
return nil
}
visitor := &FileVisitor{
Path: path,
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
@ -479,6 +490,13 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
return visitors, nil
}
func isKustomizationDir(path string) bool {
if _, err := os.Stat(filepath.Join(path, constants.KustomizationFileName)); err == nil {
return true
}
return false
}
// FileVisitor is wrapping around a StreamVisitor, to handle open/close files
type FileVisitor struct {
Path string
@ -507,6 +525,37 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error {
return v.StreamVisitor.Visit(fn)
}
// KustomizationVisitor prorvides the output of kustomization build
type KustomizationVisitor struct {
Path string
*StreamVisitor
}
// Visit in a KustomizationVisitor build the kustomization output
func (v *KustomizationVisitor) Visit(fn VisitorFunc) error {
fSys := fs.MakeRealFS()
f := k8sdeps.NewFactory()
var out bytes.Buffer
cmd := build.NewCmdBuild(&out, fSys, f.ResmapF, f.TransformerF)
cmd.SetArgs([]string{v.Path})
// we want to silence usage, error output, and any future output from cobra
// we will get error output as a golang error from execute
cmd.SetOutput(ioutil.Discard)
_, err := cmd.ExecuteC()
if err != nil {
return err
}
v.StreamVisitor.Reader = bytes.NewReader(out.Bytes())
return v.StreamVisitor.Visit(fn)
}
func NewKustomizationVisitor(mapper *mapper, path string, schema ContentValidator) *KustomizationVisitor {
return &KustomizationVisitor{
Path: path,
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
}
}
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
// visited once.
// TODO: depends on objects being in JSON format before being passed to decode - need to implement