From 6fbcbc994f4d7fa613a1b8e15bf3f73880b704f6 Mon Sep 17 00:00:00 2001 From: David Eads Date: Fri, 27 Apr 2018 08:40:57 -0400 Subject: [PATCH 1/2] remove unnecessarily flexibiliy to simplify the resource builder --- pkg/kubectl/cmd/attach.go | 2 +- pkg/kubectl/cmd/auth/reconcile.go | 3 +- pkg/kubectl/cmd/autoscale.go | 16 ++++--- pkg/kubectl/cmd/certificates.go | 5 ++- pkg/kubectl/cmd/clusterinfo.go | 3 +- pkg/kubectl/cmd/convert.go | 2 +- pkg/kubectl/cmd/create/create.go | 10 ++--- pkg/kubectl/cmd/drain.go | 8 ++-- pkg/kubectl/cmd/expose.go | 14 +++---- pkg/kubectl/cmd/logs.go | 3 +- pkg/kubectl/cmd/portforward.go | 3 +- pkg/kubectl/cmd/rollout/rollout_history.go | 3 +- pkg/kubectl/cmd/rollout/rollout_pause.go | 3 +- pkg/kubectl/cmd/rollout/rollout_resume.go | 3 +- pkg/kubectl/cmd/rollout/rollout_status.go | 3 +- pkg/kubectl/cmd/rollout/rollout_undo.go | 3 +- pkg/kubectl/cmd/run.go | 14 +++---- pkg/kubectl/cmd/set/set_env.go | 10 ++--- pkg/kubectl/cmd/set/set_image.go | 9 ++-- pkg/kubectl/cmd/set/set_resources.go | 9 ++-- pkg/kubectl/cmd/set/set_selector.go | 7 ++-- pkg/kubectl/cmd/set/set_serviceaccount.go | 9 ++-- pkg/kubectl/cmd/set/set_subject.go | 7 ++-- pkg/kubectl/cmd/taint.go | 2 +- pkg/kubectl/cmd/testing/fake.go | 11 ++--- pkg/kubectl/cmd/util/factory_builder.go | 12 ++---- pkg/kubectl/cmd/util/factory_test.go | 9 ++-- pkg/kubectl/resource/builder.go | 42 +++++++++++-------- pkg/kubectl/resource/builder_test.go | 16 +++---- pkg/kubectl/resource/mapper.go | 17 +++----- pkg/kubectl/resource/selector.go | 10 ++--- pkg/kubectl/resource/visitor.go | 30 +++++++------ .../unstructured/unstructuredscheme/scheme.go | 8 ++++ 33 files changed, 154 insertions(+), 152 deletions(-) diff --git a/pkg/kubectl/cmd/attach.go b/pkg/kubectl/cmd/attach.go index 76a2705df7a..ced12cd3fcd 100644 --- a/pkg/kubectl/cmd/attach.go +++ b/pkg/kubectl/cmd/attach.go @@ -146,7 +146,7 @@ func (p *AttachOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn [ } builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). NamespaceParam(namespace).DefaultNamespace() switch len(argsIn) { diff --git a/pkg/kubectl/cmd/auth/reconcile.go b/pkg/kubectl/cmd/auth/reconcile.go index debd2787a8a..6df674ee580 100644 --- a/pkg/kubectl/cmd/auth/reconcile.go +++ b/pkg/kubectl/cmd/auth/reconcile.go @@ -23,6 +23,7 @@ import ( "github.com/golang/glog" "github.com/spf13/cobra" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/rbac" internalcoreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" internalrbacclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" @@ -95,7 +96,7 @@ func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index b9b548ca37e..03c01350ba2 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -197,7 +197,7 @@ func (o *AutoscaleOptions) Validate(cmd *cobra.Command) error { func (o *AutoscaleOptions) Run() error { r := o.Builder. - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(o.Namespace).DefaultNamespace(). FilenameParam(o.EnforceNamespace, o.FilenameOptions). @@ -231,13 +231,11 @@ func (o *AutoscaleOptions) Run() error { } resourceMapper := &resource.Mapper{ - ObjectTyper: o.Typer, - ObjectConverter: legacyscheme.Scheme, - RESTMapper: o.Mapper, - ClientMapper: resource.ClientMapperFunc(o.ClientForMapping), - Decoder: cmdutil.InternalVersionDecoder(), + RESTMapper: o.Mapper, + ClientMapper: resource.ClientMapperFunc(o.ClientForMapping), + Decoder: cmdutil.InternalVersionDecoder(), } - hpa, err := resourceMapper.InfoForObject(object, nil) + hpa, err := resourceMapper.InfoForObject(object, legacyscheme.Scheme, nil) if err != nil { return err } @@ -253,7 +251,7 @@ func (o *AutoscaleOptions) Run() error { if err != nil { return err } - return printer.PrintObj(hpa.AsVersioned(), o.Out) + return printer.PrintObj(hpa.AsVersioned(legacyscheme.Scheme), o.Out) } if err := kubectl.CreateOrUpdateAnnotation(o.CreateAnnotation, hpa.Object, cmdutil.InternalVersionJSONEncoder()); err != nil { @@ -270,7 +268,7 @@ func (o *AutoscaleOptions) Run() error { if err != nil { return err } - return printer.PrintObj(info.AsVersioned(), o.Out) + return printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/certificates.go b/pkg/kubectl/cmd/certificates.go index 83a940fef56..d12db1e5a32 100644 --- a/pkg/kubectl/cmd/certificates.go +++ b/pkg/kubectl/cmd/certificates.go @@ -22,6 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -203,7 +204,7 @@ func (o *CertificateOptions) RunCertificateDeny(force bool) error { func (options *CertificateOptions) modifyCertificateCondition(builder *resource.Builder, clientSet internalclientset.Interface, force bool, modify func(csr *certificates.CertificateSigningRequest) (*certificates.CertificateSigningRequest, bool)) error { var found int r := builder. - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). FilenameParam(false, &options.FilenameOptions). ResourceNames("certificatesigningrequest", options.csrNames...). @@ -227,7 +228,7 @@ func (options *CertificateOptions) modifyCertificateCondition(builder *resource. } found++ - return options.PrintObj(info.AsVersioned(), options.Out) + return options.PrintObj(info.AsVersioned(legacyscheme.Scheme), options.Out) }) if found == 0 { fmt.Fprintf(options.Out, "No resources found\n") diff --git a/pkg/kubectl/cmd/clusterinfo.go b/pkg/kubectl/cmd/clusterinfo.go index 41019c004bc..b908ca47704 100644 --- a/pkg/kubectl/cmd/clusterinfo.go +++ b/pkg/kubectl/cmd/clusterinfo.go @@ -24,6 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilnet "k8s.io/apimachinery/pkg/util/net" restclient "k8s.io/client-go/rest" + "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -95,7 +96,7 @@ func (o *ClusterInfoOptions) Run() error { // TODO use generalized labels once they are implemented (#341) b := o.Builder. - Internal(). + Internal(legacyscheme.Scheme). NamespaceParam(o.Namespace).DefaultNamespace(). LabelSelectorParam("kubernetes.io/cluster-service=true"). ResourceTypeOrNameArgs(false, []string{"services"}...). diff --git a/pkg/kubectl/cmd/convert.go b/pkg/kubectl/cmd/convert.go index a76c6a30a2e..7dc2cd4dfc0 100644 --- a/pkg/kubectl/cmd/convert.go +++ b/pkg/kubectl/cmd/convert.go @@ -129,7 +129,7 @@ func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err er // build the builder o.builder = f.NewBuilder(). - Internal(). + Internal(scheme.Scheme). LocalParam(o.local) if !o.local { schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate")) diff --git a/pkg/kubectl/cmd/create/create.go b/pkg/kubectl/cmd/create/create.go index 1bb06f423eb..dc028de11be 100644 --- a/pkg/kubectl/cmd/create/create.go +++ b/pkg/kubectl/cmd/create/create.go @@ -405,12 +405,10 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er return err } resourceMapper := &resource.Mapper{ - ObjectTyper: typer, - ObjectConverter: legacyscheme.Scheme, - RESTMapper: mapper, - ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), + RESTMapper: mapper, + ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), } - info, err := resourceMapper.InfoForObject(obj, nil) + info, err := resourceMapper.InfoForObject(obj, legacyscheme.Scheme, nil) if err != nil { return err } @@ -424,7 +422,7 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er } // ensure we pass a versioned object to the printer - obj = info.AsVersioned() + obj = info.AsVersioned(legacyscheme.Scheme) } else { if meta, err := meta.Accessor(obj); err == nil && nsOverriden { meta.SetNamespace(namespace) diff --git a/pkg/kubectl/cmd/drain.go b/pkg/kubectl/cmd/drain.go index cde9e048e7d..92fe50d6d8e 100644 --- a/pkg/kubectl/cmd/drain.go +++ b/pkg/kubectl/cmd/drain.go @@ -283,7 +283,7 @@ func (o *DrainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). NamespaceParam(o.Namespace).DefaultNamespace(). ResourceNames("nodes", args...). SingleResourceType(). @@ -741,7 +741,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Printf("error: %v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(), o.Out) + printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) } else { if !o.DryRun { helper := resource.NewHelper(o.restClient, nodeInfo.Mapping) @@ -767,7 +767,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(), o.Out) + printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) } } else { printer, err := o.ToPrinter("skipped") @@ -775,7 +775,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(), o.Out) + printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) } } diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index b7d92e552cc..d1fada8b5aa 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -201,7 +201,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) error { r := o.Builder. - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(o.Namespace).DefaultNamespace(). FilenameParam(o.EnforceNamespace, &o.FilenameOptions). @@ -312,13 +312,11 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro } resourceMapper := &resource.Mapper{ - ObjectTyper: o.Typer, - ObjectConverter: legacyscheme.Scheme, - RESTMapper: o.Mapper, - ClientMapper: resource.ClientMapperFunc(o.ClientForMapping), - Decoder: cmdutil.InternalVersionDecoder(), + RESTMapper: o.Mapper, + ClientMapper: resource.ClientMapperFunc(o.ClientForMapping), + Decoder: cmdutil.InternalVersionDecoder(), } - info, err = resourceMapper.InfoForObject(object, nil) + info, err = resourceMapper.InfoForObject(object, legacyscheme.Scheme, nil) if err != nil { return err } @@ -339,7 +337,7 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro return err } - return o.PrintObj(info.AsVersioned(), o.Out) + return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/logs.go b/pkg/kubectl/cmd/logs.go index 26e0ea034cf..810d7a862cf 100644 --- a/pkg/kubectl/cmd/logs.go +++ b/pkg/kubectl/cmd/logs.go @@ -30,6 +30,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" restclient "k8s.io/client-go/rest" + "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/validation" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -201,7 +202,7 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm if o.Object == nil { builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). NamespaceParam(o.Namespace).DefaultNamespace(). SingleResourceType() if o.ResourceArg != "" { diff --git a/pkg/kubectl/cmd/portforward.go b/pkg/kubectl/cmd/portforward.go index 9dc690d33c9..e2fa114c426 100644 --- a/pkg/kubectl/cmd/portforward.go +++ b/pkg/kubectl/cmd/portforward.go @@ -33,6 +33,7 @@ import ( restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/portforward" "k8s.io/client-go/transport/spdy" + "k8s.io/kubernetes/pkg/api/legacyscheme" api "k8s.io/kubernetes/pkg/apis/core" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -179,7 +180,7 @@ func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg } builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(o.Namespace).DefaultNamespace() diff --git a/pkg/kubectl/cmd/rollout/rollout_history.go b/pkg/kubectl/cmd/rollout/rollout_history.go index fb6ccbe90e7..6ca6e0855ce 100644 --- a/pkg/kubectl/cmd/rollout/rollout_history.go +++ b/pkg/kubectl/cmd/rollout/rollout_history.go @@ -20,6 +20,7 @@ import ( "fmt" "io" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -81,7 +82,7 @@ func RunHistory(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []str } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). 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 933b7686857..abb61ba69a0 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/set" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -111,7 +112,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). 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 a578292238a..77fd9d8700d 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -26,6 +26,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/set" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" @@ -109,7 +110,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). 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 4c11a70a78c..b42c1c9f5a4 100644 --- a/pkg/kubectl/cmd/rollout/rollout_status.go +++ b/pkg/kubectl/cmd/rollout/rollout_status.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/watch" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -85,7 +86,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). 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 c69251e6c7f..d56247e3ad7 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -22,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -112,7 +113,7 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). 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 12d3bb96780..30153dc913a 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -458,7 +458,7 @@ func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*R return err } r := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace(). ResourceNames(obj.Mapping.Resource, name). @@ -674,13 +674,11 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command versioned := obj if !o.DryRun { resourceMapper := &resource.Mapper{ - ObjectTyper: typer, - ObjectConverter: legacyscheme.Scheme, - RESTMapper: mapper, - ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), - Decoder: cmdutil.InternalVersionDecoder(), + RESTMapper: mapper, + ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), + Decoder: cmdutil.InternalVersionDecoder(), } - info, err := resourceMapper.InfoForObject(obj, nil) + info, err := resourceMapper.InfoForObject(obj, legacyscheme.Scheme, nil) if err != nil { return nil, err } @@ -694,7 +692,7 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command return nil, err } - versioned = info.AsVersioned() + versioned = info.AsVersioned(legacyscheme.Scheme) } return &RunObject{ Versioned: versioned, diff --git a/pkg/kubectl/cmd/set/set_env.go b/pkg/kubectl/cmd/set/set_env.go index 247f7b643e9..0333ff4753d 100644 --- a/pkg/kubectl/cmd/set/set_env.go +++ b/pkg/kubectl/cmd/set/set_env.go @@ -253,7 +253,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { if len(o.From) != 0 { b := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.Local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -321,7 +321,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { } b := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.Local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -339,7 +339,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { return err } patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) { - info.Object = info.AsVersioned() + info.Object = info.AsVersioned(legacyscheme.Scheme) _, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { resolutionErrorsEncountered := false containers, _ := selectContainers(spec.Containers, o.ContainerSelector) @@ -430,7 +430,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { } if o.Local || o.DryRun { - if err := o.PrintObj(patch.Info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } continue @@ -449,7 +449,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { return fmt.Errorf("at least one environment variable must be provided") } - if err := o.PrintObj(info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } } diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index 8387584bdef..1b271d762b2 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -19,6 +19,7 @@ package set import ( "fmt" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/printers" "github.com/golang/glog" @@ -160,7 +161,7 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.Local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -210,7 +211,7 @@ func (o *SetImageOptions) Run() error { patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) { transformed := false - info.Object = info.AsVersioned() + info.Object = info.AsVersioned(legacyscheme.Scheme) _, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { for name, image := range o.ContainerImages { var ( @@ -274,7 +275,7 @@ func (o *SetImageOptions) Run() error { } if o.Local || o.DryRun { - if err := o.PrintObj(patch.Info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } continue @@ -288,7 +289,7 @@ func (o *SetImageOptions) Run() error { } info.Refresh(obj, true) - if err := o.PrintObj(info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } } diff --git a/pkg/kubectl/cmd/set/set_resources.go b/pkg/kubectl/cmd/set/set_resources.go index d3b635c373b..1624d5fa531 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -172,7 +173,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.Local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -223,7 +224,7 @@ func (o *SetResourcesOptions) Run() error { allErrs := []error{} patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) { transformed := false - info.Object = info.AsVersioned() + info.Object = info.AsVersioned(legacyscheme.Scheme) _, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { containers, _ := selectContainers(spec.Containers, o.ContainerSelector) if len(containers) != 0 { @@ -276,7 +277,7 @@ func (o *SetResourcesOptions) Run() error { } if o.Local || o.DryRun { - if err := o.PrintObj(patch.Info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } continue @@ -289,7 +290,7 @@ func (o *SetResourcesOptions) Run() error { } info.Refresh(obj, true) - if err := o.PrintObj(info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } } diff --git a/pkg/kubectl/cmd/set/set_selector.go b/pkg/kubectl/cmd/set/set_selector.go index cc09ca728af..e9f473a1076 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/validation" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" @@ -149,7 +150,7 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) o.builder = f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -207,7 +208,7 @@ func (o *SetSelectorOptions) RunSelector() error { return r.Visit(func(info *resource.Info, err error) error { patch := &Patch{Info: info} CalculatePatch(patch, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) { - versioned := info.AsVersioned() + versioned := info.AsVersioned(legacyscheme.Scheme) patch.Info.Object = versioned selectErr := updateSelectorForObject(info.Object, *o.selector) if selectErr != nil { @@ -235,7 +236,7 @@ func (o *SetSelectorOptions) RunSelector() error { } info.Refresh(patched, true) - return o.PrintObj(patch.Info.AsVersioned(), o.Out) + return o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out) }) } diff --git a/pkg/kubectl/cmd/set/set_serviceaccount.go b/pkg/kubectl/cmd/set/set_serviceaccount.go index 91599acca91..414c8758c8d 100644 --- a/pkg/kubectl/cmd/set/set_serviceaccount.go +++ b/pkg/kubectl/cmd/set/set_serviceaccount.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" @@ -151,7 +152,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman resources := args[:len(args)-1] includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -173,7 +174,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman func (o *SetServiceAccountOptions) Run() error { patchErrs := []error{} patchFn := func(info *resource.Info) ([]byte, error) { - info.Object = info.AsVersioned() + info.Object = info.AsVersioned(legacyscheme.Scheme) _, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error { podSpec.ServiceAccountName = o.serviceAccountName return nil @@ -197,7 +198,7 @@ func (o *SetServiceAccountOptions) Run() error { continue } if o.local || o.dryRun { - if err := o.PrintObj(patch.Info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } continue @@ -209,7 +210,7 @@ func (o *SetServiceAccountOptions) Run() error { } info.Refresh(patched, true) - if err := o.PrintObj(info.AsVersioned(), o.Out); err != nil { + if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { return err } } diff --git a/pkg/kubectl/cmd/set/set_subject.go b/pkg/kubectl/cmd/set/set_subject.go index 5a976b7cc44..ab3aeab04fc 100644 --- a/pkg/kubectl/cmd/set/set_subject.go +++ b/pkg/kubectl/cmd/set/set_subject.go @@ -28,6 +28,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -136,7 +137,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) builder := f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). LocalParam(o.Local). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -232,7 +233,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error { transformed, err := updateSubjectForObject(info.Object, subjects, fn) if transformed && err == nil { // TODO: switch UpdatePodSpecForObject to work on v1.PodSpec - return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.AsVersioned()) + return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.AsVersioned(legacyscheme.Scheme)) } return nil, err }) @@ -265,7 +266,7 @@ func (o *SubjectOptions) Run(f cmdutil.Factory, fn updateSubjects) error { } info.Refresh(obj, true) - return o.PrintObj(info.AsVersioned(), o.Out) + return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) } return utilerrors.NewAggregate(allErrs) } diff --git a/pkg/kubectl/cmd/taint.go b/pkg/kubectl/cmd/taint.go index 2688ec94ce0..53aa62f82bb 100644 --- a/pkg/kubectl/cmd/taint.go +++ b/pkg/kubectl/cmd/taint.go @@ -151,7 +151,7 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com return cmdutil.UsageErrorf(cmd, err.Error()) } o.builder = f.NewBuilder(). - Internal(). + Internal(legacyscheme.Scheme). ContinueOnError(). NamespaceParam(namespace).DefaultNamespace() if o.selector != "" { diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index e745da1a34a..ff27f173c88 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -342,19 +342,16 @@ func (f *TestFactory) Command(*cobra.Command, bool) string { } func (f *TestFactory) NewBuilder() *resource.Builder { - mapper, typer := f.Object() + mapper, _ := f.Object() return resource.NewBuilder( &resource.Mapper{ - RESTMapper: mapper, - ObjectTyper: typer, - ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), - ObjectConverter: legacyscheme.Scheme, - Decoder: cmdutil.InternalVersionDecoder(), + RESTMapper: mapper, + ClientMapper: resource.ClientMapperFunc(f.ClientForMapping), + Decoder: cmdutil.InternalVersionDecoder(), }, &resource.Mapper{ RESTMapper: mapper, - ObjectTyper: typer, ClientMapper: resource.ClientMapperFunc(f.UnstructuredClientForMapping), Decoder: unstructured.UnstructuredJSONScheme, }, diff --git a/pkg/kubectl/cmd/util/factory_builder.go b/pkg/kubectl/cmd/util/factory_builder.go index b837f1330bc..88472032822 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/dynamic" scaleclient "k8s.io/client-go/scale" - "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/plugins" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -48,7 +47,7 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac // NewBuilder returns a new resource builder for structured api objects. func (f *ring2Factory) NewBuilder() *resource.Builder { clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping) - mapper, typer := f.objectMappingFactory.Object() + mapper, _ := f.objectMappingFactory.Object() unstructuredClientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.UnstructuredClientForMapping) @@ -56,15 +55,12 @@ func (f *ring2Factory) NewBuilder() *resource.Builder { return resource.NewBuilder( &resource.Mapper{ - RESTMapper: mapper, - ObjectTyper: typer, - ObjectConverter: legacyscheme.Scheme, - ClientMapper: clientMapperFunc, - Decoder: InternalVersionDecoder(), + RESTMapper: mapper, + ClientMapper: clientMapperFunc, + Decoder: InternalVersionDecoder(), }, &resource.Mapper{ RESTMapper: mapper, - ObjectTyper: typer, ClientMapper: unstructuredClientMapperFunc, Decoder: unstructured.UnstructuredJSONScheme, }, diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index 30aad3e2d44..409a834dbcc 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -34,7 +34,6 @@ import ( "k8s.io/apimachinery/pkg/watch" manualfake "k8s.io/client-go/rest/fake" testcore "k8s.io/client-go/testing" - "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/testapi" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" @@ -474,11 +473,9 @@ func TestDiscoveryReplaceAliases(t *testing.T) { mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds) b := resource.NewBuilder( &resource.Mapper{ - RESTMapper: mapper, - ObjectTyper: legacyscheme.Scheme, - ObjectConverter: legacyscheme.Scheme, - ClientMapper: fakeClient(), - Decoder: testapi.Default.Codec(), + RESTMapper: mapper, + ClientMapper: fakeClient(), + Decoder: testapi.Default.Codec(), }, nil, categories.LegacyCategoryExpander, diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index ed6f8d9c8a7..b6979d7afe7 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -26,7 +26,9 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" @@ -50,6 +52,10 @@ type Builder struct { internal *Mapper unstructured *Mapper + // objectTyper is statically determinant per-command invocation based on your internal or unstructured choice + // it does not ever need to rely upon discovery. + objectTyper runtime.ObjectTyper + errs []error paths []Visitor @@ -186,8 +192,8 @@ func (b *Builder) Unstructured() *Builder { return b } b.mapper = b.unstructured - // the unstructured mapper doesn't do any conversion - b.mapper.ObjectConverter = nil + + b.objectTyper = unstructuredscheme.NewUnstructuredObjectTyper() return b } @@ -196,7 +202,7 @@ func (b *Builder) Unstructured() *Builder { // to the server will not be seen by the client code and may result in failure. Only // use this mode when working offline, or when generating patches to send to the server. // Use Unstructured if you are reading an object and performing a POST or PUT. -func (b *Builder) Internal() *Builder { +func (b *Builder) Internal(typer runtime.ObjectTyper) *Builder { if b.internal == nil { b.errs = append(b.errs, fmt.Errorf("no internal mapper provided")) return b @@ -206,6 +212,8 @@ func (b *Builder) Internal() *Builder { return b } b.mapper = b.internal + + b.objectTyper = typer return b } @@ -762,7 +770,7 @@ func (b *Builder) visitBySelector() *Result { if mapping.Scope.Name() != meta.RESTScopeNameNamespace { selectorNamespace = "" } - visitors = append(visitors, NewSelector(client, mapping, b.mapper.ObjectConverter, selectorNamespace, labelSelector, fieldSelector, b.export, b.includeUninitialized, b.limitChunks)) + visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, labelSelector, fieldSelector, b.export, b.includeUninitialized, b.limitChunks)) } if b.continueOnError { result.visitor = EagerVisitorList(visitors) @@ -837,12 +845,11 @@ func (b *Builder) visitByResource() *Result { } info := &Info{ - Client: client, - Mapping: mapping, - toVersionedObjectConverter: b.mapper.ObjectConverter, - Namespace: selectorNamespace, - Name: tuple.Name, - Export: b.export, + Client: client, + Mapping: mapping, + Namespace: selectorNamespace, + Name: tuple.Name, + Export: b.export, } items = append(items, info) } @@ -903,12 +910,11 @@ func (b *Builder) visitByName() *Result { visitors := []Visitor{} for _, name := range b.names { info := &Info{ - Client: client, - Mapping: mapping, - toVersionedObjectConverter: b.mapper.ObjectConverter, - Namespace: selectorNamespace, - Name: name, - Export: b.export, + Client: client, + Mapping: mapping, + Namespace: selectorNamespace, + Name: name, + Export: b.export, } visitors = append(visitors, info) } @@ -944,7 +950,7 @@ func (b *Builder) visitByPaths() *Result { if b.latest { // must flatten lists prior to fetching if b.flatten { - visitors = NewFlattenListVisitor(visitors, b.mapper) + visitors = NewFlattenListVisitor(visitors, b.objectTyper, b.mapper) } // must set namespace prior to fetching if b.defaultNamespace { @@ -975,7 +981,7 @@ func (b *Builder) Do() *Result { return r } if b.flatten { - r.visitor = NewFlattenListVisitor(r.visitor, b.mapper) + r.visitor = NewFlattenListVisitor(r.visitor, b.objectTyper, b.mapper) } helpers := []VisitorFunc{} if b.defaultNamespace { diff --git a/pkg/kubectl/resource/builder_test.go b/pkg/kubectl/resource/builder_test.go index 32b8188263b..aa6aab61e20 100644 --- a/pkg/kubectl/resource/builder_test.go +++ b/pkg/kubectl/resource/builder_test.go @@ -46,8 +46,12 @@ import ( "k8s.io/client-go/rest/fake" restclientwatch "k8s.io/client-go/rest/watch" utiltesting "k8s.io/client-go/util/testing" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl/categories" "k8s.io/kubernetes/pkg/kubectl/scheme" + + // install the pod scheme into the legacy scheme for test typer resolution + _ "k8s.io/kubernetes/pkg/apis/core/install" ) var ( @@ -270,15 +274,13 @@ func newDefaultBuilder() *Builder { func newDefaultBuilderWith(client ClientMapper) *Builder { return NewBuilder( &Mapper{ - RESTMapper: restmapper, - ObjectTyper: scheme.Scheme, - ObjectConverter: scheme.Scheme, - ClientMapper: client, - Decoder: corev1Codec, + RESTMapper: restmapper, + ClientMapper: client, + Decoder: corev1Codec, }, nil, categories.LegacyCategoryExpander, - ).Internal() + ).Internal(legacyscheme.Scheme) } func TestPathBuilderAndVersionedObjectNotDefaulted(t *testing.T) { @@ -297,7 +299,7 @@ func TestPathBuilderAndVersionedObjectNotDefaulted(t *testing.T) { if info.Name != "update-demo-kitten" || info.Namespace != "" || info.Object == nil { t.Errorf("unexpected info: %#v", info) } - obj := info.AsVersioned() + obj := info.AsVersioned(legacyscheme.Scheme) version, ok := obj.(*v1.ReplicationController) // versioned object does not have defaulting applied if obj == nil || !ok || version.Spec.Replicas != nil { diff --git a/pkg/kubectl/resource/mapper.go b/pkg/kubectl/resource/mapper.go index 391a1d45296..61f1ee1c56c 100644 --- a/pkg/kubectl/resource/mapper.go +++ b/pkg/kubectl/resource/mapper.go @@ -28,9 +28,6 @@ import ( // Mapper is a convenience struct for holding references to the interfaces // needed to create Info for arbitrary objects. type Mapper struct { - ObjectTyper runtime.ObjectTyper - ObjectConverter runtime.ObjectConvertor - RESTMapper meta.RESTMapper ClientMapper ClientMapper Decoder runtime.Decoder @@ -60,9 +57,8 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { resourceVersion, _ := metadataAccessor.ResourceVersion(obj) return &Info{ - Client: client, - Mapping: mapping, - toVersionedObjectConverter: m.ObjectConverter, + Client: client, + Mapping: mapping, Source: source, Namespace: namespace, @@ -76,8 +72,8 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { // InfoForObject creates an Info object for the given Object. An error is returned // if the object cannot be introspected. Name and namespace will be set into Info // if the mapping's MetadataAccessor can retrieve them. -func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []schema.GroupVersionKind) (*Info, error) { - groupVersionKinds, _, err := m.ObjectTyper.ObjectKinds(obj) +func (m *Mapper) InfoForObject(obj runtime.Object, typer runtime.ObjectTyper, preferredGVKs []schema.GroupVersionKind) (*Info, error) { + groupVersionKinds, _, err := typer.ObjectKinds(obj) if err != nil { return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err) } @@ -100,9 +96,8 @@ func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []schema.GroupV namespace, _ := metadataAccessor.Namespace(obj) resourceVersion, _ := metadataAccessor.ResourceVersion(obj) return &Info{ - Client: client, - Mapping: mapping, - toVersionedObjectConverter: m.ObjectConverter, + Client: client, + Mapping: mapping, Namespace: namespace, Name: name, diff --git a/pkg/kubectl/resource/selector.go b/pkg/kubectl/resource/selector.go index ce973484640..f36508bd4a9 100644 --- a/pkg/kubectl/resource/selector.go +++ b/pkg/kubectl/resource/selector.go @@ -22,7 +22,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" ) @@ -30,7 +29,6 @@ import ( type Selector struct { Client RESTClient Mapping *meta.RESTMapping - ObjectConverter runtime.ObjectConvertor Namespace string LabelSelector string FieldSelector string @@ -40,11 +38,10 @@ type Selector struct { } // NewSelector creates a resource selector which hides details of getting items by their label selector. -func NewSelector(client RESTClient, mapping *meta.RESTMapping, objectConverter runtime.ObjectConvertor, namespace, labelSelector, fieldSelector string, export, includeUninitialized bool, limitChunks int64) *Selector { +func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace, labelSelector, fieldSelector string, export, includeUninitialized bool, limitChunks int64) *Selector { return &Selector{ Client: client, Mapping: mapping, - ObjectConverter: objectConverter, Namespace: namespace, LabelSelector: labelSelector, FieldSelector: fieldSelector, @@ -94,9 +91,8 @@ func (r *Selector) Visit(fn VisitorFunc) error { resourceVersion, _ := metadataAccessor.ResourceVersion(list) nextContinueToken, _ := metadataAccessor.Continue(list) info := &Info{ - Client: r.Client, - Mapping: r.Mapping, - toVersionedObjectConverter: r.ObjectConverter, + Client: r.Client, + Mapping: r.Mapping, Namespace: r.Namespace, ResourceVersion: resourceVersion, diff --git a/pkg/kubectl/resource/visitor.go b/pkg/kubectl/resource/visitor.go index ded1dda3b59..cd6721f8dc2 100644 --- a/pkg/kubectl/resource/visitor.go +++ b/pkg/kubectl/resource/visitor.go @@ -77,8 +77,6 @@ type Info struct { // Mapping may be nil if the object has no available metadata, but is still parseable // from disk. Mapping *meta.RESTMapping - // ObjectConverter allows conversion - toVersionedObjectConverter runtime.ObjectConvertor // Namespace will be set if the object is namespaced and has a specified value. Namespace string @@ -183,17 +181,16 @@ func (i *Info) ResourceMapping() *meta.RESTMapping { } // Versioned returns the object as a Go type in the mapping's version or returns an error. -func (i *Info) Versioned() (runtime.Object, error) { - return i.toVersionedObjectConverter.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion()) +func (i *Info) versioned(convertor runtime.ObjectConvertor) (runtime.Object, error) { + return convertor.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion()) } // AsVersioned returns the object as a Go object in the external form if possible (matching the // group version kind of the mapping, or i.Object if it cannot be converted. -func (i *Info) AsVersioned() runtime.Object { - if i.toVersionedObjectConverter == nil { - panic("attempt to call AsVersioned object using .Unstructured builder") - } - if obj, err := i.Versioned(); err == nil { +// Deprecated this function will be removed once calling code is updated to indicate the correct +// negoticatedserializers during contruction of the builder +func (i *Info) AsVersioned(convertor runtime.ObjectConvertor) runtime.Object { + if obj, err := i.versioned(convertor); err == nil { return obj } return i.Object @@ -389,18 +386,19 @@ func (v ContinueOnErrorVisitor) Visit(fn VisitorFunc) error { // the visit. // TODO: allow errors to be aggregated? type FlattenListVisitor struct { - Visitor - *Mapper + visitor Visitor + typer runtime.ObjectTyper + mapper *Mapper } // NewFlattenListVisitor creates a visitor that will expand list style runtime.Objects // into individual items and then visit them individually. -func NewFlattenListVisitor(v Visitor, mapper *Mapper) Visitor { - return FlattenListVisitor{v, mapper} +func NewFlattenListVisitor(v Visitor, typer runtime.ObjectTyper, mapper *Mapper) Visitor { + return FlattenListVisitor{v, typer, mapper} } func (v FlattenListVisitor) Visit(fn VisitorFunc) error { - return v.Visitor.Visit(func(info *Info, err error) error { + return v.visitor.Visit(func(info *Info, err error) error { if err != nil { return err } @@ -411,7 +409,7 @@ func (v FlattenListVisitor) Visit(fn VisitorFunc) error { if err != nil { return fn(info, nil) } - if errs := runtime.DecodeList(items, v.Mapper.Decoder); len(errs) > 0 { + if errs := runtime.DecodeList(items, v.mapper.Decoder); len(errs) > 0 { return utilerrors.NewAggregate(errs) } @@ -422,7 +420,7 @@ func (v FlattenListVisitor) Visit(fn VisitorFunc) error { } for i := range items { - item, err := v.InfoForObject(items[i], preferredGVKs) + item, err := v.mapper.InfoForObject(items[i], v.typer, preferredGVKs) if err != nil { return err } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme/scheme.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme/scheme.go index d1479934bbe..ab2574e8287 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme/scheme.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme/scheme.go @@ -89,6 +89,14 @@ func (t unstructuredObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.Group if _, ok := obj.(runtime.Unstructured); !ok { return nil, false, fmt.Errorf("cannot type %T", obj) } + gvk := obj.GetObjectKind().GroupVersionKind() + if len(gvk.Kind) == 0 { + return nil, false, runtime.NewMissingKindErr("object has no kind field ") + } + if len(gvk.Version) == 0 { + return nil, false, runtime.NewMissingVersionErr("object has no apiVersion field") + } + return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil } From 5432ef5c4557fc47c97f631ac3b23738bbd27115 Mon Sep 17 00:00:00 2001 From: David Eads Date: Fri, 27 Apr 2018 09:27:19 -0400 Subject: [PATCH 2/2] divide statically known typer from dynamically derive restmapper --- pkg/kubectl/cmd/apply_set_last_applied.go | 3 +-- pkg/kubectl/cmd/auth/BUILD | 1 + pkg/kubectl/cmd/auth/cani.go | 2 +- pkg/kubectl/cmd/autoscale.go | 4 +-- pkg/kubectl/cmd/create/create.go | 5 ++-- .../cmd/create/create_clusterrole_test.go | 2 +- pkg/kubectl/cmd/create/create_role.go | 2 +- pkg/kubectl/cmd/create/create_role_test.go | 2 +- pkg/kubectl/cmd/drain_test.go | 2 +- pkg/kubectl/cmd/explain.go | 2 +- pkg/kubectl/cmd/expose.go | 3 +-- pkg/kubectl/cmd/rollout/BUILD | 2 +- pkg/kubectl/cmd/rollout/rollout_pause.go | 4 +-- pkg/kubectl/cmd/rollout/rollout_resume.go | 4 +-- pkg/kubectl/cmd/rollout/rollout_undo.go | 4 +-- pkg/kubectl/cmd/run.go | 5 ++-- pkg/kubectl/cmd/set/set_selector.go | 2 +- pkg/kubectl/cmd/testing/fake.go | 7 +++--- pkg/kubectl/cmd/util/factory.go | 2 +- pkg/kubectl/cmd/util/factory_builder.go | 4 +-- .../cmd/util/factory_object_mapping.go | 21 ++++------------ pkg/kubectl/resource/BUILD | 3 +++ pkg/kubectl/resource/builder.go | 5 ++++ pkg/kubectl/resource/visitor.go | 2 +- .../k8s.io/apimachinery/pkg/api/meta/lazy.go | 25 +++---------------- test/integration/apiserver/print_test.go | 2 +- .../etcd/etcd_storage_path_test.go | 2 +- 27 files changed, 47 insertions(+), 75 deletions(-) diff --git a/pkg/kubectl/cmd/apply_set_last_applied.go b/pkg/kubectl/cmd/apply_set_last_applied.go index aa2b3cbd00a..5f91266d1eb 100644 --- a/pkg/kubectl/cmd/apply_set_last_applied.go +++ b/pkg/kubectl/cmd/apply_set_last_applied.go @@ -46,7 +46,6 @@ type SetLastAppliedOptions struct { Selector string InfoList []*resource.Info Mapper meta.RESTMapper - Typer runtime.ObjectTyper Namespace string EnforceNamespace bool DryRun bool @@ -117,7 +116,7 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) o.Output = cmdutil.GetFlagString(cmd, "output") o.ShortOutput = o.Output == "name" - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() var err error o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace() diff --git a/pkg/kubectl/cmd/auth/BUILD b/pkg/kubectl/cmd/auth/BUILD index 5aa487c498c..987683660a3 100644 --- a/pkg/kubectl/cmd/auth/BUILD +++ b/pkg/kubectl/cmd/auth/BUILD @@ -16,6 +16,7 @@ go_library( "//build/visible_to:pkg_kubectl_cmd_auth_CONSUMERS", ], deps = [ + "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/authorization:go_default_library", "//pkg/apis/rbac:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/authorization/internalversion:go_default_library", diff --git a/pkg/kubectl/cmd/auth/cani.go b/pkg/kubectl/cmd/auth/cani.go index 2622addaf6b..7640a473f48 100644 --- a/pkg/kubectl/cmd/auth/cani.go +++ b/pkg/kubectl/cmd/auth/cani.go @@ -127,7 +127,7 @@ func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error { break } resourceTokens := strings.SplitN(args[1], "/", 2) - restMapper, _ := f.Object() + restMapper := f.RESTMapper() o.Resource = o.resourceFor(restMapper, resourceTokens[0]) if len(resourceTokens) > 1 { o.ResourceName = resourceTokens[1] diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index 03c01350ba2..a6452977cf6 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -68,7 +67,6 @@ type AutoscaleOptions struct { EnforceNamespace bool Mapper meta.RESTMapper - Typer runtime.ObjectTyper ClientForMapping func(mapping *meta.RESTMapping) (resource.RESTClient, error) GeneratorFunc func(string, *meta.RESTMapping) (kubectl.StructuredGenerator, error) @@ -133,7 +131,7 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag) o.Builder = f.NewBuilder() o.CanBeAutoscaled = f.CanBeAutoscaled - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() o.ClientForMapping = f.ClientForMapping o.BuilderArgs = args o.RecordFlags.Complete(f.Command(cmd, false)) diff --git a/pkg/kubectl/cmd/create/create.go b/pkg/kubectl/cmd/create/create.go index dc028de11be..d4524e39790 100644 --- a/pkg/kubectl/cmd/create/create.go +++ b/pkg/kubectl/cmd/create/create.go @@ -389,9 +389,10 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er if err != nil { return err } - mapper, typer := f.Object() + mapper := f.RESTMapper() if !options.DryRun { - gvks, _, err := typer.ObjectKinds(obj) + // create subcommands have compiled knowledge of things they create, so type them directly + gvks, _, err := legacyscheme.Scheme.ObjectKinds(obj) if err != nil { return err } diff --git a/pkg/kubectl/cmd/create/create_clusterrole_test.go b/pkg/kubectl/cmd/create/create_clusterrole_test.go index 69ea254e755..caddc639e13 100644 --- a/pkg/kubectl/cmd/create/create_clusterrole_test.go +++ b/pkg/kubectl/cmd/create/create_clusterrole_test.go @@ -437,7 +437,7 @@ func TestClusterRoleValidate(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - test.clusterRoleOptions.Mapper, _ = tf.Object() + test.clusterRoleOptions.Mapper = tf.RESTMapper() err := test.clusterRoleOptions.Validate() if test.expectErr && err == nil { t.Errorf("%s: expect error happens, but validate passes.", name) diff --git a/pkg/kubectl/cmd/create/create_role.go b/pkg/kubectl/cmd/create/create_role.go index f3271e4c5fc..29895d51821 100644 --- a/pkg/kubectl/cmd/create/create_role.go +++ b/pkg/kubectl/cmd/create/create_role.go @@ -205,7 +205,7 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args o.ResourceNames = resourceNames // Complete other options for Run. - o.Mapper, _ = f.Object() + o.Mapper = f.RESTMapper() o.DryRun = cmdutil.GetDryRunFlag(cmd) o.OutputFormat = cmdutil.GetFlagString(cmd, "output") diff --git a/pkg/kubectl/cmd/create/create_role_test.go b/pkg/kubectl/cmd/create/create_role_test.go index e7937197f96..c1a75a3770e 100644 --- a/pkg/kubectl/cmd/create/create_role_test.go +++ b/pkg/kubectl/cmd/create/create_role_test.go @@ -339,7 +339,7 @@ func TestValidate(t *testing.T) { } for name, test := range tests { - test.roleOptions.Mapper, _ = tf.Object() + test.roleOptions.Mapper = tf.RESTMapper() err := test.roleOptions.Validate() if test.expectErr && err == nil { t.Errorf("%s: expect error happens but validate passes.", name) diff --git a/pkg/kubectl/cmd/drain_test.go b/pkg/kubectl/cmd/drain_test.go index 86885aa1f01..34670e488dc 100644 --- a/pkg/kubectl/cmd/drain_test.go +++ b/pkg/kubectl/cmd/drain_test.go @@ -836,7 +836,7 @@ func TestDeletePods(t *testing.T) { o := DrainOptions{ PrintFlags: printers.NewPrintFlags("drained"), } - o.mapper, _ = tf.Object() + o.mapper = tf.RESTMapper() o.Out = os.Stdout o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) { diff --git a/pkg/kubectl/cmd/explain.go b/pkg/kubectl/cmd/explain.go index 58e10c5922f..cf4793fee65 100644 --- a/pkg/kubectl/cmd/explain.go +++ b/pkg/kubectl/cmd/explain.go @@ -94,7 +94,7 @@ func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { o.Recursive = cmdutil.GetFlagBool(cmd, "recursive") o.ApiVersion = cmdutil.GetFlagString(cmd, "api-version") - o.Mapper, _ = f.Object() + o.Mapper = f.RESTMapper() var err error o.Schema, err = f.OpenAPISchema() diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index d1fada8b5aa..a5d64a9589e 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -96,7 +96,6 @@ type ExposeServiceOptions struct { Namespace string Mapper meta.RESTMapper - Typer runtime.ObjectTyper Builder *resource.Builder @@ -188,7 +187,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e o.MapBasedSelectorForObject = f.MapBasedSelectorForObject o.PortsForObject = f.PortsForObject o.ProtocolsForObject = f.ProtocolsForObject - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() o.LabelsForObject = f.LabelsForObject o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace() diff --git a/pkg/kubectl/cmd/rollout/BUILD b/pkg/kubectl/cmd/rollout/BUILD index ed141fe1bed..df24db89891 100644 --- a/pkg/kubectl/cmd/rollout/BUILD +++ b/pkg/kubectl/cmd/rollout/BUILD @@ -19,6 +19,7 @@ go_library( "//build/visible_to:pkg_kubectl_cmd_rollout_CONSUMERS", ], deps = [ + "//pkg/api/legacyscheme:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd/set:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library", @@ -29,7 +30,6 @@ go_library( "//vendor/github.com/renstrom/dedent:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/watch:go_default_library", diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index abb61ba69a0..80716236227 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -42,7 +41,6 @@ type PauseConfig struct { Pauser func(info *resource.Info) ([]byte, error) Mapper meta.RESTMapper - Typer runtime.ObjectTyper Infos []*resource.Info Out io.Writer @@ -101,7 +99,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i return cmdutil.UsageErrorf(cmd, "%s", cmd.Use) } - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() o.Pauser = f.Pauser o.Out = out diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index 77fd9d8700d..65ee72765b8 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -23,7 +23,6 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/kubernetes/pkg/api/legacyscheme" @@ -42,7 +41,6 @@ type ResumeConfig struct { Resumer func(object *resource.Info) ([]byte, error) Mapper meta.RESTMapper - Typer runtime.ObjectTyper Infos []*resource.Info Out io.Writer @@ -99,7 +97,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out return cmdutil.UsageErrorf(cmd, "%s", cmd.Use) } - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() o.Resumer = f.Resumer o.Out = out diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index d56247e3ad7..903ad1e328d 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -20,7 +20,6 @@ import ( "io" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/runtime" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl" @@ -39,7 +38,6 @@ type UndoOptions struct { Rollbackers []kubectl.Rollbacker Mapper meta.RESTMapper - Typer runtime.ObjectTyper Infos []*resource.Info ToRevision int64 DryRun bool @@ -103,7 +101,7 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io } o.ToRevision = cmdutil.GetFlagInt64(cmd, "to-revision") - o.Mapper, o.Typer = f.Object() + o.Mapper = f.RESTMapper() o.Out = out o.DryRun = cmdutil.GetDryRunFlag(cmd) diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 30153dc913a..a544b4290f4 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -643,8 +643,9 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command return nil, err } - mapper, typer := f.Object() - groupVersionKinds, _, err := typer.ObjectKinds(obj) + mapper := f.RESTMapper() + // run has compiled knowledge of the thing is is creating + groupVersionKinds, _, err := legacyscheme.Scheme.ObjectKinds(obj) if err != nil { return nil, err } diff --git a/pkg/kubectl/cmd/set/set_selector.go b/pkg/kubectl/cmd/set/set_selector.go index e9f473a1076..ad181a452af 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -140,7 +140,7 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg return err } - mapper, _ := f.Object() + mapper := f.RESTMapper() o.mapper = mapper o.resources, o.selector, err = getResourcesAndSelector(args) diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index ff27f173c88..ad7c9fa7c02 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -342,7 +342,7 @@ func (f *TestFactory) Command(*cobra.Command, bool) string { } func (f *TestFactory) NewBuilder() *resource.Builder { - mapper, _ := f.Object() + mapper := f.RESTMapper() return resource.NewBuilder( &resource.Mapper{ @@ -430,7 +430,7 @@ func (f *TestFactory) ClientSetForVersion(requiredVersion *schema.GroupVersion) return f.ClientSet() } -func (f *TestFactory) Object() (meta.RESTMapper, runtime.ObjectTyper) { +func (f *TestFactory) RESTMapper() meta.RESTMapper { groupResources := testDynamicResources() mapper := discovery.NewRESTMapper( groupResources, @@ -457,10 +457,9 @@ func (f *TestFactory) Object() (meta.RESTMapper, runtime.ObjectTyper) { } // TODO: should probably be the external scheme - typer := discovery.NewUnstructuredObjectTyper(groupResources, legacyscheme.Scheme) fakeDs := &fakeCachedDiscoveryClient{} expander := cmdutil.NewShortcutExpander(mapper, fakeDs) - return expander, typer + return expander } func (f *TestFactory) LogsForObject(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error) { diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 167f9f2cef7..87da23dba8d 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -164,7 +164,7 @@ type ClientAccessFactory interface { // Generally they provide object typing and functions that build requests based on the negotiated clients. type ObjectMappingFactory interface { // Returns interfaces for dealing with arbitrary runtime.Objects. - Object() (meta.RESTMapper, runtime.ObjectTyper) + RESTMapper() meta.RESTMapper // Returns interface for expanding categories like `all`. CategoryExpander() categories.CategoryExpander // Returns a RESTClient for working with the specified RESTMapping or an error. This is intended diff --git a/pkg/kubectl/cmd/util/factory_builder.go b/pkg/kubectl/cmd/util/factory_builder.go index 88472032822..c5363e25515 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -47,7 +47,7 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac // NewBuilder returns a new resource builder for structured api objects. func (f *ring2Factory) NewBuilder() *resource.Builder { clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping) - mapper, _ := f.objectMappingFactory.Object() + mapper := f.objectMappingFactory.RESTMapper() unstructuredClientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.UnstructuredClientForMapping) @@ -97,7 +97,7 @@ func (f *ring2Factory) ScaleClient() (scaleclient.ScalesGetter, error) { return nil, err } resolver := scaleclient.NewDiscoveryScaleKindResolver(discoClient) - mapper, _ := f.objectMappingFactory.Object() + mapper := f.objectMappingFactory.RESTMapper() return scaleclient.New(restClient, mapper, dynamic.LegacyAPIPathResolverFunc, resolver), nil } diff --git a/pkg/kubectl/cmd/util/factory_object_mapping.go b/pkg/kubectl/cmd/util/factory_object_mapping.go index b40f75a123a..b47340fe903 100644 --- a/pkg/kubectl/cmd/util/factory_object_mapping.go +++ b/pkg/kubectl/cmd/util/factory_object_mapping.go @@ -76,34 +76,23 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp // the built in mapper if necessary. It supports unstructured objects either way, since // the underlying Scheme supports Unstructured. The mapper will return converters that can // convert versioned types to unstructured and back. -func (f *ring1Factory) objectLoader() (meta.RESTMapper, runtime.ObjectTyper, error) { +func (f *ring1Factory) restMapper() (meta.RESTMapper, error) { discoveryClient, err := f.clientAccessFactory.DiscoveryClient() if err != nil { glog.V(3).Infof("Unable to get a discovery client to find server resources, falling back to hardcoded types: %v", err) - return legacyscheme.Registry.RESTMapper(), legacyscheme.Scheme, nil - } - - groupResources, err := discovery.GetAPIGroupResources(discoveryClient) - if err != nil && !discoveryClient.Fresh() { - discoveryClient.Invalidate() - groupResources, err = discovery.GetAPIGroupResources(discoveryClient) - } - if err != nil { - glog.V(3).Infof("Unable to retrieve API resources, falling back to hardcoded types: %v", err) - return legacyscheme.Registry.RESTMapper(), legacyscheme.Scheme, nil + return legacyscheme.Registry.RESTMapper(), nil } // allow conversion between typed and unstructured objects interfaces := meta.InterfacesForUnstructuredConversion(legacyscheme.Registry.InterfacesFor) mapper := discovery.NewDeferredDiscoveryRESTMapper(discoveryClient, meta.VersionInterfacesFunc(interfaces)) // TODO: should this also indicate it recognizes typed objects? - typer := discovery.NewUnstructuredObjectTyper(groupResources, legacyscheme.Scheme) expander := NewShortcutExpander(mapper, discoveryClient) - return expander, typer, err + return expander, err } -func (f *ring1Factory) Object() (meta.RESTMapper, runtime.ObjectTyper) { - return meta.NewLazyObjectLoader(f.objectLoader) +func (f *ring1Factory) RESTMapper() meta.RESTMapper { + return meta.NewLazyRESTMapperLoader(f.restMapper) } func (f *ring1Factory) CategoryExpander() categories.CategoryExpander { diff --git a/pkg/kubectl/resource/BUILD b/pkg/kubectl/resource/BUILD index 1253463daa7..cf644789313 100644 --- a/pkg/kubectl/resource/BUILD +++ b/pkg/kubectl/resource/BUILD @@ -29,6 +29,7 @@ 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/unstructuredscheme: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", @@ -55,6 +56,8 @@ go_test( ], embed = [":go_default_library"], deps = [ + "//pkg/api/legacyscheme:go_default_library", + "//pkg/apis/core/install:go_default_library", "//pkg/kubectl/categories:go_default_library", "//pkg/kubectl/scheme:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library", diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index b6979d7afe7..a2de3ca6868 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -644,6 +644,11 @@ func (b *Builder) mappingFor(resourceOrKindArg string) (*meta.RESTMapping, error // if we error out here, it is because we could not match a resource or a kind // for the given argument. To maintain consistency with previous behavior, // announce that a resource type could not be found. + // if the error is a URL error, then we had trouble doing discovery, so we should return the original + // error since it may help a user diagnose what is actually wrong + if _, ok := err.(*url.Error); ok { + return nil, err + } return nil, fmt.Errorf("the server doesn't have a resource type %q", groupResource.Resource) } diff --git a/pkg/kubectl/resource/visitor.go b/pkg/kubectl/resource/visitor.go index cd6721f8dc2..88241712994 100644 --- a/pkg/kubectl/resource/visitor.go +++ b/pkg/kubectl/resource/visitor.go @@ -188,7 +188,7 @@ func (i *Info) versioned(convertor runtime.ObjectConvertor) (runtime.Object, err // AsVersioned returns the object as a Go object in the external form if possible (matching the // group version kind of the mapping, or i.Object if it cannot be converted. // Deprecated this function will be removed once calling code is updated to indicate the correct -// negoticatedserializers during contruction of the builder +// negoticatedserializers during construction of the builder func (i *Info) AsVersioned(convertor runtime.ObjectConvertor) runtime.Object { if obj, err := i.versioned(convertor); err == nil { return obj diff --git a/staging/src/k8s.io/apimachinery/pkg/api/meta/lazy.go b/staging/src/k8s.io/apimachinery/pkg/api/meta/lazy.go index 7f92f39a43f..431a0a63532 100644 --- a/staging/src/k8s.io/apimachinery/pkg/api/meta/lazy.go +++ b/staging/src/k8s.io/apimachinery/pkg/api/meta/lazy.go @@ -19,27 +19,25 @@ package meta import ( "sync" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" ) // lazyObject defers loading the mapper and typer until necessary. type lazyObject struct { - loader func() (RESTMapper, runtime.ObjectTyper, error) + loader func() (RESTMapper, error) lock sync.Mutex loaded bool err error mapper RESTMapper - typer runtime.ObjectTyper } // NewLazyObjectLoader handles unrecoverable errors when creating a RESTMapper / ObjectTyper by // returning those initialization errors when the interface methods are invoked. This defers the // initialization and any server calls until a client actually needs to perform the action. -func NewLazyObjectLoader(fn func() (RESTMapper, runtime.ObjectTyper, error)) (RESTMapper, runtime.ObjectTyper) { +func NewLazyRESTMapperLoader(fn func() (RESTMapper, error)) RESTMapper { obj := &lazyObject{loader: fn} - return obj, obj + return obj } // init lazily loads the mapper and typer, returning an error if initialization has failed. @@ -49,13 +47,12 @@ func (o *lazyObject) init() error { if o.loaded { return o.err } - o.mapper, o.typer, o.err = o.loader() + o.mapper, o.err = o.loader() o.loaded = true return o.err } var _ RESTMapper = &lazyObject{} -var _ runtime.ObjectTyper = &lazyObject{} func (o *lazyObject) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) { if err := o.init(); err != nil { @@ -105,17 +102,3 @@ func (o *lazyObject) ResourceSingularizer(resource string) (singular string, err } return o.mapper.ResourceSingularizer(resource) } - -func (o *lazyObject) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) { - if err := o.init(); err != nil { - return nil, false, err - } - return o.typer.ObjectKinds(obj) -} - -func (o *lazyObject) Recognizes(gvk schema.GroupVersionKind) bool { - if err := o.init(); err != nil { - return false - } - return o.typer.Recognizes(gvk) -} diff --git a/test/integration/apiserver/print_test.go b/test/integration/apiserver/print_test.go index 3eeb3afde44..e6e19fdcfd2 100644 --- a/test/integration/apiserver/print_test.go +++ b/test/integration/apiserver/print_test.go @@ -147,7 +147,7 @@ func TestServerSidePrint(t *testing.T) { printer := newFakePrinter(printersinternal.AddHandlers) factory := util.NewFactory(clientcmd.NewDefaultClientConfig(*createKubeConfig(s.URL), &clientcmd.ConfigOverrides{})) - mapper, _ := factory.Object() + mapper := factory.RESTMapper() for gvk, apiType := range legacyscheme.Scheme.AllKnownTypes() { // we do not care about internal objects or lists // TODO make sure this is always true diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 2f62c5b9ff9..0756210ea46 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -811,7 +811,7 @@ func startRealMasterOrDie(t *testing.T, certDir string) (*allClient, clientv3.KV t.Fatal(err) } - mapper, _ := util.NewFactory(clientcmd.NewDefaultClientConfig(*clientcmdapi.NewConfig(), &clientcmd.ConfigOverrides{})).Object() + mapper := util.NewFactory(clientcmd.NewDefaultClientConfig(*clientcmdapi.NewConfig(), &clientcmd.ConfigOverrides{})).RESTMapper() return client, kvClient, mapper }