fed: adapter registry -> type registry to enable ctlr mgr use

This commit is contained in:
Maru Newby 2017-04-06 20:58:22 -07:00
parent 6f061f7962
commit 1ebffa7112
10 changed files with 81 additions and 55 deletions

View File

@ -31,6 +31,7 @@ go_library(
"//federation/pkg/federation-controller/replicaset:go_default_library",
"//federation/pkg/federation-controller/secret:go_default_library",
"//federation/pkg/federation-controller/service:go_default_library",
"//federation/pkg/typeadapters:go_default_library",
"//pkg/util/configz:go_default_library",
"//pkg/version:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",

View File

@ -45,6 +45,7 @@ import (
replicasetcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/replicaset"
secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret"
servicecontroller "k8s.io/kubernetes/federation/pkg/federation-controller/service"
"k8s.io/kubernetes/federation/pkg/typeadapters"
"k8s.io/kubernetes/pkg/util/configz"
"k8s.io/kubernetes/pkg/version"
@ -159,8 +160,11 @@ func StartControllers(s *options.CMServer, restClientCfg *restclient.Config) err
namespaceController.Run(wait.NeverStop)
}
if controllerEnabled(s.Controllers, serverResources, secretcontroller.ControllerName, secretcontroller.RequiredResources, true) {
secretcontroller.StartSecretController(restClientCfg, stopChan, minimizeLatency)
for kind, federatedType := range typeadapters.FederatedTypes() {
if controllerEnabled(s.Controllers, serverResources, federatedType.ControllerName, federatedType.RequiredResources, true) {
// TODO the generic controller doesn't belong in the secretcontroller package
secretcontroller.StartFederationSyncController(kind, federatedType.AdapterFactory, restClientCfg, stopChan, minimizeLatency)
}
}
if controllerEnabled(s.Controllers, serverResources, configmapcontroller.ControllerName, configmapcontroller.RequiredResources, true) {

View File

@ -20,14 +20,12 @@ go_library(
"//federation/pkg/federation-controller/util/eventsink:go_default_library",
"//federation/pkg/typeadapters:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/controller:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
@ -49,6 +47,7 @@ go_test(
"//federation/pkg/federation-controller/util:go_default_library",
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
"//federation/pkg/federation-controller/util/test:go_default_library",
"//federation/pkg/typeadapters:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/clientset_generated/clientset/fake:go_default_library",

View File

@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
pkgruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
clientv1 "k8s.io/client-go/pkg/api/v1"
@ -39,7 +38,6 @@ import (
"k8s.io/kubernetes/federation/pkg/federation-controller/util/eventsink"
"k8s.io/kubernetes/federation/pkg/typeadapters"
"k8s.io/kubernetes/pkg/api"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/controller"
@ -48,11 +46,6 @@ import (
const (
allClustersKey = "ALL_CLUSTERS"
ControllerName = "secrets"
)
var (
RequiredResources = []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource("secrets")}
)
// FederationSyncController synchronizes the state of a federated type
@ -93,16 +86,6 @@ type FederationSyncController struct {
adapter typeadapters.FederatedTypeAdapter
}
// StartSecretController starts a new secret controller
func StartSecretController(config *restclient.Config, stopChan <-chan struct{}, minimizeLatency bool) {
StartFederationSyncController(typeadapters.SecretKind, typeadapters.NewSecretAdapter, config, stopChan, minimizeLatency)
}
// newSecretController returns a new secret controller
func newSecretController(client federationclientset.Interface) *FederationSyncController {
return newFederationSyncController(client, typeadapters.NewSecretAdapter(client))
}
// StartFederationSyncController starts a new sync controller for a type adapter
func StartFederationSyncController(kind string, adapterFactory typeadapters.AdapterFactory, config *restclient.Config, stopChan <-chan struct{}, minimizeLatency bool) {
restclient.AddUserAgent(config, fmt.Sprintf("%s-controller", kind))

View File

@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
"k8s.io/kubernetes/federation/pkg/federation-controller/util/deletionhelper"
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
"k8s.io/kubernetes/federation/pkg/typeadapters"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
fakekubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
@ -66,7 +67,7 @@ func TestSecretController(t *testing.T) {
RegisterFakeList(secrets, &cluster2Client.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}})
cluster2CreateChan := RegisterFakeCopyOnCreate(secrets, &cluster2Client.Fake, cluster2Watch)
secretController := newSecretController(fakeClient)
secretController := newFederationSyncController(fakeClient, typeadapters.NewSecretAdapter(fakeClient))
informerClientFactory := func(cluster *federationapi.Cluster) (kubeclientset.Interface, error) {
switch cluster.Name {
case cluster1.Name:

View File

@ -11,6 +11,7 @@ go_library(
name = "go_default_library",
srcs = [
"adapter.go",
"registry.go",
"secret.go",
],
tags = ["automanaged"],
@ -21,6 +22,7 @@ go_library(
"//pkg/client/clientset_generated/clientset:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
],

View File

@ -17,8 +17,6 @@ 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"
@ -63,29 +61,3 @@ type FederatedTypeAdapter interface {
// 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
}

View File

@ -0,0 +1,59 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package typeadapters
import (
"fmt"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// FederatedType configures federation for a kubernetes type
type FederatedType struct {
Kind string
ControllerName string
RequiredResources []schema.GroupVersionResource
AdapterFactory AdapterFactory
}
var typeRegistry = make(map[string]FederatedType)
// RegisterFederatedType ensures that configuration for the given kind will be returned by the FederatedTypes method.
func RegisterFederatedType(kind, controllerName string, requiredResources []schema.GroupVersionResource, factory AdapterFactory) {
_, ok := typeRegistry[kind]
if ok {
// TODO Is panicking ok given that this is part of a type-registration mechanism
panic(fmt.Sprintf("Federated type %q has already been registered", kind))
}
typeRegistry[kind] = FederatedType{
Kind: kind,
ControllerName: controllerName,
RequiredResources: requiredResources,
AdapterFactory: factory,
}
}
// FederatedTypes returns a mapping of kind (e.g. "secret") to the
// type information required to configure its federation.
func FederatedTypes() map[string]FederatedType {
// TODO copy RequiredResources to avoid accidental mutation
result := make(map[string]FederatedType)
for key, value := range typeRegistry {
result[key] = value
}
return result
}

View File

@ -19,6 +19,7 @@ package typeadapters
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
pkgruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
@ -27,10 +28,13 @@ import (
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
)
const SecretKind = "secret"
const (
SecretKind = "secret"
SecretControllerName = "secrets"
)
func init() {
RegisterAdapterFactory(SecretKind, NewSecretAdapter)
RegisterFederatedType(SecretKind, SecretControllerName, []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource(SecretControllerName)}, NewSecretAdapter)
}
type SecretAdapter struct {

View File

@ -32,14 +32,15 @@ func TestFederationCRUD(t *testing.T) {
fedFixture.SetUp(t)
defer fedFixture.TearDown(t)
for kind, adapterFactory := range typeadapters.AdapterFactories() {
federatedTypes := typeadapters.FederatedTypes()
for kind, fedType := range federatedTypes {
t.Run(kind, func(t *testing.T) {
config := fedFixture.APIFixture.NewConfig()
fixture := framework.NewControllerFixture(t, kind, adapterFactory, config)
fixture := framework.NewControllerFixture(t, kind, fedType.AdapterFactory, config)
defer fixture.TearDown(t)
client := fedFixture.APIFixture.NewClient(fmt.Sprintf("crud-test-%s", kind))
adapter := adapterFactory(client)
adapter := fedType.AdapterFactory(client)
crudtester := framework.NewFederatedTypeCRUDTester(t, adapter, fedFixture.ClusterClients)
obj := adapter.NewTestObject(uuid.New())