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,19 +99,15 @@ type ConvertOptions struct {
out io.Writer
printer printers.ResourcePrinter
outputVersion schema.GroupVersion
specifiedOutputVersion schema.GroupVersion
}
// 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
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")
if len(outputVersionString) == 0 {
if defaultVersion == nil {
return schema.GroupVersion{}, nil
}
return *defaultVersion, nil
return schema.GroupVersion{}, nil
}
return schema.ParseGroupVersion(outputVersionString)
@ -119,13 +115,10 @@ func outputVersion(cmd *cobra.Command, defaultVersion *schema.GroupVersion) (sch
// 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) {
o.outputVersion, err = outputVersion(cmd, &scheme.Registry.EnabledVersionsForGroup(api.GroupName)[0])
o.specifiedOutputVersion, err = outputVersion(cmd)
if err != nil {
return err
}
if !scheme.Registry.IsEnabledVersion(o.outputVersion) {
return cmdutil.UsageErrorf(cmd, "'%s' is not a registered version.", o.outputVersion)
}
// build the builder
o.builder = f.NewBuilder().
@ -184,7 +177,7 @@ func (o *ConvertOptions) RunConvert() error {
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 {
return err
}
@ -194,7 +187,7 @@ func (o *ConvertOptions) RunConvert() error {
if err != nil {
return err
}
filteredObj, err := objectListToVersionedObject(items, o.outputVersion)
filteredObj, err := objectListToVersionedObject(items, o.specifiedOutputVersion)
if err != nil {
return err
}
@ -206,9 +199,14 @@ func (o *ConvertOptions) RunConvert() error {
// objectListToVersionedObject receives a list of api objects and a group version
// 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}
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 {
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
// version will be preferred as the conversion target, but the Object's mapping version will be
// used if that version is not present.
func asVersionedObject(infos []*resource.Info, forceList bool, version schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
objects, err := asVersionedObjects(infos, version, encoder)
func asVersionedObject(infos []*resource.Info, forceList bool, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
objects, err := asVersionedObjects(infos, specifiedOutputVersion, encoder)
if err != nil {
return nil, err
}
@ -230,7 +228,13 @@ func asVersionedObject(infos []*resource.Info, forceList bool, version schema.Gr
object = objects[0]
} else {
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 {
return nil, err
}
@ -238,7 +242,7 @@ func asVersionedObject(infos []*resource.Info, forceList bool, version schema.Gr
}
actualVersion := object.GetObjectKind().GroupVersionKind()
if actualVersion.Version != version.Version {
if actualVersion.Version != specifiedOutputVersion.Version {
defaultVersionInfo := ""
if len(actualVersion.Version) > 0 {
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
// version will be preferred as the conversion target, but the Object's mapping version will be
// 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{}
for _, info := range infos {
if info.Object == nil {
continue
}
targetVersions := []schema.GroupVersion{}
// objects that are not part of api.Scheme must be converted to JSON
// 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) {
// TODO: ideally this would encode to version, but we don't expose multiple codecs here.
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})
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 {
return nil, err
}