From 90d76adb4bf1180782528b10852d2a12ce35022d Mon Sep 17 00:00:00 2001 From: juanvallejo Date: Wed, 2 Aug 2017 16:23:07 -0400 Subject: [PATCH] add Local and Unstructured builder attributes Moves DisabledClientMapperForMapping wrapper to new Local attribute. Removes Factory#NewUnstructuredBuilder in favor of new Unstructured builder attribute. --- pkg/kubectl/cmd/annotate.go | 19 ++++++++---- pkg/kubectl/cmd/apply.go | 11 ++----- pkg/kubectl/cmd/apply_set_last_applied.go | 5 ++-- pkg/kubectl/cmd/apply_view_last_applied.go | 5 ++-- pkg/kubectl/cmd/attach.go | 2 +- pkg/kubectl/cmd/auth/reconcile.go | 2 +- pkg/kubectl/cmd/autoscale.go | 4 +-- pkg/kubectl/cmd/certificates.go | 2 +- pkg/kubectl/cmd/clusterinfo.go | 2 +- pkg/kubectl/cmd/convert.go | 5 +++- pkg/kubectl/cmd/create.go | 10 ++----- pkg/kubectl/cmd/delete.go | 10 ++----- pkg/kubectl/cmd/describe.go | 6 ++-- pkg/kubectl/cmd/drain.go | 5 ++-- pkg/kubectl/cmd/expose.go | 2 +- pkg/kubectl/cmd/get.go | 18 +++++------ pkg/kubectl/cmd/label.go | 19 ++++++++---- pkg/kubectl/cmd/logs.go | 2 +- pkg/kubectl/cmd/patch.go | 7 ++--- pkg/kubectl/cmd/replace.go | 18 ++++------- pkg/kubectl/cmd/rollingupdate.go | 2 +- pkg/kubectl/cmd/rollout/rollout_history.go | 2 +- pkg/kubectl/cmd/rollout/rollout_pause.go | 2 +- pkg/kubectl/cmd/rollout/rollout_resume.go | 2 +- pkg/kubectl/cmd/rollout/rollout_status.go | 2 +- pkg/kubectl/cmd/rollout/rollout_undo.go | 2 +- pkg/kubectl/cmd/run.go | 2 +- pkg/kubectl/cmd/scale.go | 2 +- pkg/kubectl/cmd/set/set_image.go | 5 +++- pkg/kubectl/cmd/set/set_resources.go | 4 ++- pkg/kubectl/cmd/set/set_selector.go | 4 ++- pkg/kubectl/cmd/set/set_serviceaccount.go | 4 ++- pkg/kubectl/cmd/set/set_subject.go | 4 ++- pkg/kubectl/cmd/taint.go | 2 +- pkg/kubectl/cmd/testing/fake.go | 35 +++------------------- pkg/kubectl/cmd/util/editor/editoptions.go | 5 +--- pkg/kubectl/cmd/util/factory.go | 4 +-- pkg/kubectl/cmd/util/factory_builder.go | 28 ++--------------- pkg/kubectl/resource/builder.go | 35 ++++++++++++++++++++++ 39 files changed, 143 insertions(+), 157 deletions(-) diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index 318aeb7594..3d53db9697 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -186,13 +186,8 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro changeCause := f.Command(cmd, false) - builder, err := f.NewUnstructuredBuilder(!o.local) - if err != nil { - return err - } - includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - b := builder. + b := f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). @@ -200,10 +195,22 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro 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.SelectorParam(o.selector). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). ResourceTypeOrNameArgs(o.all, o.resources...). Latest() + } else { + b = b.Local(f.ClientForMapping) } + r := b.Do() if err := r.Err(); err != nil { return err diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index 5b756c81e7..3a006880ca 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, _, err := f.UnstructuredObject() + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } @@ -210,16 +210,11 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti } } - builder, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } - // include the uninitialized objects by default if --prune is true // unless explicitly set --include-uninitialized=false includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, options.Prune) - - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). 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 d2453aa746..f1f06648ae 100644 --- a/pkg/kubectl/cmd/apply_set_last_applied.go +++ b/pkg/kubectl/cmd/apply_set_last_applied.go @@ -122,12 +122,13 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) } func (o *SetLastAppliedOptions) Validate(f cmdutil.Factory, cmd *cobra.Command) error { - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). NamespaceParam(o.Namespace).DefaultNamespace(). FilenameParam(o.EnforceNamespace, &o.FilenameOptions). Latest(). diff --git a/pkg/kubectl/cmd/apply_view_last_applied.go b/pkg/kubectl/cmd/apply_view_last_applied.go index 69b16f5ec8..4c7cec8214 100644 --- a/pkg/kubectl/cmd/apply_view_last_applied.go +++ b/pkg/kubectl/cmd/apply_view_last_applied.go @@ -87,12 +87,13 @@ func (o *ViewLastAppliedOptions) Complete(f cmdutil.Factory, args []string) erro return err } - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(enforceNamespace, args...). diff --git a/pkg/kubectl/cmd/attach.go b/pkg/kubectl/cmd/attach.go index 3afa2db1ae..0086178491 100644 --- a/pkg/kubectl/cmd/attach.go +++ b/pkg/kubectl/cmd/attach.go @@ -142,7 +142,7 @@ func (p *AttachOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn [ return cmdutil.UsageErrorf(cmd, err.Error()) } - builder := f.NewBuilder(true). + builder := f.NewBuilder(). NamespaceParam(namespace).DefaultNamespace() switch len(argsIn) { diff --git a/pkg/kubectl/cmd/auth/reconcile.go b/pkg/kubectl/cmd/auth/reconcile.go index 5ce505eec6..2dc8ca44e8 100644 --- a/pkg/kubectl/cmd/auth/reconcile.go +++ b/pkg/kubectl/cmd/auth/reconcile.go @@ -92,7 +92,7 @@ func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args if err != nil { return err } - o.ResourceBuilder = f.NewBuilder(true). + o.ResourceBuilder = f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index 34890f87b3..27f320d5d1 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -90,8 +90,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s return err } - mapper, typer := f.Object() - r := f.NewBuilder(true). + r := f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). @@ -145,6 +144,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s return err } + mapper, typer := f.Object() resourceMapper := &resource.Mapper{ ObjectTyper: typer, RESTMapper: mapper, diff --git a/pkg/kubectl/cmd/certificates.go b/pkg/kubectl/cmd/certificates.go index 1287f55deb..43388b4b57 100644 --- a/pkg/kubectl/cmd/certificates.go +++ b/pkg/kubectl/cmd/certificates.go @@ -167,7 +167,7 @@ func (options *CertificateOptions) modifyCertificateCondition(f cmdutil.Factory, if err != nil { return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). ContinueOnError(). FilenameParam(false, &options.FilenameOptions). ResourceNames("certificatesigningrequest", options.csrNames...). diff --git a/pkg/kubectl/cmd/clusterinfo.go b/pkg/kubectl/cmd/clusterinfo.go index 71871a9a22..f0f39448dd 100644 --- a/pkg/kubectl/cmd/clusterinfo.go +++ b/pkg/kubectl/cmd/clusterinfo.go @@ -71,7 +71,7 @@ func RunClusterInfo(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error } // TODO use generalized labels once they are implemented (#341) - b := f.NewBuilder(true). + b := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). SelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). diff --git a/pkg/kubectl/cmd/convert.go b/pkg/kubectl/cmd/convert.go index b450ad1427..c5c4afb74c 100644 --- a/pkg/kubectl/cmd/convert.go +++ b/pkg/kubectl/cmd/convert.go @@ -126,14 +126,17 @@ func (o *ConvertOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.C } // build the builder - o.builder = f.NewBuilder(!o.local) + o.builder = f.NewBuilder() if !o.local { schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagBool(cmd, "openapi-validation"), cmdutil.GetFlagString(cmd, "schema-cache-dir")) if err != nil { return err } o.builder = o.builder.Schema(schema) + } else { + o.builder = o.builder.Local(f.ClientForMapping) } + cmdNamespace, _, err := f.DefaultNamespace() if err != nil { return err diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index 8593f14152..31eaa484f6 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -125,17 +125,13 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt return err } - mapper, _, err := f.UnstructuredObject() + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } - builder, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } - - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index 9b63f41200..50f32f4ca0 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -170,19 +170,15 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args } // Set up client based support. - mapper, _, err := f.UnstructuredObject() - if err != nil { - return err - } - - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } o.Mapper = mapper includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). diff --git a/pkg/kubectl/cmd/describe.go b/pkg/kubectl/cmd/describe.go index 993c74ceab..579d521de9 100644 --- a/pkg/kubectl/cmd/describe.go +++ b/pkg/kubectl/cmd/describe.go @@ -117,7 +117,7 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a return cmdutil.UsageErrorf(cmd, "Required resource not specified.") } - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } @@ -125,8 +125,8 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a // include the uninitialized objects by default // unless user explicitly set --include-uninitialized=false includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, true) - - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/drain.go b/pkg/kubectl/cmd/drain.go index 5a7c9db38b..80128d86c3 100644 --- a/pkg/kubectl/cmd/drain.go +++ b/pkg/kubectl/cmd/drain.go @@ -20,11 +20,12 @@ import ( "errors" "fmt" "io" - "k8s.io/apimachinery/pkg/util/json" "math" "strings" "time" + "k8s.io/apimachinery/pkg/util/json" + "github.com/jonboulle/clockwork" "github.com/spf13/cobra" @@ -217,7 +218,7 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error { return err } - r := o.Factory.NewBuilder(true). + r := o.Factory.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceNames("node", args[0]). Do() diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index ce5b74cdef..6ae4387376 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -126,7 +126,7 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri } mapper, typer := f.Object() - r := f.NewBuilder(true). + r := f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index 5ee488f3ad..d575af3144 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -166,14 +166,16 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ return nil } - selector := cmdutil.GetFlagString(cmd, "selector") - allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces") - showKind := cmdutil.GetFlagBool(cmd, "show-kind") - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } + selector := cmdutil.GetFlagString(cmd, "selector") + allNamespaces := cmdutil.GetFlagBool(cmd, "all-namespaces") + showKind := cmdutil.GetFlagBool(cmd, "show-kind") + builder := f.NewBuilder().Unstructured(f.UnstructuredClientForMapping, mapper, typer) + cmdNamespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err @@ -212,12 +214,8 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ includeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, includeUninitialized) if isWatch || isWatchOnly { - builder, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } - - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index 0819a5e633..e97de9ee8d 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -181,13 +181,8 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { changeCause := f.Command(cmd, false) - builder, err := f.NewUnstructuredBuilder(!o.local) - if err != nil { - return err - } - includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - b := builder. + b := f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). @@ -195,10 +190,22 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { 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.SelectorParam(o.selector). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). ResourceTypeOrNameArgs(o.all, o.resources...). Latest() + } else { + b = b.Local(f.ClientForMapping) } + one := false r := b.Do().IntoSingleItemImplied(&one) if err := r.Err(); err != nil { diff --git a/pkg/kubectl/cmd/logs.go b/pkg/kubectl/cmd/logs.go index 6881f1e65e..8392c95bab 100644 --- a/pkg/kubectl/cmd/logs.go +++ b/pkg/kubectl/cmd/logs.go @@ -192,7 +192,7 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm } if o.Object == nil { - builder := f.NewBuilder(true). + builder := f.NewBuilder(). NamespaceParam(o.Namespace).DefaultNamespace(). SingleResourceType() if o.ResourceArg != "" { diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index f0de9caa19..267e0139c0 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -150,14 +150,13 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin return fmt.Errorf("unable to parse %q: %v", patch, err) } - // TODO: fix --local to work with customresources without making use of the discovery client. - // https://github.com/kubernetes/kubernetes/issues/46722 - builder, err := f.NewUnstructuredBuilder(true) + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &options.FilenameOptions). diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index a23b0cab9b..330971c56d 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -120,17 +120,13 @@ func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str return fmt.Errorf("--timeout must have --force specified") } - mapper, _, err := f.UnstructuredObject() + mapper, typer, err := f.UnstructuredObject() if err != nil { return err } - builder, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } - - r := builder. + r := f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -250,12 +246,8 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s }) }) - builder, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } - - r = builder. + r = f.NewBuilder(). + Unstructured(f.UnstructuredClientForMapping, mapper, typer). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/rollingupdate.go b/pkg/kubectl/cmd/rollingupdate.go index be6c4d6e03..b8449042b5 100644 --- a/pkg/kubectl/cmd/rollingupdate.go +++ b/pkg/kubectl/cmd/rollingupdate.go @@ -199,7 +199,7 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args return err } - request := f.NewBuilder(true). + request := f.NewBuilder(). Schema(schema). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}). diff --git a/pkg/kubectl/cmd/rollout/rollout_history.go b/pkg/kubectl/cmd/rollout/rollout_history.go index 22f31e8e7c..a4fe03fba7 100644 --- a/pkg/kubectl/cmd/rollout/rollout_history.go +++ b/pkg/kubectl/cmd/rollout/rollout_history.go @@ -79,7 +79,7 @@ func RunHistory(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []str return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index 7753aabbdd..c4472b7a68 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -111,7 +111,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index 713c518912..72ea49e965 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -109,7 +109,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_status.go b/pkg/kubectl/cmd/rollout/rollout_status.go index e54f22030f..d817a81a6d 100644 --- a/pkg/kubectl/cmd/rollout/rollout_status.go +++ b/pkg/kubectl/cmd/rollout/rollout_status.go @@ -82,7 +82,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index c703924c42..7d1f0cba57 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -110,7 +110,7 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). ResourceTypeOrNameArgs(true, args...). diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index ae705796d8..6100002740 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -352,7 +352,7 @@ func RunRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *c if err != nil { return err } - r := f.NewBuilder(true). + r := f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). ResourceNames(obj.Mapping.Resource, name). diff --git a/pkg/kubectl/cmd/scale.go b/pkg/kubectl/cmd/scale.go index 950c55ba76..6e0c24c38d 100644 --- a/pkg/kubectl/cmd/scale.go +++ b/pkg/kubectl/cmd/scale.go @@ -99,7 +99,7 @@ func RunScale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin } mapper, _ := f.Object() - r := f.NewBuilder(true). + r := f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index 779a94e382..564285afa0 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -139,12 +139,13 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - builder := f.NewBuilder(!o.Local). + builder := f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). IncludeUninitialized(includeUninitialized). Flatten() + if !o.Local { builder = builder. SelectorParam(o.Selector). @@ -157,6 +158,8 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st if len(o.Resources) > 0 { return resource.LocalResourceError } + + builder = builder.Local(f.ClientForMapping) } 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 f26d087627..28f0d47a4c 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -143,7 +143,7 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args } includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - builder := f.NewBuilder(!o.Local). + builder := f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). @@ -162,6 +162,8 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args if len(args) > 0 { return resource.LocalResourceError } + + builder = builder.Local(f.ClientForMapping) } 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 895daf0ee9..56e0193777 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -123,7 +123,7 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ } includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - o.builder = f.NewBuilder(!o.local). + o.builder = f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.fileOptions). @@ -141,6 +141,8 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ if len(o.resources) > 0 { return resource.LocalResourceError } + + o.builder = o.builder.Local(f.ClientForMapping) } o.PrintObject = func(obj runtime.Object) error { diff --git a/pkg/kubectl/cmd/set/set_serviceaccount.go b/pkg/kubectl/cmd/set/set_serviceaccount.go index f983c17089..f767bce078 100644 --- a/pkg/kubectl/cmd/set/set_serviceaccount.go +++ b/pkg/kubectl/cmd/set/set_serviceaccount.go @@ -126,7 +126,7 @@ func (saConfig *serviceAccountConfig) Complete(f cmdutil.Factory, cmd *cobra.Com saConfig.serviceAccountName = args[len(args)-1] resources := args[:len(args)-1] includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - builder := f.NewBuilder(!saConfig.local).ContinueOnError(). + builder := f.NewBuilder().ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &saConfig.fileNameOptions). IncludeUninitialized(includeUninitialized). @@ -134,6 +134,8 @@ func (saConfig *serviceAccountConfig) Complete(f cmdutil.Factory, cmd *cobra.Com if !saConfig.local { builder.ResourceTypeOrNameArgs(saConfig.all, resources...). Latest() + } else { + builder = builder.Local(f.ClientForMapping) } saConfig.infos, err = builder.Do().Infos() if err != nil { diff --git a/pkg/kubectl/cmd/set/set_subject.go b/pkg/kubectl/cmd/set/set_subject.go index 7e148048e5..281f0097d0 100644 --- a/pkg/kubectl/cmd/set/set_subject.go +++ b/pkg/kubectl/cmd/set/set_subject.go @@ -125,7 +125,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] } includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) - builder := f.NewBuilder(!o.Local). + builder := f.NewBuilder(). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, &o.FilenameOptions). @@ -144,6 +144,8 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] if len(args) > 0 { return resource.LocalResourceError } + + builder = builder.Local(f.ClientForMapping) } o.Infos, err = builder.Do().Infos() diff --git a/pkg/kubectl/cmd/taint.go b/pkg/kubectl/cmd/taint.go index 76063cab6f..04578bbee9 100644 --- a/pkg/kubectl/cmd/taint.go +++ b/pkg/kubectl/cmd/taint.go @@ -148,7 +148,7 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com if o.taintsToAdd, o.taintsToRemove, err = taintutils.ParseTaints(taintArgs); err != nil { return cmdutil.UsageErrorf(cmd, err.Error()) } - o.builder = f.NewBuilder(true). + o.builder = f.NewBuilder(). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace() if o.selector != "" { diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 9306797453..236c0b76a0 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -29,7 +29,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/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" @@ -484,21 +483,9 @@ func (f *FakeFactory) PrinterForMapping(cmd *cobra.Command, isLocal bool, output return f.tf.Printer, f.tf.Err } -func (f *FakeFactory) NewBuilder(allowRemoteCalls bool) *resource.Builder { - return nil -} - -func (f *FakeFactory) NewUnstructuredBuilder(allowRemoteCalls bool) (*resource.Builder, error) { - if !allowRemoteCalls { - return f.NewBuilder(allowRemoteCalls), nil - } - - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return nil, err - } - - return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme), nil +func (f *FakeFactory) NewBuilder() *resource.Builder { + mapper, typer := f.Object() + return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) } func (f *FakeFactory) DefaultResourceFilterOptions(cmd *cobra.Command, withNamespace bool) *printers.PrintOptions { @@ -769,25 +756,11 @@ func (f *fakeAPIFactory) PrinterForMapping(cmd *cobra.Command, isLocal bool, out return f.tf.Printer, f.tf.Err } -func (f *fakeAPIFactory) NewBuilder(allowRemoteCalls bool) *resource.Builder { +func (f *fakeAPIFactory) NewBuilder() *resource.Builder { mapper, typer := f.Object() - return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)) } -func (f *fakeAPIFactory) NewUnstructuredBuilder(allowRemoteCalls bool) (*resource.Builder, error) { - if !allowRemoteCalls { - return f.NewBuilder(allowRemoteCalls), nil - } - - mapper, typer, err := f.UnstructuredObject() - if err != nil { - return nil, err - } - - return resource.NewBuilder(mapper, f.CategoryExpander(), typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme), nil -} - 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 2374ec2d8f..96cd207f9b 100644 --- a/pkg/kubectl/cmd/util/editor/editoptions.go +++ b/pkg/kubectl/cmd/util/editor/editoptions.go @@ -111,10 +111,7 @@ func (o *EditOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args [] return err } - b, err := f.NewUnstructuredBuilder(true) - if err != nil { - return err - } + b := f.NewBuilder().Unstructured(f.UnstructuredClientForMapping, mapper, typer) 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() diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 50fd5387a7..1de4133b1b 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -256,9 +256,7 @@ type BuilderFactory interface { // 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 - NewBuilder(allowRemoteCalls bool) *resource.Builder - // Resource builder for working with unstructured objects - NewUnstructuredBuilder(allowRemoteCalls bool) (*resource.Builder, error) + NewBuilder() *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 e3a270fee3..fdbe6db113 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -140,37 +140,13 @@ func (f *ring2Factory) PrintObject(cmd *cobra.Command, isLocal bool, mapper meta // NewBuilder returns a new resource builder. // Receives a bool flag and avoids remote calls if set to false -func (f *ring2Factory) NewBuilder(allowRemoteCalls bool) *resource.Builder { - var clientMapper resource.ClientMapper +func (f *ring2Factory) NewBuilder() *resource.Builder { clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping) mapper, typer := f.objectMappingFactory.Object() categoryExpander := f.objectMappingFactory.CategoryExpander() - if allowRemoteCalls { - clientMapper = clientMapperFunc - } else { - clientMapper = resource.DisabledClientForMapping{ClientMapper: clientMapperFunc} - } - - return resource.NewBuilder(mapper, categoryExpander, typer, clientMapper, f.clientAccessFactory.Decoder(true)) -} - -func (f *ring2Factory) NewUnstructuredBuilder(allowRemoteCalls bool) (*resource.Builder, error) { - if !allowRemoteCalls { - return f.NewBuilder(allowRemoteCalls), nil - } - - clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.UnstructuredClientForMapping) - - mapper, typer, err := f.objectMappingFactory.UnstructuredObject() - if err != nil { - return nil, err - } - - categoryExpander := f.objectMappingFactory.CategoryExpander() - return resource.NewBuilder(mapper, categoryExpander, typer, clientMapperFunc, unstructured.UnstructuredJSONScheme), nil - + return resource.NewBuilder(mapper, categoryExpander, typer, clientMapperFunc, f.clientAccessFactory.Decoder(true)) } // PluginLoader loads plugins from a path set by the KUBECTL_PLUGINS_PATH env var. diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 70a6093781..379d78acce 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -26,6 +26,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/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -67,6 +68,9 @@ type Builder struct { defaultNamespace bool requireNamespace bool + isLocal bool + isUnstructured bool + flatten bool latest bool @@ -82,6 +86,8 @@ type Builder struct { schema validation.Schema } +var LocalUnstructuredBuilderError = fmt.Errorf("Unstructured objects cannot be handled with a local builder - Local and Unstructured attributes cannot be used in conjunction") + var missingResourceError = fmt.Errorf(`You must provide one or more resources by argument or filename. Example resource specifications include: '-f rsrc.yaml' @@ -161,6 +167,35 @@ func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *Filename return b } +// Local wraps the builder's clientMapper in a DisabledClientMapperForMapping +func (b *Builder) Local(mapperFunc ClientMapperFunc) *Builder { + if b.isUnstructured { + b.errs = append(b.errs, LocalUnstructuredBuilderError) + return b + } + + b.isLocal = true + b.mapper.ClientMapper = DisabledClientForMapping{ClientMapper: ClientMapperFunc(mapperFunc)} + 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 { + if b.isLocal { + b.errs = append(b.errs, LocalUnstructuredBuilderError) + return b + } + + b.isUnstructured = true + 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 {