diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index 52b9deddc4c..8a37c00980e 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -246,12 +246,7 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro } var outputObj runtime.Object - var obj runtime.Object - - obj, err = info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) - if err != nil { - return err - } + obj := info.Object if o.dryrun || o.local { if err := o.updateAnnotations(obj); err != nil { diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index d3e47730569..5d0a14b0b9a 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -364,7 +364,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error { if err != nil { return err } - return printer.PrintObj(info.AsVersioned(), o.Out) + return printer.PrintObj(info.Object, o.Out) } if !o.DryRun { @@ -415,7 +415,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error { if err != nil { return err } - return printer.PrintObj(info.AsVersioned(), o.Out) + return printer.PrintObj(info.Object, o.Out) } } count++ @@ -429,7 +429,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error { if err != nil { return err } - return printer.PrintObj(info.AsVersioned(), o.Out) + return printer.PrintObj(info.Object, o.Out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/create/BUILD b/pkg/kubectl/cmd/create/BUILD index b322e982ca4..53a84bd9ea8 100644 --- a/pkg/kubectl/cmd/create/BUILD +++ b/pkg/kubectl/cmd/create/BUILD @@ -30,6 +30,7 @@ go_library( "//pkg/kubectl/cmd/util/editor:go_default_library", "//pkg/kubectl/genericclioptions:go_default_library", "//pkg/kubectl/resource:go_default_library", + "//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/util/i18n:go_default_library", "//pkg/printers:go_default_library", "//vendor/github.com/golang/glog:go_default_library", diff --git a/pkg/kubectl/cmd/create/create_job.go b/pkg/kubectl/cmd/create/create_job.go index e52b6b52f42..74462cc9ce0 100644 --- a/pkg/kubectl/cmd/create/create_job.go +++ b/pkg/kubectl/cmd/create/create_job.go @@ -30,6 +30,7 @@ import ( cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/util/i18n" ) @@ -144,7 +145,12 @@ func (o *CreateJobOptions) RunCreateJob() error { if len(infos) != 1 { return fmt.Errorf("from must be an existing cronjob") } - cronJob, ok := infos[0].AsVersioned().(*batchv1beta1.CronJob) + + uncastVersionedObj, err := scheme.Scheme.ConvertToVersion(infos[0].Object, batchv1beta1.SchemeGroupVersion) + if err != nil { + return fmt.Errorf("from must be an existing cronjob: %v", err) + } + cronJob, ok := uncastVersionedObj.(*batchv1beta1.CronJob) if !ok { return fmt.Errorf("from must be an existing cronjob") } diff --git a/pkg/kubectl/cmd/drain.go b/pkg/kubectl/cmd/drain.go index fdcb57a2453..cde9e048e7d 100644 --- a/pkg/kubectl/cmd/drain.go +++ b/pkg/kubectl/cmd/drain.go @@ -43,6 +43,7 @@ import ( restclient "k8s.io/client-go/rest" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" + "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" @@ -718,7 +719,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { for _, nodeInfo := range o.nodeInfos { if nodeInfo.Mapping.GroupVersionKind.Kind == "Node" { - obj, err := nodeInfo.ObjectConverter.ConvertToVersion(nodeInfo.Object, nodeInfo.Mapping.GroupVersionKind.GroupVersion()) + obj, err := legacyscheme.Scheme.ConvertToVersion(nodeInfo.Object, nodeInfo.Mapping.GroupVersionKind.GroupVersion()) if err != nil { fmt.Printf("error: unable to %s node %q: %v", cordonOrUncordon, nodeInfo.Name, err) continue diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index 4592b9e6893..2641ef05de4 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -332,7 +332,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil }) } diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index 9e959cdf067..f8d92f6fb1c 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -242,7 +242,7 @@ func (o *PatchOptions) RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Com if err != nil { return err } - printer.PrintObj(info.AsVersioned(), out) + printer.PrintObj(info.Object, out) // if object was not successfully patched, exit with error code 1 if !didPatch { @@ -285,7 +285,7 @@ func (o *PatchOptions) RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Com if err != nil { return err } - return printer.PrintObj(info.AsVersioned(), out) + return printer.PrintObj(info.Object, out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index 3c73025097c..8e4e4aa53f9 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -234,7 +234,7 @@ func (o *ReplaceOptions) Run() error { } info.Refresh(obj, true) - return o.PrintObj(info.AsVersioned()) + return o.PrintObj(info.Object) }) } @@ -330,7 +330,7 @@ func (o *ReplaceOptions) forceReplace() error { count++ info.Refresh(obj, true) - return o.PrintObj(info.AsVersioned()) + return o.PrintObj(info.Object) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/rollingupdate.go b/pkg/kubectl/cmd/rollingupdate.go index 0ae18b3e725..748a4ecb897 100644 --- a/pkg/kubectl/cmd/rollingupdate.go +++ b/pkg/kubectl/cmd/rollingupdate.go @@ -217,12 +217,16 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args return cmdutil.UsageErrorf(cmd, "please make sure %s exists and is not empty", filename) } - switch t := infos[0].AsVersioned().(type) { + uncastVersionedObj, err := legacyscheme.Scheme.ConvertToVersion(infos[0].Object, v1.SchemeGroupVersion) + if err != nil { + return err + } + switch t := uncastVersionedObj.(type) { case *v1.ReplicationController: replicasDefaulted = t.Spec.Replicas == nil // previous code ignored the error. Seem like it's very unlikely to fail, so ok for now. - uncastObj, err := legacyscheme.Scheme.ConvertToVersion(t, api.SchemeGroupVersion) + uncastObj, err := legacyscheme.Scheme.ConvertToVersion(uncastVersionedObj, api.SchemeGroupVersion) if err == nil { newRc, _ = uncastObj.(*api.ReplicationController) } diff --git a/pkg/kubectl/cmd/set/BUILD b/pkg/kubectl/cmd/set/BUILD index bdde3d4ce8b..a7dd1844c99 100644 --- a/pkg/kubectl/cmd/set/BUILD +++ b/pkg/kubectl/cmd/set/BUILD @@ -19,6 +19,7 @@ go_library( importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/set", visibility = ["//build/visible_to:pkg_kubectl_cmd_set_CONSUMERS"], deps = [ + "//pkg/api/legacyscheme:go_default_library", "//pkg/apis/rbac:go_default_library", "//pkg/kubectl:go_default_library", "//pkg/kubectl/cmd/templates:go_default_library", diff --git a/pkg/kubectl/cmd/set/set_env.go b/pkg/kubectl/cmd/set/set_env.go index efbed9c2299..247f7b643e9 100644 --- a/pkg/kubectl/cmd/set/set_env.go +++ b/pkg/kubectl/cmd/set/set_env.go @@ -35,6 +35,7 @@ import ( "k8s.io/kubernetes/pkg/printers" utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" ) @@ -272,7 +273,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error { } for _, info := range infos { - versionedObject, err := info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) + versionedObject, err := legacyscheme.Scheme.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) if err != nil { return err } diff --git a/pkg/kubectl/cmd/taint.go b/pkg/kubectl/cmd/taint.go index 49a20d9e1f8..2688ec94ce0 100644 --- a/pkg/kubectl/cmd/taint.go +++ b/pkg/kubectl/cmd/taint.go @@ -30,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/strategicpatch" "k8s.io/apimachinery/pkg/util/validation" + "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" @@ -233,7 +234,7 @@ func (o TaintOptions) RunTaint() error { return err } - obj, err := info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) + obj, err := legacyscheme.Scheme.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion()) if err != nil { return err } diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 8fae54e02a3..e745da1a34a 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -353,11 +353,10 @@ func (f *TestFactory) NewBuilder() *resource.Builder { Decoder: cmdutil.InternalVersionDecoder(), }, &resource.Mapper{ - RESTMapper: mapper, - ObjectTyper: typer, - ClientMapper: resource.ClientMapperFunc(f.UnstructuredClientForMapping), - ObjectConverter: unstructured.UnstructuredObjectConverter{}, - Decoder: unstructured.UnstructuredJSONScheme, + RESTMapper: mapper, + ObjectTyper: typer, + ClientMapper: resource.ClientMapperFunc(f.UnstructuredClientForMapping), + Decoder: unstructured.UnstructuredJSONScheme, }, f.CategoryExpander(), ) diff --git a/pkg/kubectl/cmd/util/editor/editoptions.go b/pkg/kubectl/cmd/util/editor/editoptions.go index dd16245521c..324670dda44 100644 --- a/pkg/kubectl/cmd/util/editor/editoptions.go +++ b/pkg/kubectl/cmd/util/editor/editoptions.go @@ -441,7 +441,7 @@ func (o *EditOptions) visitToApplyEditPatch(originalInfos []*resource.Info, patc if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil } else { err := o.annotationPatch(info) @@ -453,7 +453,7 @@ func (o *EditOptions) visitToApplyEditPatch(originalInfos []*resource.Info, patc if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil } }) @@ -576,7 +576,7 @@ func (o *EditOptions) visitToPatch(originalInfos []*resource.Info, patchVisitor if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil } @@ -634,7 +634,7 @@ func (o *EditOptions) visitToPatch(originalInfos []*resource.Info, patchVisitor if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil }) return err @@ -649,7 +649,7 @@ func (o *EditOptions) visitToCreate(createVisitor resource.Visitor) error { if err != nil { return err } - printer.PrintObj(info.AsVersioned(), o.Out) + printer.PrintObj(info.Object, o.Out) return nil }) return err diff --git a/pkg/kubectl/cmd/util/factory_builder.go b/pkg/kubectl/cmd/util/factory_builder.go index 4476ff1ba43..b837f1330bc 100644 --- a/pkg/kubectl/cmd/util/factory_builder.go +++ b/pkg/kubectl/cmd/util/factory_builder.go @@ -63,11 +63,10 @@ func (f *ring2Factory) NewBuilder() *resource.Builder { Decoder: InternalVersionDecoder(), }, &resource.Mapper{ - RESTMapper: mapper, - ObjectTyper: typer, - ObjectConverter: unstructured.UnstructuredObjectConverter{}, - ClientMapper: unstructuredClientMapperFunc, - Decoder: unstructured.UnstructuredJSONScheme, + RESTMapper: mapper, + ObjectTyper: typer, + ClientMapper: unstructuredClientMapperFunc, + Decoder: unstructured.UnstructuredJSONScheme, }, categoryExpander, ) diff --git a/pkg/kubectl/resource/BUILD b/pkg/kubectl/resource/BUILD index 142fc8ce1e9..1253463daa7 100644 --- a/pkg/kubectl/resource/BUILD +++ b/pkg/kubectl/resource/BUILD @@ -29,7 +29,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 30fa1220aef..1fbe71e0afa 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -186,6 +186,8 @@ func (b *Builder) Unstructured() *Builder { return b } b.mapper = b.unstructured + // the unstructured mapper doesn't do any conversion + b.mapper.ObjectConverter = nil return b } @@ -835,12 +837,12 @@ func (b *Builder) visitByResource() *Result { } info := &Info{ - Client: client, - Mapping: mapping, - ObjectConverter: b.mapper.ObjectConverter, - Namespace: selectorNamespace, - Name: tuple.Name, - Export: b.export, + Client: client, + Mapping: mapping, + toVersionedObjectConverter: b.mapper.ObjectConverter, + Namespace: selectorNamespace, + Name: tuple.Name, + Export: b.export, } items = append(items, info) } @@ -901,12 +903,12 @@ func (b *Builder) visitByName() *Result { visitors := []Visitor{} for _, name := range b.names { info := &Info{ - Client: client, - Mapping: mapping, - ObjectConverter: b.mapper.ObjectConverter, - Namespace: selectorNamespace, - Name: name, - Export: b.export, + Client: client, + Mapping: mapping, + toVersionedObjectConverter: b.mapper.ObjectConverter, + Namespace: selectorNamespace, + Name: name, + Export: b.export, } visitors = append(visitors, info) } diff --git a/pkg/kubectl/resource/mapper.go b/pkg/kubectl/resource/mapper.go index 9d479c87f28..b834b6ca125 100644 --- a/pkg/kubectl/resource/mapper.go +++ b/pkg/kubectl/resource/mapper.go @@ -72,9 +72,9 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) { resourceVersion, _ := metadataAccessor.ResourceVersion(obj) return &Info{ - Client: client, - Mapping: mapping, - ObjectConverter: m.ObjectConverter, + Client: client, + Mapping: mapping, + toVersionedObjectConverter: m.ObjectConverter, Source: source, Namespace: namespace, @@ -112,9 +112,9 @@ func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []schema.GroupV namespace, _ := metadataAccessor.Namespace(obj) resourceVersion, _ := metadataAccessor.ResourceVersion(obj) return &Info{ - Client: client, - Mapping: mapping, - ObjectConverter: m.ObjectConverter, + Client: client, + Mapping: mapping, + toVersionedObjectConverter: m.ObjectConverter, Namespace: namespace, Name: name, diff --git a/pkg/kubectl/resource/selector.go b/pkg/kubectl/resource/selector.go index 41c47703461..ce973484640 100644 --- a/pkg/kubectl/resource/selector.go +++ b/pkg/kubectl/resource/selector.go @@ -94,9 +94,9 @@ func (r *Selector) Visit(fn VisitorFunc) error { resourceVersion, _ := metadataAccessor.ResourceVersion(list) nextContinueToken, _ := metadataAccessor.Continue(list) info := &Info{ - Client: r.Client, - Mapping: r.Mapping, - ObjectConverter: r.ObjectConverter, + Client: r.Client, + Mapping: r.Mapping, + toVersionedObjectConverter: r.ObjectConverter, Namespace: r.Namespace, ResourceVersion: resourceVersion, diff --git a/pkg/kubectl/resource/visitor.go b/pkg/kubectl/resource/visitor.go index e46ffd92c14..ded1dda3b59 100644 --- a/pkg/kubectl/resource/visitor.go +++ b/pkg/kubectl/resource/visitor.go @@ -32,7 +32,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/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -79,7 +78,7 @@ type Info struct { // from disk. Mapping *meta.RESTMapping // ObjectConverter allows conversion - ObjectConverter runtime.ObjectConvertor + toVersionedObjectConverter runtime.ObjectConvertor // Namespace will be set if the object is namespaced and has a specified value. Namespace string @@ -185,45 +184,21 @@ 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.ObjectConverter.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion()) + return i.toVersionedObjectConverter.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 { return obj } return i.Object } -// Unstructured returns the current object in unstructured form (as a runtime.Unstructured) -func (i *Info) Unstructured() (runtime.Unstructured, error) { - switch t := i.Object.(type) { - case runtime.Unstructured: - return t, nil - case *runtime.Unknown: - gvk := i.Mapping.GroupVersionKind - out, _, err := unstructured.UnstructuredJSONScheme.Decode(t.Raw, &gvk, nil) - return out.(runtime.Unstructured), err - default: - out := &unstructured.Unstructured{} - if err := i.ObjectConverter.Convert(i.Object, out, nil); err != nil { - return nil, err - } - return out, nil - } -} - -// AsUnstructured returns the object as a Go object in external form as a runtime.Unstructured -// (map of JSON equivalent values) or as i.Object if it cannot be converted. -func (i *Info) AsUnstructured() runtime.Object { - if out, err := i.Unstructured(); err == nil { - return out - } - return i.Object -} - // VisitorList implements Visit for the sub visitors it contains. The first error // returned from a child Visitor will terminate iteration. type VisitorList []Visitor