mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 05:03:09 +00:00
Move kubectl type conversion libs out of the resource & util package and into the conversion command.
Kubectl shouldn't have code that does type conversion. This should be in the server.
This commit is contained in:
parent
4548a07c0e
commit
7ab3f96100
@ -30,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -182,7 +183,7 @@ func (o *ConvertOptions) RunConvert() error {
|
|||||||
return fmt.Errorf("no objects passed to convert")
|
return fmt.Errorf("no objects passed to convert")
|
||||||
}
|
}
|
||||||
|
|
||||||
objects, err := resource.AsVersionedObject(infos, !singleItemImplied, o.outputVersion, o.encoder)
|
objects, err := asVersionedObject(infos, !singleItemImplied, o.outputVersion, o.encoder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -192,7 +193,7 @@ func (o *ConvertOptions) RunConvert() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filteredObj, err := cmdutil.ObjectListToVersionedObject(items, o.outputVersion)
|
filteredObj, err := objectListToVersionedObject(items, o.outputVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -201,3 +202,99 @@ func (o *ConvertOptions) RunConvert() error {
|
|||||||
|
|
||||||
return o.printer.PrintObj(objects, o.out)
|
return o.printer.PrintObj(objects, o.out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
objectList := &api.List{Items: objects}
|
||||||
|
converted, err := tryConvert(api.Scheme, objectList, version, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return converted, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsVersionedObject converts a list of infos into a single object - either a List containing
|
||||||
|
// 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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var object runtime.Object
|
||||||
|
if len(objects) == 1 && !forceList {
|
||||||
|
object = objects[0]
|
||||||
|
} else {
|
||||||
|
object = &api.List{Items: objects}
|
||||||
|
converted, err := tryConvert(api.Scheme, object, version, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
object = converted
|
||||||
|
}
|
||||||
|
|
||||||
|
actualVersion := object.GetObjectKind().GroupVersionKind()
|
||||||
|
if actualVersion.Version != version.Version {
|
||||||
|
defaultVersionInfo := ""
|
||||||
|
if len(actualVersion.Version) > 0 {
|
||||||
|
defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version)
|
||||||
|
}
|
||||||
|
glog.V(1).Infof("info: the output version specified is invalid. %s\n", defaultVersionInfo)
|
||||||
|
}
|
||||||
|
return object, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
objects := []runtime.Object{}
|
||||||
|
for _, info := range infos {
|
||||||
|
if info.Object == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 _, _, err := api.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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// TODO: Set ContentEncoding and ContentType.
|
||||||
|
objects = append(objects, &runtime.Unknown{Raw: data})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
objects = append(objects, converted)
|
||||||
|
}
|
||||||
|
return objects, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// tryConvert attempts to convert the given object to the provided versions in order. This function assumes
|
||||||
|
// the object is in internal version.
|
||||||
|
func tryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...schema.GroupVersion) (runtime.Object, error) {
|
||||||
|
var last error
|
||||||
|
for _, version := range versions {
|
||||||
|
if version.Empty() {
|
||||||
|
return object, nil
|
||||||
|
}
|
||||||
|
obj, err := converter.ConvertToVersion(object, version)
|
||||||
|
if err != nil {
|
||||||
|
last = err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
return nil, last
|
||||||
|
}
|
||||||
|
@ -36,7 +36,6 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/json"
|
"k8s.io/apimachinery/pkg/util/json"
|
||||||
@ -731,17 +730,6 @@ func PrintFilterCount(out io.Writer, found, hidden, errors int, options *printer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
|
||||||
objectList := &api.List{Items: objects}
|
|
||||||
converted, err := resource.TryConvert(api.Scheme, objectList, version, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return converted, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSiblingCommandExists receives a pointer to a cobra command and a target string.
|
// IsSiblingCommandExists receives a pointer to a cobra command and a target string.
|
||||||
// Returns true if the target string is found in the list of sibling commands.
|
// Returns true if the target string is found in the list of sibling commands.
|
||||||
func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {
|
func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {
|
||||||
|
@ -23,7 +23,6 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/kubectl/validation:go_default_library",
|
"//pkg/kubectl/validation:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
|
||||||
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
||||||
"//vendor/golang.org/x/text/transform:go_default_library",
|
"//vendor/golang.org/x/text/transform:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
|
@ -20,12 +20,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
@ -221,88 +218,3 @@ func (r *Result) Watch(resourceVersion string) (watch.Interface, error) {
|
|||||||
}
|
}
|
||||||
return w.Watch(resourceVersion)
|
return w.Watch(resourceVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsVersionedObject converts a list of infos into a single object - either a List containing
|
|
||||||
// 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 []*Info, forceList bool, version schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
|
|
||||||
objects, err := AsVersionedObjects(infos, version, encoder)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var object runtime.Object
|
|
||||||
if len(objects) == 1 && !forceList {
|
|
||||||
object = objects[0]
|
|
||||||
} else {
|
|
||||||
object = &api.List{Items: objects}
|
|
||||||
converted, err := TryConvert(api.Scheme, object, version, api.Registry.GroupOrDie(api.GroupName).GroupVersion)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
object = converted
|
|
||||||
}
|
|
||||||
|
|
||||||
actualVersion := object.GetObjectKind().GroupVersionKind()
|
|
||||||
if actualVersion.Version != version.Version {
|
|
||||||
defaultVersionInfo := ""
|
|
||||||
if len(actualVersion.Version) > 0 {
|
|
||||||
defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version)
|
|
||||||
}
|
|
||||||
glog.V(1).Infof("info: the output version specified is invalid. %s\n", defaultVersionInfo)
|
|
||||||
}
|
|
||||||
return object, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 []*Info, version schema.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) {
|
|
||||||
objects := []runtime.Object{}
|
|
||||||
for _, info := range infos {
|
|
||||||
if info.Object == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 _, _, err := api.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)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// TODO: Set ContentEncoding and ContentType.
|
|
||||||
objects = append(objects, &runtime.Unknown{Raw: data})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
converted, err := TryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
objects = append(objects, converted)
|
|
||||||
}
|
|
||||||
return objects, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TryConvert attempts to convert the given object to the provided versions in order. This function assumes
|
|
||||||
// the object is in internal version.
|
|
||||||
func TryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...schema.GroupVersion) (runtime.Object, error) {
|
|
||||||
var last error
|
|
||||||
for _, version := range versions {
|
|
||||||
if version.Empty() {
|
|
||||||
return object, nil
|
|
||||||
}
|
|
||||||
obj, err := converter.ConvertToVersion(object, version)
|
|
||||||
if err != nil {
|
|
||||||
last = err
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return obj, nil
|
|
||||||
}
|
|
||||||
return nil, last
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user