diff --git a/pkg/kubectl/cmd/apply_set_last_applied.go b/pkg/kubectl/cmd/apply_set_last_applied.go index f4246b36e2..40ca8841c6 100644 --- a/pkg/kubectl/cmd/apply_set_last_applied.go +++ b/pkg/kubectl/cmd/apply_set_last_applied.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/types" - "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" @@ -203,7 +202,7 @@ func (o *SetLastAppliedOptions) RunSetLastApplied() error { } info.Refresh(patchedObj, false) } - if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil { return err } } diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index bde5495689..e1a0d61c51 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -253,7 +253,7 @@ func (o *AutoscaleOptions) Run() error { if err != nil { return err } - return printer.PrintObj(hpa.AsVersioned(legacyscheme.Scheme), o.Out) + return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(hpa.Object, hpa.Mapping), o.Out) } if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, hpa.Object, cmdutil.InternalVersionJSONEncoder()); err != nil { @@ -270,7 +270,7 @@ func (o *AutoscaleOptions) Run() error { if err != nil { return err } - return printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, hpa.Mapping), o.Out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/certificates.go b/pkg/kubectl/cmd/certificates.go index d12db1e5a3..d7357cba95 100644 --- a/pkg/kubectl/cmd/certificates.go +++ b/pkg/kubectl/cmd/certificates.go @@ -228,7 +228,7 @@ func (options *CertificateOptions) modifyCertificateCondition(builder *resource. } found++ - return options.PrintObj(info.AsVersioned(legacyscheme.Scheme), options.Out) + return options.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), options.Out) }) if found == 0 { fmt.Fprintf(options.Out, "No resources found\n") diff --git a/pkg/kubectl/cmd/create/create.go b/pkg/kubectl/cmd/create/create.go index 1eb57bb1d3..e1dfc5b866 100644 --- a/pkg/kubectl/cmd/create/create.go +++ b/pkg/kubectl/cmd/create/create.go @@ -426,7 +426,7 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er } // ensure we pass a versioned object to the printer - obj = info.AsVersioned(legacyscheme.Scheme) + obj = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) } 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 99ae24d01e..db4ae94ef6 100644 --- a/pkg/kubectl/cmd/drain.go +++ b/pkg/kubectl/cmd/drain.go @@ -739,7 +739,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Printf("error: %v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) } else { if !o.DryRun { helper := resource.NewHelper(o.restClient, nodeInfo.Mapping) @@ -765,7 +765,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) } } else { printer, err := o.ToPrinter("skipped") @@ -773,7 +773,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { fmt.Fprintf(o.ErrOut, "%v", err) continue } - printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out) } } diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index 4313f4e39f..cf356e58b0 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -339,7 +339,7 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro return err } - return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) }) if err != nil { return err diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index 52b06bd972..fddf3c8cf4 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -156,7 +156,7 @@ func (o PauseConfig) RunPause() error { allErrs = append(allErrs, err) continue } - printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) continue } @@ -172,7 +172,7 @@ func (o PauseConfig) RunPause() error { allErrs = append(allErrs, err) continue } - printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) } return utilerrors.NewAggregate(allErrs) diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index b0e1ab8218..ac0c19caea 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -161,7 +161,7 @@ func (o ResumeConfig) RunResume() error { allErrs = append(allErrs, err) continue } - printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) } obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch) @@ -176,7 +176,7 @@ func (o ResumeConfig) RunResume() error { allErrs = append(allErrs, err) continue } - printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) } return utilerrors.NewAggregate(allErrs) diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index 81057108f9..45aaf17038 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -168,7 +168,7 @@ func (o *UndoOptions) RunUndo() error { allErrs = append(allErrs, err) continue } - printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) } return utilerrors.NewAggregate(allErrs) } diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 98769839a8..a56674dd0c 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -696,7 +696,7 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command return nil, err } - versioned = info.AsVersioned(legacyscheme.Scheme) + versioned = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) } return &RunObject{ Versioned: versioned, diff --git a/pkg/kubectl/cmd/set/set_env.go b/pkg/kubectl/cmd/set/set_env.go index 6ae37a48bc..ef2a5c6112 100644 --- a/pkg/kubectl/cmd/set/set_env.go +++ b/pkg/kubectl/cmd/set/set_env.go @@ -327,7 +327,7 @@ func (o *EnvOptions) RunEnv() error { return err } patches := CalculatePatches(infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) { - info.Object = info.AsVersioned(legacyscheme.Scheme) + info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) _, err := o.updatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { resolutionErrorsEncountered := false containers, _ := selectContainers(spec.Containers, o.ContainerSelector) @@ -418,7 +418,7 @@ func (o *EnvOptions) RunEnv() error { } if o.Local || o.dryRun { - if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil { return err } continue @@ -437,7 +437,7 @@ func (o *EnvOptions) RunEnv() error { return fmt.Errorf("at least one environment variable must be provided") } - if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), 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 1b271d762b..e3096aa753 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -211,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(legacyscheme.Scheme) + info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) _, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { for name, image := range o.ContainerImages { var ( @@ -275,7 +275,7 @@ func (o *SetImageOptions) Run() error { } if o.Local || o.DryRun { - if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil { return err } continue @@ -289,7 +289,7 @@ func (o *SetImageOptions) Run() error { } info.Refresh(obj, true) - if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), 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 1624d5fa53..ceb57798d6 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -224,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(legacyscheme.Scheme) + info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) _, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error { containers, _ := selectContainers(spec.Containers, o.ContainerSelector) if len(containers) != 0 { @@ -277,7 +277,7 @@ func (o *SetResourcesOptions) Run() error { } if o.Local || o.DryRun { - if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil { return err } continue @@ -290,7 +290,7 @@ func (o *SetResourcesOptions) Run() error { } info.Refresh(obj, true) - if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), 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 e50a14509a..6c21fb58bb 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -204,7 +204,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(legacyscheme.Scheme) + versioned := cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) patch.Info.Object = versioned selectErr := updateSelectorForObject(info.Object, *o.selector) if selectErr != nil { @@ -232,7 +232,7 @@ func (o *SetSelectorOptions) RunSelector() error { } info.Refresh(patched, true) - return o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out) + return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, info.Mapping), o.Out) }) } diff --git a/pkg/kubectl/cmd/set/set_serviceaccount.go b/pkg/kubectl/cmd/set/set_serviceaccount.go index 414c8758c8..217bfff776 100644 --- a/pkg/kubectl/cmd/set/set_serviceaccount.go +++ b/pkg/kubectl/cmd/set/set_serviceaccount.go @@ -174,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(legacyscheme.Scheme) + info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping) _, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error { podSpec.ServiceAccountName = o.serviceAccountName return nil @@ -198,7 +198,7 @@ func (o *SetServiceAccountOptions) Run() error { continue } if o.local || o.dryRun { - if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil { return err } continue @@ -210,7 +210,7 @@ func (o *SetServiceAccountOptions) Run() error { } info.Refresh(patched, true) - if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil { + if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), 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 885b237a0f..fa6a49bf84 100644 --- a/pkg/kubectl/cmd/set/set_subject.go +++ b/pkg/kubectl/cmd/set/set_subject.go @@ -230,7 +230,7 @@ func (o *SubjectOptions) Run(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(legacyscheme.Scheme)) + return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)) } return nil, err }) @@ -263,7 +263,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error { } info.Refresh(obj, true) - return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out) + return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out) } return utilerrors.NewAggregate(allErrs) } diff --git a/pkg/kubectl/cmd/util/BUILD b/pkg/kubectl/cmd/util/BUILD index 5b432c1048..c3ce48d37c 100644 --- a/pkg/kubectl/cmd/util/BUILD +++ b/pkg/kubectl/cmd/util/BUILD @@ -4,6 +4,7 @@ go_library( name = "go_default_library", srcs = [ "cached_discovery.go", + "conversion.go", "factory.go", "factory_builder.go", "factory_client_access.go", diff --git a/pkg/kubectl/cmd/util/conversion.go b/pkg/kubectl/cmd/util/conversion.go new file mode 100644 index 0000000000..960b3e0895 --- /dev/null +++ b/pkg/kubectl/cmd/util/conversion.go @@ -0,0 +1,40 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/api/legacyscheme" +) + +// AsDefaultVersionedOrOriginal returns the object as a Go object in the external form if possible (matching the +// group version kind of the mapping if provided, a best guess based on serialization if not provided, or obj if it cannot be converted. +// TODO update call sites to specify the scheme they want on their builder. +func AsDefaultVersionedOrOriginal(obj runtime.Object, mapping *meta.RESTMapping) runtime.Object { + converter := runtime.ObjectConvertor(legacyscheme.Scheme) + groupVersioner := runtime.GroupVersioner(schema.GroupVersions(legacyscheme.Registry.RegisteredGroupVersions())) + if mapping != nil { + groupVersioner = mapping.GroupVersionKind.GroupVersion() + } + + if obj, err := converter.ConvertToVersion(obj, groupVersioner); err == nil { + return obj + } + return obj +} diff --git a/pkg/kubectl/resource/builder_test.go b/pkg/kubectl/resource/builder_test.go index 399219091a..c40ae4eebb 100644 --- a/pkg/kubectl/resource/builder_test.go +++ b/pkg/kubectl/resource/builder_test.go @@ -300,7 +300,8 @@ 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(legacyscheme.Scheme) + + obj := info.Object 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/visitor.go b/pkg/kubectl/resource/visitor.go index 8824171299..95b6bbbe0a 100644 --- a/pkg/kubectl/resource/visitor.go +++ b/pkg/kubectl/resource/visitor.go @@ -180,22 +180,6 @@ func (i *Info) ResourceMapping() *meta.RESTMapping { return i.Mapping } -// Versioned returns the object as a Go type in the mapping's version or returns an error. -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. -// Deprecated this function will be removed once calling code is updated to indicate the correct -// 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 - } - 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