diff --git a/federation/pkg/typeadapters/adapter.go b/federation/pkg/typeadapters/adapter.go index b5799666a6c..a0f8b1ae0c9 100644 --- a/federation/pkg/typeadapters/adapter.go +++ b/federation/pkg/typeadapters/adapter.go @@ -17,6 +17,8 @@ limitations under the License. package typeadapters import ( + "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" pkgruntime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -29,8 +31,6 @@ import ( // federated type. Code written to this interface can then target any // type for which an implementation of this interface exists. type FederatedTypeAdapter interface { - SetClient(client federationclientset.Interface) - Kind() string ObjectType() pkgruntime.Object IsExpectedType(obj interface{}) bool @@ -57,3 +57,35 @@ type FederatedTypeAdapter interface { NewTestObject(namespace string) pkgruntime.Object } + +// AdapterFactory defines the function signature for factory methods +// that create FederatedTypeAdapters. Such methods should be +// registered with RegisterAdapterFactory to ensure the type adapter +// is discoverable. +type AdapterFactory func(client federationclientset.Interface) FederatedTypeAdapter + +var typeAdapterRegistry = make(map[string]AdapterFactory) + +// RegisterAdapterFactory ensures that the given kind and adapter +// factory will be returned in the results of the AdapterFactories +// method. +func RegisterAdapterFactory(kind string, factory AdapterFactory) { + _, ok := typeAdapterRegistry[kind] + if ok { + // TODO Is panicking ok given that this is part of a type-registration mechanism + panic(fmt.Sprintf("An adapter has already been registered for federated type %q", kind)) + } + typeAdapterRegistry[kind] = factory +} + +// AdapterFactories returns a mapping of federated kind +// (e.g. "secret") to the factory method that will create an adapter +// for that type. +func AdapterFactories() map[string]AdapterFactory { + // Return a copy to avoid accidental mutation + result := make(map[string]AdapterFactory) + for key, value := range typeAdapterRegistry { + result[key] = value + } + return result +} diff --git a/federation/pkg/typeadapters/secret.go b/federation/pkg/typeadapters/secret.go index aae439c611e..1d467405163 100644 --- a/federation/pkg/typeadapters/secret.go +++ b/federation/pkg/typeadapters/secret.go @@ -27,20 +27,22 @@ import ( kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" ) +const secretKind = "secret" + +func init() { + RegisterAdapterFactory(secretKind, NewSecretAdapter) +} + type SecretAdapter struct { client federationclientset.Interface } -func NewSecretAdapter(client federationclientset.Interface) *SecretAdapter { +func NewSecretAdapter(client federationclientset.Interface) FederatedTypeAdapter { return &SecretAdapter{client: client} } -func (a *SecretAdapter) SetClient(client federationclientset.Interface) { - a.client = client -} - func (a *SecretAdapter) Kind() string { - return "secret" + return secretKind } func (a *SecretAdapter) ObjectType() pkgruntime.Object { diff --git a/test/integration/federation/framework/secret.go b/test/integration/federation/framework/secret.go index ab2d143da9a..f24c364b05a 100644 --- a/test/integration/federation/framework/secret.go +++ b/test/integration/federation/framework/secret.go @@ -26,7 +26,7 @@ import ( ) type SecretFixture struct { - adapter *typeadapters.SecretAdapter + adapter typeadapters.FederatedTypeAdapter stopChan chan struct{} }