mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
282 lines
9.6 KiB
Diff
Executable File
282 lines
9.6 KiB
Diff
Executable File
commit 1b893558aa83ac6491e5ba416b493170a9045fec
|
|
Author: Jingfang Liu <jingfangliu@google.com>
|
|
Date: Mon Nov 12 10:26:12 2018 -0800
|
|
|
|
last change
|
|
|
|
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml
|
|
new file mode 100644
|
|
index 0000000000..0008853094
|
|
--- /dev/null
|
|
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml
|
|
@@ -0,0 +1,8 @@
|
|
+
|
|
+apiVersion: v1
|
|
+kind: ConfigMap
|
|
+metadata:
|
|
+ name: the-map
|
|
+data:
|
|
+ altGreeting: "Good Morning!"
|
|
+ enableRisky: "false"
|
|
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml
|
|
new file mode 100644
|
|
index 0000000000..6e79409080
|
|
--- /dev/null
|
|
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml
|
|
@@ -0,0 +1,30 @@
|
|
+apiVersion: apps/v1
|
|
+kind: Deployment
|
|
+metadata:
|
|
+ name: the-deployment
|
|
+spec:
|
|
+ replicas: 3
|
|
+ template:
|
|
+ metadata:
|
|
+ labels:
|
|
+ deployment: hello
|
|
+ spec:
|
|
+ containers:
|
|
+ - name: the-container
|
|
+ image: monopole/hello:1
|
|
+ command: ["/hello",
|
|
+ "--port=8080",
|
|
+ "--enableRiskyFeature=$(ENABLE_RISKY)"]
|
|
+ ports:
|
|
+ - containerPort: 8080
|
|
+ env:
|
|
+ - name: ALT_GREETING
|
|
+ valueFrom:
|
|
+ configMapKeyRef:
|
|
+ name: the-map
|
|
+ key: altGreeting
|
|
+ - name: ENABLE_RISKY
|
|
+ valueFrom:
|
|
+ configMapKeyRef:
|
|
+ name: the-map
|
|
+ key: enableRisky
|
|
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml
|
|
new file mode 100644
|
|
index 0000000000..6e1e3202d5
|
|
--- /dev/null
|
|
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml
|
|
@@ -0,0 +1,5 @@
|
|
+nameprefix: test-
|
|
+ resources:
|
|
+- deployment.yaml
|
|
+- service.yaml
|
|
+- configMap.yaml
|
|
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml
|
|
new file mode 100644
|
|
index 0000000000..2942cdb7df
|
|
--- /dev/null
|
|
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml
|
|
@@ -0,0 +1,13 @@
|
|
+kind: Service
|
|
+apiVersion: v1
|
|
+metadata:
|
|
+ name: the-service
|
|
+spec:
|
|
+ selector:
|
|
+ deployment: hello
|
|
+ type: LoadBalancer
|
|
+ ports:
|
|
+ - protocol: TCP
|
|
+ port: 8666
|
|
+ targetPort: 8080
|
|
+
|
|
\ No newline at end of file
|
|
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
|
index 22b34de008..b91d1c0130 100644
|
|
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
|
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
|
@@ -35,12 +35,15 @@ 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/fs:go_default_library",
|
|
],
|
|
)
|
|
|
|
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
|
index 7fd526b33c..801f13f772 100644
|
|
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
|
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
|
@@ -465,27 +465,48 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) {
|
|
}
|
|
|
|
func TestDirectoryBuilder(t *testing.T) {
|
|
- b := newDefaultBuilder().
|
|
- FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../artifacts/guestbook"}}).
|
|
- NamespaceParam("test").DefaultNamespace()
|
|
+ tests := []struct {
|
|
+ directories []string
|
|
+ singleItem bool
|
|
+ number int
|
|
+ expectedNames []string
|
|
+ }{
|
|
+ {[]string{"../../../artifacts/guestbook"}, false, 3, []string{"redis-master"}},
|
|
+ {[]string{"../../../artifacts/kustomization"}, true, 3, []string{"test-the-deployment"}},
|
|
+ {[]string{"../../../artifacts/guestbook", "../../../artifacts/kustomization"}, false, 6, []string{"redis-master", "test-the-deployment"}},
|
|
+ }
|
|
|
|
- test := &testVisitor{}
|
|
- singleItemImplied := false
|
|
+ for _, tt := range tests {
|
|
+ b := newDefaultBuilder().
|
|
+ FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: tt.directories}).
|
|
+ NamespaceParam("test").DefaultNamespace()
|
|
|
|
- err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
|
- if err != nil || singleItemImplied || len(test.Infos) < 3 {
|
|
- t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
|
- }
|
|
+ test := &testVisitor{}
|
|
+ singleItemImplied := false
|
|
|
|
- found := false
|
|
- for _, info := range test.Infos {
|
|
- if info.Name == "redis-master" && info.Namespace == "test" && info.Object != nil {
|
|
- found = true
|
|
- break
|
|
+ err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
|
+ if err != nil || singleItemImplied != tt.singleItem || len(test.Infos) < tt.number {
|
|
+ t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
|
+ }
|
|
+
|
|
+ contained := func(name string) bool {
|
|
+ for _, info := range test.Infos {
|
|
+ if info.Name == name && info.Namespace == "test" && info.Object != nil {
|
|
+ return true
|
|
+ }
|
|
+ }
|
|
+ return false
|
|
+ }
|
|
+
|
|
+ allFound := true
|
|
+ for _, name := range tt.expectedNames {
|
|
+ if !contained(name) {
|
|
+ allFound = false
|
|
+ }
|
|
+ }
|
|
+ if !allFound {
|
|
+ t.Errorf("unexpected responses: %#v", test.Infos)
|
|
}
|
|
- }
|
|
- if !found {
|
|
- t.Errorf("unexpected responses: %#v", test.Infos)
|
|
}
|
|
}
|
|
|
|
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
|
index 32c1a691a5..d7a37e1cde 100644
|
|
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
|
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
|
@@ -20,10 +20,12 @@ import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
+ "io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
+ "strings"
|
|
"time"
|
|
|
|
"golang.org/x/text/encoding/unicode"
|
|
@@ -38,6 +40,9 @@ 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/fs"
|
|
)
|
|
|
|
const (
|
|
@@ -452,7 +457,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
|
if err != nil {
|
|
return err
|
|
}
|
|
-
|
|
+ if 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 strings.HasSuffix(path, "kustomization.yaml") {
|
|
+ visitors = append(visitors, NewKustomizationVisitor(mapper, filepath.Dir(path), schema))
|
|
+ return nil
|
|
+ }
|
|
visitor := &FileVisitor{
|
|
Path: path,
|
|
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
|
@@ -479,6 +490,14 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
|
return visitors, nil
|
|
}
|
|
|
|
+func isKustomizationDir(path string) bool {
|
|
+ if _, err := os.Stat(filepath.Join(path, "kustomization.yaml")); err == nil {
|
|
+ return true
|
|
+ }
|
|
+ return false
|
|
+}
|
|
+
|
|
+
|
|
// FileVisitor is wrapping around a StreamVisitor, to handle open/close files
|
|
type FileVisitor struct {
|
|
Path string
|
|
@@ -507,6 +526,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
|