mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 11:13:48 +00:00
Introduce ObjectConvertor for conversion to known API versions
Will allow clients to transform internal objects to a version suitable for external output.
This commit is contained in:
parent
2d54dfe249
commit
778a50d00b
@ -211,6 +211,46 @@ func (s *Scheme) Convert(in, out interface{}) error {
|
||||
return s.converter.Convert(in, out, 0, s.generateConvertMeta(inVersion, outVersion))
|
||||
}
|
||||
|
||||
// ConvertToVersion attempts to convert an input object to its matching Kind in another
|
||||
// version within this scheme. Will return an error if the provided version does not
|
||||
// contain the inKind (or a mapping by name defined with AddKnownTypeWithName).
|
||||
func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{}, error) {
|
||||
t := reflect.TypeOf(in)
|
||||
if t.Kind() != reflect.Ptr {
|
||||
return nil, fmt.Errorf("only pointer types may be converted: %v", t)
|
||||
}
|
||||
t = t.Elem()
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("only pointers to struct types may be converted: %v", t)
|
||||
}
|
||||
|
||||
kinds, ok := s.typeToKind[t]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%v cannot be converted into version %q", t, outVersion)
|
||||
}
|
||||
outKind := kinds[0]
|
||||
|
||||
inVersion, _, err := s.ObjectVersionAndKind(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out, err := s.NewObject(outVersion, outKind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.converter.Convert(in, out, 0, s.generateConvertMeta(inVersion, outVersion)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.SetVersionAndKind(outVersion, outKind, out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// generateConvertMeta constructs the meta value we pass to Convert.
|
||||
func (s *Scheme) generateConvertMeta(srcVersion, destVersion string) *Meta {
|
||||
return &Meta{
|
||||
|
@ -240,6 +240,45 @@ func TestMultipleNames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestKnownTypes(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
if len(s.KnownTypes("v2")) != 0 {
|
||||
t.Errorf("should have no known types for v2")
|
||||
}
|
||||
|
||||
types := s.KnownTypes("v1")
|
||||
for _, s := range []string{"TestType1", "TestType2", "TestType3", "ExternalInternalSame"} {
|
||||
if _, ok := types[s]; !ok {
|
||||
t.Errorf("missing type %q", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertToVersion(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
tt := &TestType1{A: "I'm not a pointer object"}
|
||||
other, err := s.ConvertToVersion(tt, "v1")
|
||||
if err != nil {
|
||||
t.Fatalf("Failure: %v", err)
|
||||
}
|
||||
converted, ok := other.(*ExternalTestType1)
|
||||
if !ok {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if tt.A != converted.A {
|
||||
t.Fatalf("Failed to convert object correctly: %#v", converted)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertToVersionErr(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
tt := TestType1{A: "I'm not a pointer object"}
|
||||
_, err := s.ConvertToVersion(tt, "v1")
|
||||
if err == nil {
|
||||
t.Fatalf("unexpected non-error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncode_NonPtr(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
tt := TestType1{A: "I'm not a pointer object"}
|
||||
|
@ -33,6 +33,11 @@ type Codec interface {
|
||||
Encoder
|
||||
}
|
||||
|
||||
// ObjectConvertor converts an object to a different version.
|
||||
type ObjectConvertor interface {
|
||||
ConvertToVersion(in Object, outVersion string) (out Object, err error)
|
||||
}
|
||||
|
||||
// ObjectTyper contains methods for extracting the APIVersion and Kind
|
||||
// of objects.
|
||||
type ObjectTyper interface {
|
||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
@ -223,6 +224,23 @@ func (s *Scheme) Convert(in, out interface{}) error {
|
||||
return s.raw.Convert(in, out)
|
||||
}
|
||||
|
||||
// ConvertToVersion attempts to convert an input object to its matching Kind in another
|
||||
// version within this scheme. Will return an error if the provided version does not
|
||||
// contain the inKind (or a mapping by name defined with AddKnownTypeWithName). Will also
|
||||
// return an error if the conversion does not result in a valid Object being
|
||||
// returned.
|
||||
func (s *Scheme) ConvertToVersion(in Object, outVersion string) (Object, error) {
|
||||
unknown, err := s.raw.ConvertToVersion(in, outVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj, ok := unknown.(Object)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided object cannot be converted to a runtime.Object: %#v", unknown)
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// EncodeToVersion turns the given api object into an appropriate JSON string.
|
||||
// Will return an error if the object doesn't have an embedded TypeMeta.
|
||||
// Obj may be a pointer to a struct, or a struct. If a struct, a copy
|
||||
|
Loading…
Reference in New Issue
Block a user