tighten .Info for kubectl to avoid unpredictable conversion

This commit is contained in:
David Eads
2018-04-26 11:21:41 -04:00
parent 6900f8856f
commit b8177bb9af
20 changed files with 71 additions and 87 deletions

View File

@@ -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 {

View File

@@ -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

View File

@@ -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",

View File

@@ -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")
}

View File

@@ -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

View File

@@ -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
})
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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(),
)

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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",

View File

@@ -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)
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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