mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +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:
		@@ -211,6 +211,46 @@ func (s *Scheme) Convert(in, out interface{}) error {
 | 
				
			|||||||
	return s.converter.Convert(in, out, 0, s.generateConvertMeta(inVersion, outVersion))
 | 
						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.
 | 
					// generateConvertMeta constructs the meta value we pass to Convert.
 | 
				
			||||||
func (s *Scheme) generateConvertMeta(srcVersion, destVersion string) *Meta {
 | 
					func (s *Scheme) generateConvertMeta(srcVersion, destVersion string) *Meta {
 | 
				
			||||||
	return &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) {
 | 
					func TestEncode_NonPtr(t *testing.T) {
 | 
				
			||||||
	s := GetTestScheme()
 | 
						s := GetTestScheme()
 | 
				
			||||||
	tt := TestType1{A: "I'm not a pointer object"}
 | 
						tt := TestType1{A: "I'm not a pointer object"}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,11 @@ type Codec interface {
 | 
				
			|||||||
	Encoder
 | 
						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
 | 
					// ObjectTyper contains methods for extracting the APIVersion and Kind
 | 
				
			||||||
// of objects.
 | 
					// of objects.
 | 
				
			||||||
type ObjectTyper interface {
 | 
					type ObjectTyper interface {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ limitations under the License.
 | 
				
			|||||||
package runtime
 | 
					package runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
				
			||||||
@@ -223,6 +224,23 @@ func (s *Scheme) Convert(in, out interface{}) error {
 | 
				
			|||||||
	return s.raw.Convert(in, out)
 | 
						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.
 | 
					// EncodeToVersion turns the given api object into an appropriate JSON string.
 | 
				
			||||||
// Will return an error if the object doesn't have an embedded TypeMeta.
 | 
					// 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
 | 
					// Obj may be a pointer to a struct, or a struct. If a struct, a copy
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user