mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	apimachinery: handle duplicated and conflicting type registration
This commit is contained in:
		@@ -22,6 +22,7 @@ import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/conversion"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/types"
 | 
			
		||||
	clientv1 "k8s.io/client-go/pkg/api/v1"
 | 
			
		||||
	"k8s.io/client-go/tools/record"
 | 
			
		||||
@@ -48,10 +49,11 @@ func NewFederatedEventSink(clientset fedclientset.Interface) *FederatedEventSink
 | 
			
		||||
var scheme = runtime.NewScheme()
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	scheme.AddKnownTypes(clientv1.SchemeGroupVersion,
 | 
			
		||||
		&clientv1.Event{},
 | 
			
		||||
		&kubev1.Event{},
 | 
			
		||||
	)
 | 
			
		||||
	// register client-go's and kube's Event type under two different GroupVersions
 | 
			
		||||
	// TODO: switch to client-go client for events
 | 
			
		||||
	scheme.AddKnownTypes(clientv1.SchemeGroupVersion, &clientv1.Event{})
 | 
			
		||||
	scheme.AddKnownTypes(schema.GroupVersion{Group: "fake-kube-" + kubev1.SchemeGroupVersion.Group, Version: kubev1.SchemeGroupVersion.Version}, &kubev1.Event{})
 | 
			
		||||
 | 
			
		||||
	if err := scheme.AddConversionFuncs(
 | 
			
		||||
		metav1.Convert_unversioned_Time_To_unversioned_Time,
 | 
			
		||||
	); err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -174,7 +174,8 @@ func TestCommonKindsRegistered(t *testing.T) {
 | 
			
		||||
				t.Error(err)
 | 
			
		||||
			}
 | 
			
		||||
			defaults := gv.WithKind("")
 | 
			
		||||
			if _, got, err := api.Codecs.LegacyCodec().Decode([]byte(`{"kind":"`+kind+`"}`), &defaults, nil); err != nil || gvk != *got {
 | 
			
		||||
			var got *schema.GroupVersionKind
 | 
			
		||||
			if obj, got, err = api.Codecs.LegacyCodec().Decode([]byte(`{"kind":"`+kind+`"}`), &defaults, obj); err != nil || gvk != *got {
 | 
			
		||||
				t.Errorf("expected %v: %v %v", gvk, got, err)
 | 
			
		||||
			}
 | 
			
		||||
			data, err := runtime.Encode(api.Codecs.LegacyCodec(*gv), obj)
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/api/v1"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GroupName is the group name use in this package
 | 
			
		||||
@@ -39,10 +38,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
	scheme.AddKnownTypes(SchemeGroupVersion,
 | 
			
		||||
		&HorizontalPodAutoscaler{},
 | 
			
		||||
		&HorizontalPodAutoscalerList{},
 | 
			
		||||
		&v1.ListOptions{},
 | 
			
		||||
		&v1.DeleteOptions{},
 | 
			
		||||
		&metav1.GetOptions{},
 | 
			
		||||
		&metav1.ExportOptions{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ limitations under the License.
 | 
			
		||||
package rbac
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
)
 | 
			
		||||
@@ -55,6 +54,5 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
		&ClusterRoleBindingList{},
 | 
			
		||||
		&ClusterRoleList{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,10 @@ func NewMetadataCodecFactory() serializer.CodecFactory {
 | 
			
		||||
		if kind.Version == runtime.APIVersionInternal {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if kind == api.Unversioned.WithKind("Status") {
 | 
			
		||||
			// this is added below as unversioned
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		metaOnlyObject := gvkToMetadataOnlyObject(kind)
 | 
			
		||||
		scheme.AddKnownTypeWithName(kind, metaOnlyObject)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -190,7 +190,17 @@ func (s *Scheme) AddKnownTypeWithName(gvk schema.GroupVersionKind, obj Object) {
 | 
			
		||||
		panic("All types must be pointers to structs.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if oldT, found := s.gvkToType[gvk]; found && oldT != t {
 | 
			
		||||
		panic(fmt.Sprintf("Double registration of different types for %v: old=%v.%v, new=%v.%v", gvk, oldT.PkgPath(), oldT.Name(), t.PkgPath(), t.Name()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.gvkToType[gvk] = t
 | 
			
		||||
 | 
			
		||||
	for _, existingGvk := range s.typeToGVK[t] {
 | 
			
		||||
		if existingGvk == gvk {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s.typeToGVK[t] = append(s.typeToGVK[t], gvk)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -548,6 +548,79 @@ func TestKnownTypes(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestAddKnownTypesIdemPotent(t *testing.T) {
 | 
			
		||||
	s := runtime.NewScheme()
 | 
			
		||||
 | 
			
		||||
	gv := schema.GroupVersion{Group: "foo", Version: "v1"}
 | 
			
		||||
	s.AddKnownTypes(gv, &InternalSimple{})
 | 
			
		||||
	s.AddKnownTypes(gv, &InternalSimple{})
 | 
			
		||||
	if len(s.KnownTypes(gv)) != 1 {
 | 
			
		||||
		t.Errorf("expected only one %v type after double registration", gv)
 | 
			
		||||
	}
 | 
			
		||||
	if len(s.AllKnownTypes()) != 1 {
 | 
			
		||||
		t.Errorf("expected only one type after double registration")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{})
 | 
			
		||||
	s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{})
 | 
			
		||||
	if len(s.KnownTypes(gv)) != 1 {
 | 
			
		||||
		t.Errorf("expected only one %v type after double registration with custom name", gv)
 | 
			
		||||
	}
 | 
			
		||||
	if len(s.AllKnownTypes()) != 1 {
 | 
			
		||||
		t.Errorf("expected only one type after double registration with custom name")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.AddUnversionedTypes(gv, &InternalSimple{})
 | 
			
		||||
	if len(s.KnownTypes(gv)) != 1 {
 | 
			
		||||
		t.Errorf("expected only one %v type after double registration with custom name", gv)
 | 
			
		||||
	}
 | 
			
		||||
	if len(s.AllKnownTypes()) != 1 {
 | 
			
		||||
		t.Errorf("expected only one type after double registration with custom name")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kinds, _, err := s.ObjectKinds(&InternalSimple{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatalf("unexpected error: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	if len(kinds) != 1 {
 | 
			
		||||
		t.Errorf("expected only one kind for InternalSimple after double registration", gv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestConflictingAddKnownTypes(t *testing.T) {
 | 
			
		||||
	s := runtime.NewScheme()
 | 
			
		||||
	gv := schema.GroupVersion{Group: "foo", Version: "v1"}
 | 
			
		||||
 | 
			
		||||
	panicked := make(chan bool)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer func() {
 | 
			
		||||
			if recover() != nil {
 | 
			
		||||
				panicked <- true
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
		s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &InternalSimple{})
 | 
			
		||||
		s.AddKnownTypeWithName(gv.WithKind("InternalSimple"), &ExternalSimple{})
 | 
			
		||||
		panicked <- false
 | 
			
		||||
	}()
 | 
			
		||||
	if !<-panicked {
 | 
			
		||||
		t.Errorf("Expected AddKnownTypesWithName to panic with conflicting type registrations")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer func() {
 | 
			
		||||
			if recover() != nil {
 | 
			
		||||
				panicked <- true
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
		s.AddUnversionedTypes(gv, &InternalSimple{})
 | 
			
		||||
		s.AddUnversionedTypes(gv, &InternalSimple{})
 | 
			
		||||
		panicked <- false
 | 
			
		||||
	}()
 | 
			
		||||
	if !<-panicked {
 | 
			
		||||
		t.Errorf("Expected AddUnversionedTypes to panic with conflicting type registrations")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestConvertToVersionBasic(t *testing.T) {
 | 
			
		||||
	s := GetTestScheme()
 | 
			
		||||
	tt := &TestType1{A: "I'm not a pointer object"}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ limitations under the License.
 | 
			
		||||
package apiserver
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
)
 | 
			
		||||
@@ -47,6 +46,5 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
	scheme.AddKnownTypes(SchemeGroupVersion,
 | 
			
		||||
		&AdmissionConfiguration{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ limitations under the License.
 | 
			
		||||
package example
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
)
 | 
			
		||||
@@ -48,6 +47,5 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
	scheme.AddKnownTypes(SchemeGroupVersion,
 | 
			
		||||
		&Pod{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -77,7 +77,6 @@ func testScheme(t *testing.T) (*runtime.Scheme, serializer.CodecFactory) {
 | 
			
		||||
	scheme := runtime.NewScheme()
 | 
			
		||||
	scheme.Log(t)
 | 
			
		||||
	scheme.AddKnownTypes(schema.GroupVersion{Version: runtime.APIVersionInternal}, &storagetesting.TestResource{})
 | 
			
		||||
	scheme.AddKnownTypes(schema.GroupVersion{Version: runtime.APIVersionInternal}, &storagetesting.TestResource{})
 | 
			
		||||
	example.AddToScheme(scheme)
 | 
			
		||||
	examplev1.AddToScheme(scheme)
 | 
			
		||||
	if err := scheme.AddConversionFuncs(
 | 
			
		||||
 
 | 
			
		||||
@@ -17,12 +17,8 @@ limitations under the License.
 | 
			
		||||
package apiregistration
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
 | 
			
		||||
	// we register here until we separate our scheme, which requires updates to client gen
 | 
			
		||||
	kapi "k8s.io/client-go/pkg/api"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const GroupName = "apiregistration.k8s.io"
 | 
			
		||||
@@ -50,11 +46,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
	scheme.AddKnownTypes(SchemeGroupVersion,
 | 
			
		||||
		&APIService{},
 | 
			
		||||
		&APIServiceList{},
 | 
			
		||||
 | 
			
		||||
		&kapi.ListOptions{},
 | 
			
		||||
		&metav1.DeleteOptions{},
 | 
			
		||||
		&metav1.GetOptions{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,6 @@ limitations under the License.
 | 
			
		||||
package wardle
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime"
 | 
			
		||||
	"k8s.io/apimachinery/pkg/runtime/schema"
 | 
			
		||||
)
 | 
			
		||||
@@ -48,6 +47,5 @@ func addKnownTypes(scheme *runtime.Scheme) error {
 | 
			
		||||
		&Flunder{},
 | 
			
		||||
		&FlunderList{},
 | 
			
		||||
	)
 | 
			
		||||
	metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user