diff --git a/pkg/conversion/scheme.go b/pkg/conversion/scheme.go index 3b4f0b93859..d5300378777 100644 --- a/pkg/conversion/scheme.go +++ b/pkg/conversion/scheme.go @@ -53,7 +53,7 @@ type Scheme struct { // typeToKind allows one to figure out the desired "kind" field for a given // go object. Requirements and caveats are the same as typeToVersion. - typeToKind map[reflect.Type]string + typeToKind map[reflect.Type][]string // converter stores all registered conversion functions. It also has // default coverting behavior. @@ -77,7 +77,7 @@ func NewScheme() *Scheme { s := &Scheme{ versionMap: map[string]map[string]reflect.Type{}, typeToVersion: map[reflect.Type]string{}, - typeToKind: map[reflect.Type]string{}, + typeToKind: map[reflect.Type][]string{}, converter: NewConverter(), InternalVersion: "", MetaInsertionFactory: metaInsertion{}, @@ -95,7 +95,7 @@ func (s *Scheme) Log(l DebugLogger) { // the go name of the type if the type is not registered. func (s *Scheme) nameFunc(t reflect.Type) string { if kind, ok := s.typeToKind[t]; ok { - return kind + return kind[0] } return t.Name() } @@ -121,7 +121,7 @@ func (s *Scheme) AddKnownTypes(version string, types ...interface{}) { } knownTypes[t.Name()] = t s.typeToVersion[t] = version - s.typeToKind[t] = t.Name() + s.typeToKind[t] = append(s.typeToKind[t], t.Name()) } } @@ -144,7 +144,7 @@ func (s *Scheme) AddKnownTypeWithName(version, kind string, obj interface{}) { } knownTypes[kind] = t s.typeToVersion[t] = version - s.typeToKind[t] = kind + s.typeToKind[t] = append(s.typeToKind[t], kind) } // KnownTypes returns an array of the types that are known for a particular version. @@ -284,11 +284,13 @@ func (s *Scheme) ObjectVersionAndKind(obj interface{}) (apiVersion, kind string, } t := v.Type() version, vOK := s.typeToVersion[t] - kind, kOK := s.typeToKind[t] + kinds, kOK := s.typeToKind[t] if !vOK || !kOK { return "", "", fmt.Errorf("Unregistered type: %v", t) } - return version, kind, nil + apiVersion = version + kind = kinds[0] + return } // SetVersionAndKind sets the version and kind fields (with help from diff --git a/pkg/conversion/scheme_test.go b/pkg/conversion/scheme_test.go index e75708478a3..16157e866a0 100644 --- a/pkg/conversion/scheme_test.go +++ b/pkg/conversion/scheme_test.go @@ -21,6 +21,7 @@ import ( "flag" "fmt" "reflect" + "strings" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -125,6 +126,8 @@ func GetTestScheme() *Scheme { s.AddKnownTypes("v1", &ExternalInternalSame{}) s.AddKnownTypeWithName("v1", "TestType1", &ExternalTestType1{}) s.AddKnownTypeWithName("v1", "TestType2", &ExternalTestType2{}) + s.AddKnownTypeWithName("", "TestType3", &TestType1{}) + s.AddKnownTypeWithName("v1", "TestType3", &ExternalTestType1{}) s.InternalVersion = "" s.MetaInsertionFactory = testMetaInsertionFactory{} return s @@ -216,6 +219,27 @@ func TestTypes(t *testing.T) { } } +func TestMultipleNames(t *testing.T) { + s := GetTestScheme() + + obj, err := s.Decode([]byte(`{"myKindKey":"TestType3","myVersionKey":"v1","A":"value"}`)) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + internal := obj.(*TestType1) + if internal.A != "value" { + t.Fatalf("unexpected decoded object: %#v", internal) + } + + out, err := s.EncodeToVersion(internal, "v1") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !strings.Contains(string(out), `"myKindKey":"TestType1"`) { + t.Errorf("unexpected encoded output: %s", string(out)) + } +} + func TestEncode_NonPtr(t *testing.T) { s := GetTestScheme() tt := TestType1{A: "I'm not a pointer object"}