From 06c5be98028d6c045ae438498b46262ea1035b9c Mon Sep 17 00:00:00 2001 From: ymqytw Date: Tue, 7 Nov 2017 17:42:03 -0800 Subject: [PATCH] refactor builder in kubectl factory --- pkg/kubectl/cmd/annotate.go | 36 +++++++++------------- pkg/kubectl/cmd/apply.go | 5 ++- pkg/kubectl/cmd/apply_set_last_applied.go | 10 ++---- pkg/kubectl/cmd/apply_view_last_applied.go | 8 +---- pkg/kubectl/cmd/convert.go | 6 ++-- pkg/kubectl/cmd/create.go | 5 ++- pkg/kubectl/cmd/delete.go | 5 ++- pkg/kubectl/cmd/describe.go | 8 +---- pkg/kubectl/cmd/diff.go | 8 +---- pkg/kubectl/cmd/label.go | 35 +++++++++------------ pkg/kubectl/cmd/patch.go | 8 +---- pkg/kubectl/cmd/replace.go | 8 ++--- pkg/kubectl/cmd/resource/get.go | 18 ++--------- pkg/kubectl/cmd/set/set_env.go | 12 ++++---- pkg/kubectl/cmd/set/set_image.go | 12 ++++---- pkg/kubectl/cmd/set/set_resources.go | 12 ++++---- pkg/kubectl/cmd/set/set_selector.go | 10 +++--- pkg/kubectl/cmd/set/set_subject.go | 12 ++++---- pkg/kubectl/cmd/testing/BUILD | 1 + pkg/kubectl/cmd/testing/fake.go | 27 ++++++++++++++++ pkg/kubectl/cmd/util/editor/editoptions.go | 6 ++-- pkg/kubectl/cmd/util/factory.go | 4 ++- pkg/kubectl/cmd/util/factory_builder.go | 15 +++++++-- pkg/kubectl/resource/BUILD | 1 - pkg/kubectl/resource/builder.go | 12 -------- 25 files changed, 125 insertions(+), 159 deletions(-) diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index 92ec1a12527..bf11285685d 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -189,31 +189,23 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro changeCause := f.Command(cmd, false) includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - b := f.NewBuilder(). - ContinueOnError(). + + var b *resource.Builder + if o.local { + b = f.NewBuilder(). + Local(f.ClientForMapping) + } else { + b = f.NewUnstructuredBuilder(). + LabelSelectorParam(o.selector). + ResourceTypeOrNameArgs(o.all, o.resources...). + Latest() + } + r := b.ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). IncludeUninitialized(includeUninitialized). - Flatten() - - if !o.local { - // call this method here, as it requires an api call - // and will cause the command to fail when there is - // no connection to a server - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - b = b.LabelSelectorParam(o.selector). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). - ResourceTypeOrNameArgs(o.all, o.resources...). - Latest() - } else { - b = b.Local(f.ClientForMapping) - } - - r := b.Do() + Flatten(). + Do() if err := r.Err(); err != nil { return err } diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index df3b2190079..17f04fe4332 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -198,7 +198,7 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti return err } - mapper, typer, err := f.UnstructuredObject() + mapper, _, err := f.UnstructuredObject() if err != nil { return err } @@ -213,8 +213,7 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti // include the uninitialized objects by default if --prune is true // unless explicitly set --include-uninitialized=false includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, options.Prune) - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/apply_set_last_applied.go b/pkg/kubectl/cmd/apply_set_last_applied.go index f1f06648ae2..60f84f32687 100644 --- a/pkg/kubectl/cmd/apply_set_last_applied.go +++ b/pkg/kubectl/cmd/apply_set_last_applied.go @@ -122,19 +122,13 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) } func (o *SetLastAppliedOptions) Validate(f cmdutil.Factory, cmd *cobra.Command) error { - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). NamespaceParam(o.Namespace).DefaultNamespace(). FilenameParam(o.EnforceNamespace, &o.FilenameOptions). Latest(). Flatten(). Do() - err = r.Err() + err := r.Err() if err != nil { return err } diff --git a/pkg/kubectl/cmd/apply_view_last_applied.go b/pkg/kubectl/cmd/apply_view_last_applied.go index 8692cffde1f..7a01bee09cc 100644 --- a/pkg/kubectl/cmd/apply_view_last_applied.go +++ b/pkg/kubectl/cmd/apply_view_last_applied.go @@ -87,13 +87,7 @@ func (o *ViewLastAppliedOptions) Complete(f cmdutil.Factory, args []string) erro return err } - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(enforceNamespace, args...). diff --git a/pkg/kubectl/cmd/convert.go b/pkg/kubectl/cmd/convert.go index 88cec678c58..492f850162b 100644 --- a/pkg/kubectl/cmd/convert.go +++ b/pkg/kubectl/cmd/convert.go @@ -129,14 +129,14 @@ func (o *ConvertOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.C // build the builder o.builder = f.NewBuilder() - if !o.local { + if o.local { + o.builder = o.builder.Local(f.ClientForMapping) + } else { schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate")) if err != nil { return err } o.builder = o.builder.Schema(schema) - } else { - o.builder = o.builder.Local(f.ClientForMapping) } cmdNamespace, _, err := f.DefaultNamespace() diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index 6ec61c93acd..5aecf9688e6 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -183,13 +183,12 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt return err } - mapper, typer, err := f.UnstructuredObject() + mapper, _, err := f.UnstructuredObject() if err != nil { return err } - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index bf37e301367..ad9efbb2abc 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -170,15 +170,14 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args } // Set up client based support. - mapper, typer, err := f.UnstructuredObject() + mapper, _, err := f.UnstructuredObject() if err != nil { return err } o.Mapper = mapper includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/describe.go b/pkg/kubectl/cmd/describe.go index 0f69c73164a..efb47985513 100644 --- a/pkg/kubectl/cmd/describe.go +++ b/pkg/kubectl/cmd/describe.go @@ -116,16 +116,10 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a return cmdutil.UsageErrorf(cmd, "Required resource not specified.") } - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - // include the uninitialized objects by default // unless user explicitly set --include-uninitialized=false includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, true) - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/diff.go b/pkg/kubectl/cmd/diff.go index dc3b19577ba..b6c98ec85c7 100644 --- a/pkg/kubectl/cmd/diff.go +++ b/pkg/kubectl/cmd/diff.go @@ -408,18 +408,12 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions, from, t printer := Printer{} - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err } - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &options.FilenameOptions). Flatten(). diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index e53e4b720d2..171b1ce48bc 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -190,32 +190,25 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { changeCause := f.Command(cmd, false) includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - b := f.NewBuilder(). - ContinueOnError(). - NamespaceParam(cmdNamespace).DefaultNamespace(). - FilenameParam(enforceNamespace, &o.FilenameOptions). - IncludeUninitialized(includeUninitialized). - Flatten() - - if !o.local { - // call this method here, as it requires an api call - // and will cause the command to fail when there is - // no connection to a server - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - b = b.LabelSelectorParam(o.selector). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + var b *resource.Builder + if o.local { + b = f.NewBuilder(). + Local(f.ClientForMapping) + } else { + b = f.NewUnstructuredBuilder(). + LabelSelectorParam(o.selector). ResourceTypeOrNameArgs(o.all, o.resources...). Latest() - } else { - b = b.Local(f.ClientForMapping) } one := false - r := b.Do().IntoSingleItemImplied(&one) + r := b.ContinueOnError(). + NamespaceParam(cmdNamespace).DefaultNamespace(). + FilenameParam(enforceNamespace, &o.FilenameOptions). + IncludeUninitialized(includeUninitialized). + Flatten(). + Do(). + IntoSingleItemImplied(&one) if err := r.Err(); err != nil { return err } diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index ddd4e130a75..bb160564455 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -153,13 +153,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin return fmt.Errorf("unable to parse %q: %v", patch, err) } - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &options.FilenameOptions). diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index 40403b2dc48..8d2674af8f2 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -120,13 +120,12 @@ func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str return fmt.Errorf("--timeout must have --force specified") } - mapper, typer, err := f.UnstructuredObject() + mapper, _, err := f.UnstructuredObject() if err != nil { return err } - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -249,8 +248,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s return err } - r = f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r = f.NewUnstructuredBuilder(). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/resource/get.go b/pkg/kubectl/cmd/resource/get.go index 96931118393..a47730e4d48 100644 --- a/pkg/kubectl/cmd/resource/get.go +++ b/pkg/kubectl/cmd/resource/get.go @@ -226,13 +226,7 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str return options.watch(f, cmd, args) } - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces). FilenameParam(options.ExplicitNamespace, &options.FilenameOptions). LabelSelectorParam(options.LabelSelector). @@ -439,18 +433,12 @@ func (options *GetOptions) raw(f cmdutil.Factory) error { // watch starts a client-side watch of one or more resources. // TODO: remove the need for arguments here. func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string) error { - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return err - } - // TODO: this could be better factored // include uninitialized objects when watching on a single object // unless explicitly set --include-uninitialized=false includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, len(args) == 2) - r := f.NewBuilder(). - Unstructured(f.UnstructuredClientForMapping, mapper, typer). + r := f.NewUnstructuredBuilder(). NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces). FilenameParam(options.ExplicitNamespace, &options.FilenameOptions). LabelSelectorParam(options.LabelSelector). @@ -462,7 +450,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s SingleResourceType(). Latest(). Do() - err = r.Err() + err := r.Err() if err != nil { return err } diff --git a/pkg/kubectl/cmd/set/set_env.go b/pkg/kubectl/cmd/set/set_env.go index e6a2679715f..1e92195ed35 100644 --- a/pkg/kubectl/cmd/set/set_env.go +++ b/pkg/kubectl/cmd/set/set_env.go @@ -238,13 +238,13 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { FilenameParam(enforceNamespace, &o.FilenameOptions). Flatten() - if !o.Local { + if o.Local { + b = b.Local(f.ClientForMapping) + } else { b = b. LabelSelectorParam(o.Selector). ResourceTypeOrNameArgs(o.All, o.From). Latest() - } else { - b = b.Local(f.ClientForMapping) } infos, err := b.Do().Infos() @@ -302,13 +302,13 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { FilenameParam(enforceNamespace, &o.FilenameOptions). Flatten() - if !o.Local { + if o.Local { + b = b.Local(f.ClientForMapping) + } else { b = b. LabelSelectorParam(o.Selector). ResourceTypeOrNameArgs(o.All, o.Resources...). Latest() - } else { - b = b.Local(f.ClientForMapping) } o.Infos, err = b.Do().Infos() diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index 9cac8b68cae..2ccf578d26b 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -147,12 +147,7 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st IncludeUninitialized(includeUninitialized). Flatten() - if !o.Local { - builder = builder. - LabelSelectorParam(o.Selector). - ResourceTypeOrNameArgs(o.All, o.Resources...). - Latest() - } else { + if o.Local { // if a --local flag was provided, and a resource was specified in the form // /, fail immediately as --local cannot query the api server // for the specified resource. @@ -161,6 +156,11 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } builder = builder.Local(f.ClientForMapping) + } else { + builder = builder. + LabelSelectorParam(o.Selector). + ResourceTypeOrNameArgs(o.All, o.Resources...). + Latest() } o.Infos, err = builder.Do().Infos() diff --git a/pkg/kubectl/cmd/set/set_resources.go b/pkg/kubectl/cmd/set/set_resources.go index 3278c6a1733..db882d0ed4e 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -151,12 +151,7 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args IncludeUninitialized(includeUninitialized). Flatten() - if !o.Local { - builder = builder. - LabelSelectorParam(o.Selector). - ResourceTypeOrNameArgs(o.All, args...). - Latest() - } else { + if o.Local { // if a --local flag was provided, and a resource was specified in the form // /, fail immediately as --local cannot query the api server // for the specified resource. @@ -165,6 +160,11 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args } builder = builder.Local(f.ClientForMapping) + } else { + builder = builder. + LabelSelectorParam(o.Selector). + ResourceTypeOrNameArgs(o.All, args...). + Latest() } o.Infos, err = builder.Do().Infos() diff --git a/pkg/kubectl/cmd/set/set_selector.go b/pkg/kubectl/cmd/set/set_selector.go index 343c8051803..83d6432ca8a 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -132,11 +132,7 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ IncludeUninitialized(includeUninitialized). Flatten() - if !o.local { - o.builder = o.builder. - ResourceTypeOrNameArgs(o.all, o.resources...). - Latest() - } else { + if o.local { // if a --local flag was provided, and a resource was specified in the form // /, fail immediately as --local cannot query the api server // for the specified resource. @@ -145,6 +141,10 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ } o.builder = o.builder.Local(f.ClientForMapping) + } else { + o.builder = o.builder. + ResourceTypeOrNameArgs(o.all, o.resources...). + Latest() } o.PrintObject = func(obj runtime.Object) error { diff --git a/pkg/kubectl/cmd/set/set_subject.go b/pkg/kubectl/cmd/set/set_subject.go index 9ab633310b2..4972d88fbcb 100644 --- a/pkg/kubectl/cmd/set/set_subject.go +++ b/pkg/kubectl/cmd/set/set_subject.go @@ -133,12 +133,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] IncludeUninitialized(includeUninitialized). Flatten() - if !o.Local { - builder = builder. - LabelSelectorParam(o.Selector). - ResourceTypeOrNameArgs(o.All, args...). - Latest() - } else { + if o.Local { // if a --local flag was provided, and a resource was specified in the form // /, fail immediately as --local cannot query the api server // for the specified resource. @@ -147,6 +142,11 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] } builder = builder.Local(f.ClientForMapping) + } else { + builder = builder. + LabelSelectorParam(o.Selector). + ResourceTypeOrNameArgs(o.All, args...). + Latest() } o.Infos, err = builder.Do().Infos() diff --git a/pkg/kubectl/cmd/testing/BUILD b/pkg/kubectl/cmd/testing/BUILD index 483b7c98c0d..3d4fd216627 100644 --- a/pkg/kubectl/cmd/testing/BUILD +++ b/pkg/kubectl/cmd/testing/BUILD @@ -29,6 +29,7 @@ go_library( "//vendor/github.com/spf13/pflag:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index e622b395f24..a451ab6b718 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -481,6 +482,19 @@ func (f *FakeFactory) NewBuilder() *resource.Builder { return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) } +func (f *FakeFactory) NewUnstructuredBuilder() *resource.Builder { + mapper, typer, err := f.UnstructuredObject() + if err != nil { + cmdutil.CheckErr(err) + } + return resource.NewBuilder( + mapper, + f.CategoryExpander(), + typer, + resource.ClientMapperFunc(f.UnstructuredClientForMapping), + unstructured.UnstructuredJSONScheme) +} + func (f *FakeFactory) DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *printers.PrintOptions { return &printers.PrintOptions{} } @@ -758,6 +772,19 @@ func (f *fakeAPIFactory) NewBuilder() *resource.Builder { return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) } +func (f *fakeAPIFactory) NewUnstructuredBuilder() *resource.Builder { + mapper, typer, err := f.UnstructuredObject() + if err != nil { + cmdutil.CheckErr(err) + } + return resource.NewBuilder( + mapper, + f.CategoryExpander(), + typer, + resource.ClientMapperFunc(f.UnstructuredClientForMapping), + unstructured.UnstructuredJSONScheme) +} + func (f *fakeAPIFactory) SuggestedPodTemplateResources() []schema.GroupResource { return []schema.GroupResource{} } diff --git a/pkg/kubectl/cmd/util/editor/editoptions.go b/pkg/kubectl/cmd/util/editor/editoptions.go index a17e502f113..2403217b049 100644 --- a/pkg/kubectl/cmd/util/editor/editoptions.go +++ b/pkg/kubectl/cmd/util/editor/editoptions.go @@ -107,12 +107,12 @@ func (o *EditOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args [] if err != nil { return err } - mapper, typer, err := f.UnstructuredObject() + mapper, _, err := f.UnstructuredObject() if err != nil { return err } - b := f.NewBuilder().Unstructured(f.UnstructuredClientForMapping, mapper, typer) + b := f.NewUnstructuredBuilder() if o.EditMode == NormalEditMode || o.EditMode == ApplyEditMode { // when do normal edit or apply edit we need to always retrieve the latest resource from server b = b.ResourceTypeOrNameArgs(true, args...).Latest() @@ -132,7 +132,7 @@ func (o *EditOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args [] o.updatedResultGetter = func(data []byte) *resource.Result { // resource builder to read objects from edited data - return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). + return f.NewUnstructuredBuilder(). Stream(bytes.NewReader(data), "edited-file"). IncludeUninitialized(includeUninitialized). ContinueOnError(). diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 62dd2b40bf2..a614ff0688f 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -243,8 +243,10 @@ type BuilderFactory interface { PrinterForMapping(cmd *cobra.Command, isLocal bool, outputOpts *printers.OutputOptions, mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinter, error) // PrintObject prints an api object given command line flags to modify the output format PrintObject(cmd *cobra.Command, isLocal bool, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error - // One stop shopping for a Builder + // One stop shopping for a structured Builder NewBuilder() *resource.Builder + // One stop shopping for a unstructured Builder + NewUnstructuredBuilder() *resource.Builder // PluginLoader provides the implementation to be used to load cli plugins. PluginLoader() plugins.PluginLoader // PluginRunner provides the implementation to be used to run cli plugins. diff --git a/pkg/kubectl/cmd/util/factory_builder.go b/pkg/kubectl/cmd/util/factory_builder.go index b5d1ba1c5f7..e62280a7358 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -138,8 +138,7 @@ func (f *ring2Factory) PrintObject(cmd *cobra.Command, isLocal bool, mapper meta return printer.PrintObj(obj, out) } -// NewBuilder returns a new resource builder. -// Receives a bool flag and avoids remote calls if set to false +// NewBuilder returns a new resource builder for structured api objects. func (f *ring2Factory) NewBuilder() *resource.Builder { clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping) @@ -149,6 +148,18 @@ func (f *ring2Factory) NewBuilder() *resource.Builder { return resource.NewBuilder(mapper, categoryExpander, typer, clientMapperFunc, f.clientAccessFactory.Decoder(true)) } +// NewUnstructuredBuilder returns a new resource builder for unstructured api objects. +func (f *ring2Factory) NewUnstructuredBuilder() *resource.Builder { + clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.UnstructuredClientForMapping) + mapper, typer, err := f.objectMappingFactory.UnstructuredObject() + if err != nil { + CheckErr(err) + } + categoryExpander := f.objectMappingFactory.CategoryExpander() + + return resource.NewBuilder(mapper, categoryExpander, typer, clientMapperFunc, unstructured.UnstructuredJSONScheme) +} + // PluginLoader loads plugins from a path set by the KUBECTL_PLUGINS_PATH env var. // If this env var is not set, it defaults to // "~/.kube/plugins", plus diff --git a/pkg/kubectl/resource/BUILD b/pkg/kubectl/resource/BUILD index c3490f32407..ed749eb0d58 100644 --- a/pkg/kubectl/resource/BUILD +++ b/pkg/kubectl/resource/BUILD @@ -29,7 +29,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 08b63ad7723..c9b2cfee4d8 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -26,7 +26,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -170,17 +169,6 @@ func (b *Builder) Local(mapperFunc ClientMapperFunc) *Builder { return b } -// Unstructured updates the builder's ClientMapper, RESTMapper, -// ObjectTyper, and codec for working with unstructured api objects -func (b *Builder) Unstructured(mapperFunc ClientMapperFunc, mapper meta.RESTMapper, typer runtime.ObjectTyper) *Builder { - b.mapper.RESTMapper = mapper - b.mapper.ObjectTyper = typer - b.mapper.Decoder = unstructured.UnstructuredJSONScheme - b.mapper.ClientMapper = ClientMapperFunc(mapperFunc) - - return b -} - // URL accepts a number of URLs directly. func (b *Builder) URL(httpAttemptCount int, urls ...*url.URL) *Builder { for _, u := range urls {