From 6c9460f0b405630ebd21cd432b8b8ffede6d7554 Mon Sep 17 00:00:00 2001 From: monopole Date: Thu, 25 Feb 2021 12:06:47 -0800 Subject: [PATCH] Manually update kustomize attachment points. --- .../cli-runtime/pkg/resource/builder.go | 11 ++- .../pkg/resource/kustomizevisitor.go | 54 +++++++++++++ .../pkg/resource/kustomizevisitor_test.go | 51 ++++++++----- .../cli-runtime/pkg/resource/visitor.go | 22 ------ .../kubectl/pkg/cmd/kustomize/kustomize.go | 76 +++---------------- 5 files changed, 105 insertions(+), 109 deletions(-) create mode 100644 staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/builder.go b/staging/src/k8s.io/cli-runtime/pkg/resource/builder.go index 2f665bb51d0..a8ebf6410c8 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/builder.go +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/builder.go @@ -38,6 +38,7 @@ import ( "k8s.io/client-go/discovery" "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" + "sigs.k8s.io/kustomize/api/filesys" ) var FileExtensions = []string{".json", ".yaml", ".yml"} @@ -258,8 +259,14 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename } } if filenameOptions.Kustomize != "" { - b.paths = append(b.paths, &KustomizeVisitor{filenameOptions.Kustomize, - NewStreamVisitor(nil, b.mapper, filenameOptions.Kustomize, b.schema)}) + b.paths = append( + b.paths, + &KustomizeVisitor{ + mapper: b.mapper, + dirPath: filenameOptions.Kustomize, + schema: b.schema, + fSys: filesys.MakeFsOnDisk(), + }) } if enforceNamespace { diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go b/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go new file mode 100644 index 00000000000..22c9a548d4b --- /dev/null +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor.go @@ -0,0 +1,54 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "bytes" + + "sigs.k8s.io/kustomize/api/filesys" + "sigs.k8s.io/kustomize/api/krusty" +) + +// KustomizeVisitor handles kustomization.yaml files. +type KustomizeVisitor struct { + mapper *mapper + schema ContentValidator + // Directory expected to contain a kustomization file. + dirPath string + // File system containing dirPath. + fSys filesys.FileSystem + // Holds result of kustomize build, retained for tests. + yml []byte +} + +// Visit passes the result of a kustomize build to a StreamVisitor. +func (v *KustomizeVisitor) Visit(fn VisitorFunc) error { + kOpts := krusty.MakeDefaultOptions() + kOpts.DoLegacyResourceSort = true + k := krusty.MakeKustomizer(kOpts) + m, err := k.Run(v.fSys, v.dirPath) + if err != nil { + return err + } + v.yml, err = m.AsYaml() + if err != nil { + return err + } + sv := NewStreamVisitor( + bytes.NewReader(v.yml), v.mapper, v.dirPath, v.schema) + return sv.Visit(fn) +} diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor_test.go b/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor_test.go index df17cae9d84..6bcaaf9d539 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor_test.go +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/kustomizevisitor_test.go @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kustomize +package resource import ( - "bytes" + "github.com/davecgh/go-spew/spew" + "sigs.k8s.io/kustomize/api/filesys" + "sigs.k8s.io/kustomize/api/konfig" "testing" - - "sigs.k8s.io/kustomize/pkg/fs" ) const ( @@ -79,7 +79,7 @@ metadata: note: This is a test annotation labels: app: nginx - name: foo-ns1-bar + name: ns1 --- apiVersion: v1 data: @@ -91,7 +91,7 @@ metadata: note: This is a test annotation labels: app: nginx - name: foo-literalConfigMap-bar-8d2dkb8k24 + name: foo-literalConfigMap-bar-g5f6t456f5 namespace: ns1 --- apiVersion: v1 @@ -104,7 +104,7 @@ metadata: note: This is a test annotation labels: app: nginx - name: foo-secret-bar-9btc7bt4kb + name: foo-secret-bar-82c2g5f8f6 namespace: ns1 type: Opaque --- @@ -131,20 +131,29 @@ spec: ` ) -func TestResources1(t *testing.T) { - fSys := fs.MakeFakeFS() - fSys.WriteFile("/kustomization.yaml", []byte(kustomizationContent1)) - fSys.WriteFile("/deployment.yaml", []byte(deploymentContent)) - fSys.WriteFile("/namespace.yaml", []byte(namespaceContent)) - fSys.WriteFile("/jsonpatch.json", []byte(jsonpatchContent)) - - var out bytes.Buffer - err := RunKustomizeBuild(&out, fSys, "/") - if err != nil { - t.Fatalf("unexpected Resources error %v", err) +func TestKustomizeVisitor(t *testing.T) { + fSys := filesys.MakeFsInMemory() + fSys.WriteFile( + konfig.DefaultKustomizationFileName(), + []byte(kustomizationContent1)) + fSys.WriteFile("deployment.yaml", []byte(deploymentContent)) + fSys.WriteFile("namespace.yaml", []byte(namespaceContent)) + fSys.WriteFile("jsonpatch.json", []byte(jsonpatchContent)) + b := newDefaultBuilder() + kv := KustomizeVisitor{ + mapper: b.mapper, + dirPath: ".", + schema: b.schema, + fSys: fSys, } - - if out.String() != expectedContent { - t.Fatalf("expected:\n%s\nbut got:\n%s", expectedContent, out.String()) + tv := &testVisitor{} + if err := kv.Visit(tv.Handle); err != nil { + t.Fatal(err) + } + if len(tv.Infos) != 4 { + t.Fatal(spew.Sdump(tv.Infos)) + } + if string(kv.yml) != expectedContent { + t.Fatalf("expected:\n%s\nbut got:\n%s", expectedContent, string(kv.yml)) } } diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/visitor.go b/staging/src/k8s.io/cli-runtime/pkg/resource/visitor.go index fbd52e12f20..25d24434651 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/visitor.go +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/visitor.go @@ -30,9 +30,6 @@ import ( "golang.org/x/text/encoding/unicode" "golang.org/x/text/transform" - - "sigs.k8s.io/kustomize/pkg/fs" - "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,7 +39,6 @@ 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" ) const ( @@ -528,24 +524,6 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error { return v.StreamVisitor.Visit(fn) } -// KustomizeVisitor is wrapper around a StreamVisitor, to handle Kustomization directories -type KustomizeVisitor struct { - Path string - *StreamVisitor -} - -// Visit in a KustomizeVisitor gets the output of Kustomize build and save it in the Streamvisitor -func (v *KustomizeVisitor) Visit(fn VisitorFunc) error { - fSys := fs.MakeRealFS() - var out bytes.Buffer - err := kustomize.RunKustomizeBuild(&out, fSys, v.Path) - if err != nil { - return err - } - v.StreamVisitor.Reader = bytes.NewReader(out.Bytes()) - return v.StreamVisitor.Visit(fn) -} - // 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 diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/kustomize/kustomize.go b/staging/src/k8s.io/kubectl/pkg/cmd/kustomize/kustomize.go index 5d13098f502..7b9d85e9315 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/kustomize/kustomize.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/kustomize/kustomize.go @@ -17,76 +17,24 @@ limitations under the License. package kustomize import ( - "errors" "github.com/spf13/cobra" - "k8s.io/cli-runtime/pkg/genericclioptions" - "k8s.io/cli-runtime/pkg/kustomize" "k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/templates" - "sigs.k8s.io/kustomize/pkg/fs" + "sigs.k8s.io/kustomize/api/filesys" + "sigs.k8s.io/kustomize/kustomize/v4/commands/build" ) -type kustomizeOptions struct { - kustomizationDir string -} - -var ( - kustomizeLong = templates.LongDesc(i18n.T(` -Print a set of API resources generated from instructions in a kustomization.yaml file. - -The argument must be the path to the directory containing -the file, or a git repository -URL with a path suffix specifying same with respect to the -repository root. - - kubectl kustomize somedir - `)) - - kustomizeExample = templates.Examples(i18n.T(` -# Use the current working directory - kubectl kustomize . - -# Use some shared configuration directory - kubectl kustomize /home/configuration/production - -# Use a URL - kubectl kustomize github.com/kubernetes-sigs/kustomize.git/examples/helloWorld?ref=v1.0.6 -`)) -) - -// NewCmdKustomize returns a kustomize command +// NewCmdKustomize returns an adapted kustomize build command. func NewCmdKustomize(streams genericclioptions.IOStreams) *cobra.Command { - var o kustomizeOptions - - cmd := &cobra.Command{ - Use: "kustomize ", - Short: i18n.T("Build a kustomization target from a directory or a remote url."), - Long: kustomizeLong, - Example: kustomizeExample, - - RunE: func(cmd *cobra.Command, args []string) error { - err := o.Validate(args) - if err != nil { - return err - } - return kustomize.RunKustomizeBuild(streams.Out, fs.MakeRealFS(), o.kustomizationDir) + h := build.MakeHelp("kubectl", "kustomize") + return build.NewCmdBuild( + filesys.MakeFsOnDisk(), + &build.Help{ + Use: h.Use, + Short: i18n.T(h.Short), + Long: templates.LongDesc(i18n.T(h.Long)), + Example: templates.Examples(i18n.T(h.Example)), }, - } - - return cmd -} - -// Validate validates build command. -func (o *kustomizeOptions) Validate(args []string) error { - if len(args) > 1 { - return errors.New("specify one path to a kustomization directory") - } - if len(args) == 0 { - o.kustomizationDir = "./" - } else { - o.kustomizationDir = args[0] - } - - return nil + streams.Out) }