Merge pull request #57150 from deads2k/rebase-03-convert

Automatic merge from submit-queue (batch tested with PRs 57324, 56931, 57000, 57150, 56965). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

allow convert to default on a per object basis

`kubetl convert` needs to distinguish between cases where a user specifies a version (use this at all cost) and cases where it doesn't (for each object, find the best version to convert to).  This allows that to happen.
This commit is contained in:
Kubernetes Submit Queue 2017-12-18 08:46:49 -08:00 committed by GitHub
commit 90acdba062
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -99,33 +99,26 @@ type ConvertOptions struct {
out io.Writer out io.Writer
printer printers.ResourcePrinter printer printers.ResourcePrinter
outputVersion schema.GroupVersion specifiedOutputVersion schema.GroupVersion
} }
// outputVersion returns the preferred output version for generic content (JSON, YAML, or templates) // outputVersion returns the preferred output version for generic content (JSON, YAML, or templates)
// defaultVersion is never mutated. Nil simply allows clean passing in common usage from client.Config // defaultVersion is never mutated. Nil simply allows clean passing in common usage from client.Config
func outputVersion(cmd *cobra.Command, defaultVersion *schema.GroupVersion) (schema.GroupVersion, error) { func outputVersion(cmd *cobra.Command) (schema.GroupVersion, error) {
outputVersionString := cmdutil.GetFlagString(cmd, "output-version") outputVersionString := cmdutil.GetFlagString(cmd, "output-version")
if len(outputVersionString) == 0 { if len(outputVersionString) == 0 {
if defaultVersion == nil {
return schema.GroupVersion{}, nil return schema.GroupVersion{}, nil
} }
return *defaultVersion, nil
}
return schema.ParseGroupVersion(outputVersionString) return schema.ParseGroupVersion(outputVersionString)
} }
// Complete collects information required to run Convert command from command line. // Complete collects information required to run Convert command from command line.
func (o *ConvertOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) (err error) { func (o *ConvertOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) (err error) {
o.outputVersion, err = outputVersion(cmd, &scheme.Registry.EnabledVersionsForGroup(api.GroupName)[0]) o.specifiedOutputVersion, err = outputVersion(cmd)
if err != nil { if err != nil {
return err return err
} }
if !scheme.Registry.IsEnabledVersion(o.outputVersion) {
return cmdutil.UsageErrorf(cmd, "'%s' is not a registered version.", o.outputVersion)
}
// build the builder // build the builder
o.builder = f.NewBuilder(). o.builder = f.NewBuilder().
@ -184,7 +177,7 @@ func (o *ConvertOptions) RunConvert() error {
return fmt.Errorf("no objects passed to convert") return fmt.Errorf("no objects passed to convert")
} }
objects, err := asVersionedObject(infos, !singleItemImplied, o.outputVersion, o.encoder) objects, err := asVersionedObject(infos, !singleItemImplied, o.specifiedOutputVersion, o.encoder)
if err != nil { if err != nil {
return err return err
} }
@ -194,7 +187,7 @@ func (o *ConvertOptions) RunConvert() error {
if err != nil { if err != nil {
return err return err
} }
filteredObj, err := objectListToVersionedObject(items, o.outputVersion) filteredObj, err := objectListToVersionedObject(items, o.specifiedOutputVersion)
if err != nil { if err != nil {
return err return err
} }
@ -206,9 +199,14 @@ func (o *ConvertOptions) RunConvert() error {
// objectListToVersionedObject receives a list of api objects and a group version // objectListToVersionedObject receives a list of api objects and a group version
// and squashes the list's items into a single versioned runtime.Object. // and squashes the list's items into a single versioned runtime.Object.
func objectListToVersionedObject(objects []runtime.Object, version schema.GroupVersion) (runtime.Object, error) { func objectListToVersionedObject(objects []runtime.Object, specifiedOutputVersion schema.GroupVersion) (runtime.Object, error) {
objectList := &api.List{Items: objects} objectList := &api.List{Items: objects}
converted, err := tryConvert(scheme.Scheme, objectList, version, scheme.Registry.GroupOrDie(api.GroupName).GroupVersion) targetVersions := []schema.GroupVersion{}
if !specifiedOutputVersion.Empty() {
targetVersions = append(targetVersions, specifiedOutputVersion)
}
targetVersions = append(targetVersions, scheme.Registry.GroupOrDie(api.GroupName).GroupVersion)
converted, err := tryConvert(scheme.Scheme, objectList, targetVersions...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -219,8 +217,8 @@ func objectListToVersionedObject(objects []runtime.Object, version schema.GroupV
// the objects as children, or if only a single Object is present, as that object. The provided // the objects as children, or if only a single Object is present, as that object. The provided
// version will be preferred as the conversion target, but the Object's mapping version will be // version will be preferred as the conversion target, but the Object's mapping version will be
// used if that version is not present. // used if that version is not present.
func asVersionedObject(infos []*resource.Info, forceList bool, version schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) { func asVersionedObject(infos []*resource.Info, forceList bool, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
objects, err := asVersionedObjects(infos, version, encoder) objects, err := asVersionedObjects(infos, specifiedOutputVersion, encoder)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -230,7 +228,13 @@ func asVersionedObject(infos []*resource.Info, forceList bool, version schema.Gr
object = objects[0] object = objects[0]
} else { } else {
object = &api.List{Items: objects} object = &api.List{Items: objects}
converted, err := tryConvert(scheme.Scheme, object, version, scheme.Registry.GroupOrDie(api.GroupName).GroupVersion) targetVersions := []schema.GroupVersion{}
if !specifiedOutputVersion.Empty() {
targetVersions = append(targetVersions, specifiedOutputVersion)
}
targetVersions = append(targetVersions, scheme.Registry.GroupOrDie(api.GroupName).GroupVersion)
converted, err := tryConvert(scheme.Scheme, object, targetVersions...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -238,7 +242,7 @@ func asVersionedObject(infos []*resource.Info, forceList bool, version schema.Gr
} }
actualVersion := object.GetObjectKind().GroupVersionKind() actualVersion := object.GetObjectKind().GroupVersionKind()
if actualVersion.Version != version.Version { if actualVersion.Version != specifiedOutputVersion.Version {
defaultVersionInfo := "" defaultVersionInfo := ""
if len(actualVersion.Version) > 0 { if len(actualVersion.Version) > 0 {
defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version) defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version)
@ -251,16 +255,17 @@ func asVersionedObject(infos []*resource.Info, forceList bool, version schema.Gr
// asVersionedObjects converts a list of infos into versioned objects. The provided // asVersionedObjects converts a list of infos into versioned objects. The provided
// version will be preferred as the conversion target, but the Object's mapping version will be // version will be preferred as the conversion target, but the Object's mapping version will be
// used if that version is not present. // used if that version is not present.
func asVersionedObjects(infos []*resource.Info, version schema.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) { func asVersionedObjects(infos []*resource.Info, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) {
objects := []runtime.Object{} objects := []runtime.Object{}
for _, info := range infos { for _, info := range infos {
if info.Object == nil { if info.Object == nil {
continue continue
} }
targetVersions := []schema.GroupVersion{}
// objects that are not part of api.Scheme must be converted to JSON // objects that are not part of api.Scheme must be converted to JSON
// TODO: convert to map[string]interface{}, attach to runtime.Unknown? // TODO: convert to map[string]interface{}, attach to runtime.Unknown?
if !version.Empty() { if !specifiedOutputVersion.Empty() {
if _, _, err := scheme.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) { if _, _, err := scheme.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) {
// TODO: ideally this would encode to version, but we don't expose multiple codecs here. // TODO: ideally this would encode to version, but we don't expose multiple codecs here.
data, err := runtime.Encode(encoder, info.Object) data, err := runtime.Encode(encoder, info.Object)
@ -271,9 +276,19 @@ func asVersionedObjects(infos []*resource.Info, version schema.GroupVersion, enc
objects = append(objects, &runtime.Unknown{Raw: data}) objects = append(objects, &runtime.Unknown{Raw: data})
continue continue
} }
targetVersions = append(targetVersions, specifiedOutputVersion)
} else {
gvks, _, err := scheme.Scheme.ObjectKinds(info.Object)
if err == nil {
for _, gvk := range gvks {
for _, version := range scheme.Registry.EnabledVersionsForGroup(gvk.Group) {
targetVersions = append(targetVersions, version)
}
}
}
} }
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion()) converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, targetVersions...)
if err != nil { if err != nil {
return nil, err return nil, err
} }