mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Merge pull request #43713 from marun/fed-secret-upgrade-test-redux
Automatic merge from submit-queue [Federation] Add federated type registry This PR adds a registry for federated types. The goal is to simplify the consumption of federated type configuration by controllers/integration tests/e2e tests/upgrade tests. Consumers can iterate over ``fedtypes.FederatedTypes()``, as per the usage in the crud integration test and controller manager in this PR. The previous name for the the adapter package - ``typeadapters`` - has been changed to ``fedtypes`` to reflect the fact that more than just type adapters are defined there. I'm happy to take suggestions on the name, ``fedtypes`` was just the first thing that came to mind. cc: @kubernetes/sig-federation-pr-reviews
This commit is contained in:
commit
f96b187fcb
@ -27,9 +27,9 @@ filegroup(
|
|||||||
"//federation/cmd/kubefed:all-srcs",
|
"//federation/cmd/kubefed:all-srcs",
|
||||||
"//federation/develop:all-srcs",
|
"//federation/develop:all-srcs",
|
||||||
"//federation/pkg/dnsprovider:all-srcs",
|
"//federation/pkg/dnsprovider:all-srcs",
|
||||||
|
"//federation/pkg/federatedtypes:all-srcs",
|
||||||
"//federation/pkg/federation-controller:all-srcs",
|
"//federation/pkg/federation-controller:all-srcs",
|
||||||
"//federation/pkg/kubefed:all-srcs",
|
"//federation/pkg/kubefed:all-srcs",
|
||||||
"//federation/pkg/typeadapters:all-srcs",
|
|
||||||
"//federation/registry/cluster:all-srcs",
|
"//federation/registry/cluster:all-srcs",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
|
@ -22,6 +22,7 @@ go_library(
|
|||||||
"//federation/pkg/dnsprovider/providers/aws/route53:go_default_library",
|
"//federation/pkg/dnsprovider/providers/aws/route53:go_default_library",
|
||||||
"//federation/pkg/dnsprovider/providers/coredns:go_default_library",
|
"//federation/pkg/dnsprovider/providers/coredns:go_default_library",
|
||||||
"//federation/pkg/dnsprovider/providers/google/clouddns:go_default_library",
|
"//federation/pkg/dnsprovider/providers/google/clouddns:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
"//federation/pkg/federation-controller/cluster:go_default_library",
|
"//federation/pkg/federation-controller/cluster:go_default_library",
|
||||||
"//federation/pkg/federation-controller/configmap:go_default_library",
|
"//federation/pkg/federation-controller/configmap:go_default_library",
|
||||||
"//federation/pkg/federation-controller/daemonset:go_default_library",
|
"//federation/pkg/federation-controller/daemonset:go_default_library",
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options"
|
"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options"
|
||||||
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
"k8s.io/kubernetes/federation/pkg/dnsprovider"
|
||||||
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
clustercontroller "k8s.io/kubernetes/federation/pkg/federation-controller/cluster"
|
clustercontroller "k8s.io/kubernetes/federation/pkg/federation-controller/cluster"
|
||||||
configmapcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/configmap"
|
configmapcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/configmap"
|
||||||
daemonsetcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/daemonset"
|
daemonsetcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/daemonset"
|
||||||
@ -159,8 +160,11 @@ func StartControllers(s *options.CMServer, restClientCfg *restclient.Config) err
|
|||||||
namespaceController.Run(wait.NeverStop)
|
namespaceController.Run(wait.NeverStop)
|
||||||
}
|
}
|
||||||
|
|
||||||
if controllerEnabled(s.Controllers, serverResources, secretcontroller.ControllerName, secretcontroller.RequiredResources, true) {
|
for kind, federatedType := range federatedtypes.FederatedTypes() {
|
||||||
secretcontroller.StartSecretController(restClientCfg, stopChan, minimizeLatency)
|
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) {
|
if controllerEnabled(s.Controllers, serverResources, configmapcontroller.ControllerName, configmapcontroller.RequiredResources, true) {
|
||||||
|
@ -11,6 +11,7 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"adapter.go",
|
"adapter.go",
|
||||||
|
"registry.go",
|
||||||
"secret.go",
|
"secret.go",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
@ -21,6 +22,7 @@ go_library(
|
|||||||
"//pkg/client/clientset_generated/clientset:go_default_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/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime: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/types:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
],
|
],
|
||||||
@ -37,7 +39,7 @@ filegroup(
|
|||||||
name = "all-srcs",
|
name = "all-srcs",
|
||||||
srcs = [
|
srcs = [
|
||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//federation/pkg/typeadapters/crudtester:all-srcs",
|
"//federation/pkg/federatedtypes/crudtester:all-srcs",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package typeadapters
|
package federatedtypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -29,8 +29,6 @@ import (
|
|||||||
// federated type. Code written to this interface can then target any
|
// federated type. Code written to this interface can then target any
|
||||||
// type for which an implementation of this interface exists.
|
// type for which an implementation of this interface exists.
|
||||||
type FederatedTypeAdapter interface {
|
type FederatedTypeAdapter interface {
|
||||||
SetClient(client federationclientset.Interface)
|
|
||||||
|
|
||||||
Kind() string
|
Kind() string
|
||||||
ObjectType() pkgruntime.Object
|
ObjectType() pkgruntime.Object
|
||||||
IsExpectedType(obj interface{}) bool
|
IsExpectedType(obj interface{}) bool
|
||||||
@ -57,3 +55,9 @@ type FederatedTypeAdapter interface {
|
|||||||
|
|
||||||
NewTestObject(namespace string) pkgruntime.Object
|
NewTestObject(namespace string) pkgruntime.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AdapterFactory defines the function signature for factory methods
|
||||||
|
// that create instances of FederatedTypeAdapter. Such methods should
|
||||||
|
// be registered with RegisterAdapterFactory to ensure the type
|
||||||
|
// adapter is discoverable.
|
||||||
|
type AdapterFactory func(client federationclientset.Interface) FederatedTypeAdapter
|
@ -12,7 +12,7 @@ go_library(
|
|||||||
srcs = ["crudtester.go"],
|
srcs = ["crudtester.go"],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//federation/pkg/typeadapters:go_default_library",
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors: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/apis/meta/v1:go_default_library",
|
@ -23,7 +23,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters"
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ type TestLogger interface {
|
|||||||
// members of a federation.
|
// members of a federation.
|
||||||
type FederatedTypeCRUDTester struct {
|
type FederatedTypeCRUDTester struct {
|
||||||
tl TestLogger
|
tl TestLogger
|
||||||
adapter typeadapters.FederatedTypeAdapter
|
adapter federatedtypes.FederatedTypeAdapter
|
||||||
kind string
|
kind string
|
||||||
clusterClients []clientset.Interface
|
clusterClients []clientset.Interface
|
||||||
waitInterval time.Duration
|
waitInterval time.Duration
|
||||||
@ -54,7 +54,7 @@ type FederatedTypeCRUDTester struct {
|
|||||||
clusterWaitTimeout time.Duration
|
clusterWaitTimeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFederatedTypeCRUDTester(testLogger TestLogger, adapter typeadapters.FederatedTypeAdapter, clusterClients []clientset.Interface, waitInterval, clusterWaitTimeout time.Duration) *FederatedTypeCRUDTester {
|
func NewFederatedTypeCRUDTester(testLogger TestLogger, adapter federatedtypes.FederatedTypeAdapter, clusterClients []clientset.Interface, waitInterval, clusterWaitTimeout time.Duration) *FederatedTypeCRUDTester {
|
||||||
return &FederatedTypeCRUDTester{
|
return &FederatedTypeCRUDTester{
|
||||||
tl: testLogger,
|
tl: testLogger,
|
||||||
adapter: adapter,
|
adapter: adapter,
|
59
federation/pkg/federatedtypes/registry.go
Normal file
59
federation/pkg/federatedtypes/registry.go
Normal 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 federatedtypes
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package typeadapters
|
package federatedtypes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
@ -27,20 +28,25 @@ import (
|
|||||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SecretKind = "secret"
|
||||||
|
SecretControllerName = "secrets"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterFederatedType(SecretKind, SecretControllerName, []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource(SecretControllerName)}, NewSecretAdapter)
|
||||||
|
}
|
||||||
|
|
||||||
type SecretAdapter struct {
|
type SecretAdapter struct {
|
||||||
client federationclientset.Interface
|
client federationclientset.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSecretAdapter(client federationclientset.Interface) *SecretAdapter {
|
func NewSecretAdapter(client federationclientset.Interface) FederatedTypeAdapter {
|
||||||
return &SecretAdapter{client: client}
|
return &SecretAdapter{client: client}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SecretAdapter) SetClient(client federationclientset.Interface) {
|
|
||||||
a.client = client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *SecretAdapter) Kind() string {
|
func (a *SecretAdapter) Kind() string {
|
||||||
return "secret"
|
return SecretKind
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SecretAdapter) ObjectType() pkgruntime.Object {
|
func (a *SecretAdapter) ObjectType() pkgruntime.Object {
|
@ -15,19 +15,17 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util:go_default_library",
|
"//federation/pkg/federation-controller/util:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
|
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util/eventsink:go_default_library",
|
"//federation/pkg/federation-controller/util/eventsink:go_default_library",
|
||||||
"//federation/pkg/typeadapters:go_default_library",
|
|
||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
"//pkg/controller:go_default_library",
|
"//pkg/controller:go_default_library",
|
||||||
"//vendor/github.com/golang/glog: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/api/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1: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: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/types:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
"//vendor/k8s.io/client-go/pkg/api/v1:go_default_library",
|
||||||
@ -46,6 +44,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
"//federation/client/clientset_generated/federation_clientset/fake:go_default_library",
|
"//federation/client/clientset_generated/federation_clientset/fake:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util:go_default_library",
|
"//federation/pkg/federation-controller/util:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
|
"//federation/pkg/federation-controller/util/deletionhelper:go_default_library",
|
||||||
"//federation/pkg/federation-controller/util/test:go_default_library",
|
"//federation/pkg/federation-controller/util/test:go_default_library",
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
clientv1 "k8s.io/client-go/pkg/api/v1"
|
clientv1 "k8s.io/client-go/pkg/api/v1"
|
||||||
@ -34,12 +33,11 @@ import (
|
|||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||||
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
"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/deletionhelper"
|
||||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util/eventsink"
|
"k8s.io/kubernetes/federation/pkg/federation-controller/util/eventsink"
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
|
||||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
|
|
||||||
@ -48,11 +46,6 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
allClustersKey = "ALL_CLUSTERS"
|
allClustersKey = "ALL_CLUSTERS"
|
||||||
ControllerName = "secrets"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
RequiredResources = []schema.GroupVersionResource{apiv1.SchemeGroupVersion.WithResource("secrets")}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// FederationSyncController synchronizes the state of a federated type
|
// FederationSyncController synchronizes the state of a federated type
|
||||||
@ -90,34 +83,24 @@ type FederationSyncController struct {
|
|||||||
smallDelay time.Duration
|
smallDelay time.Duration
|
||||||
updateTimeout time.Duration
|
updateTimeout time.Duration
|
||||||
|
|
||||||
adapter typeadapters.FederatedTypeAdapter
|
adapter federatedtypes.FederatedTypeAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartSecretController starts a new secret controller
|
// StartFederationSyncController starts a new sync controller for a type adapter
|
||||||
func StartSecretController(config *restclient.Config, stopChan <-chan struct{}, minimizeLatency bool) {
|
func StartFederationSyncController(kind string, adapterFactory federatedtypes.AdapterFactory, config *restclient.Config, stopChan <-chan struct{}, minimizeLatency bool) {
|
||||||
startFederationSyncController(&typeadapters.SecretAdapter{}, config, stopChan, minimizeLatency)
|
restclient.AddUserAgent(config, fmt.Sprintf("%s-controller", kind))
|
||||||
}
|
|
||||||
|
|
||||||
// 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 the given type adapter
|
|
||||||
func startFederationSyncController(adapter typeadapters.FederatedTypeAdapter, config *restclient.Config, stopChan <-chan struct{}, minimizeLatency bool) {
|
|
||||||
restclient.AddUserAgent(config, fmt.Sprintf("%s-controller", adapter.Kind()))
|
|
||||||
client := federationclientset.NewForConfigOrDie(config)
|
client := federationclientset.NewForConfigOrDie(config)
|
||||||
adapter.SetClient(client)
|
adapter := adapterFactory(client)
|
||||||
controller := newFederationSyncController(client, adapter)
|
controller := newFederationSyncController(client, adapter)
|
||||||
if minimizeLatency {
|
if minimizeLatency {
|
||||||
controller.minimizeLatency()
|
controller.minimizeLatency()
|
||||||
}
|
}
|
||||||
glog.Infof(fmt.Sprintf("Starting federated sync controller for %s resources", adapter.Kind()))
|
glog.Infof(fmt.Sprintf("Starting federated sync controller for %s resources", kind))
|
||||||
controller.Run(stopChan)
|
controller.Run(stopChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFederationSyncController returns a new sync controller for the given client and type adapter
|
// newFederationSyncController returns a new sync controller for the given client and type adapter
|
||||||
func newFederationSyncController(client federationclientset.Interface, adapter typeadapters.FederatedTypeAdapter) *FederationSyncController {
|
func newFederationSyncController(client federationclientset.Interface, adapter federatedtypes.FederatedTypeAdapter) *FederationSyncController {
|
||||||
broadcaster := record.NewBroadcaster()
|
broadcaster := record.NewBroadcaster()
|
||||||
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
|
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
|
||||||
recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: fmt.Sprintf("federated-%v-controller", adapter.Kind())})
|
recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: fmt.Sprintf("federated-%v-controller", adapter.Kind())})
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||||
fakefedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset/fake"
|
fakefedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset/fake"
|
||||||
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
"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/deletionhelper"
|
||||||
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
|
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
|
||||||
@ -66,7 +67,7 @@ func TestSecretController(t *testing.T) {
|
|||||||
RegisterFakeList(secrets, &cluster2Client.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}})
|
RegisterFakeList(secrets, &cluster2Client.Fake, &apiv1.SecretList{Items: []apiv1.Secret{}})
|
||||||
cluster2CreateChan := RegisterFakeCopyOnCreate(secrets, &cluster2Client.Fake, cluster2Watch)
|
cluster2CreateChan := RegisterFakeCopyOnCreate(secrets, &cluster2Client.Fake, cluster2Watch)
|
||||||
|
|
||||||
secretController := newSecretController(fakeClient)
|
secretController := newFederationSyncController(fakeClient, federatedtypes.NewSecretAdapter(fakeClient))
|
||||||
informerClientFactory := func(cluster *federationapi.Cluster) (kubeclientset.Interface, error) {
|
informerClientFactory := func(cluster *federationapi.Cluster) (kubeclientset.Interface, error) {
|
||||||
switch cluster.Name {
|
switch cluster.Name {
|
||||||
case cluster1.Name:
|
case cluster1.Name:
|
||||||
|
@ -16,6 +16,7 @@ go_test(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//federation/apis/federation/v1beta1:go_default_library",
|
"//federation/apis/federation/v1beta1:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
"//pkg/api/v1:go_default_library",
|
"//pkg/api/v1:go_default_library",
|
||||||
"//pkg/apis/autoscaling/v1:go_default_library",
|
"//pkg/apis/autoscaling/v1:go_default_library",
|
||||||
"//pkg/apis/batch/v1:go_default_library",
|
"//pkg/apis/batch/v1:go_default_library",
|
||||||
|
@ -17,10 +17,12 @@ limitations under the License.
|
|||||||
package federation
|
package federation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/test/integration/federation/framework"
|
"k8s.io/kubernetes/test/integration/federation/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,15 +32,16 @@ func TestFederationCRUD(t *testing.T) {
|
|||||||
fedFixture.SetUp(t)
|
fedFixture.SetUp(t)
|
||||||
defer fedFixture.TearDown(t)
|
defer fedFixture.TearDown(t)
|
||||||
|
|
||||||
controllerFixtures := []framework.ControllerFixture{
|
federatedTypes := federatedtypes.FederatedTypes()
|
||||||
&framework.SecretFixture{},
|
for kind, fedType := range federatedTypes {
|
||||||
}
|
t.Run(kind, func(t *testing.T) {
|
||||||
for _, fixture := range controllerFixtures {
|
config := fedFixture.APIFixture.NewConfig()
|
||||||
t.Run(fixture.Kind(), func(t *testing.T) {
|
fixture := framework.NewControllerFixture(t, kind, fedType.AdapterFactory, config)
|
||||||
framework.SetUpControllerFixture(t, fedFixture.APIFixture, fixture)
|
|
||||||
defer fixture.TearDown(t)
|
defer fixture.TearDown(t)
|
||||||
|
|
||||||
adapter := fixture.Adapter()
|
client := fedFixture.APIFixture.NewClient(fmt.Sprintf("crud-test-%s", kind))
|
||||||
|
adapter := fedType.AdapterFactory(client)
|
||||||
|
|
||||||
crudtester := framework.NewFederatedTypeCRUDTester(t, adapter, fedFixture.ClusterClients)
|
crudtester := framework.NewFederatedTypeCRUDTester(t, adapter, fedFixture.ClusterClients)
|
||||||
obj := adapter.NewTestObject(uuid.New())
|
obj := adapter.NewTestObject(uuid.New())
|
||||||
crudtester.CheckLifecycle(obj)
|
crudtester.CheckLifecycle(obj)
|
||||||
@ -52,13 +55,17 @@ func TestFederationCRUD(t *testing.T) {
|
|||||||
"Resources should not be deleted from underlying clusters when OrphanDependents is true": &orphanedDependents,
|
"Resources should not be deleted from underlying clusters when OrphanDependents is true": &orphanedDependents,
|
||||||
"Resources should not be deleted from underlying clusters when OrphanDependents is nil": nil,
|
"Resources should not be deleted from underlying clusters when OrphanDependents is nil": nil,
|
||||||
}
|
}
|
||||||
|
kind := federatedtypes.SecretKind
|
||||||
|
adapterFactory := federatedtypes.NewSecretAdapter
|
||||||
for testName, orphanDependents := range testCases {
|
for testName, orphanDependents := range testCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
fixture := &framework.SecretFixture{}
|
config := fedFixture.APIFixture.NewConfig()
|
||||||
framework.SetUpControllerFixture(t, fedFixture.APIFixture, fixture)
|
fixture := framework.NewControllerFixture(t, kind, adapterFactory, config)
|
||||||
defer fixture.TearDown(t)
|
defer fixture.TearDown(t)
|
||||||
|
|
||||||
adapter := fixture.Adapter()
|
client := fedFixture.APIFixture.NewClient(fmt.Sprintf("deletion-test-%s", kind))
|
||||||
|
adapter := adapterFactory(client)
|
||||||
|
|
||||||
crudtester := framework.NewFederatedTypeCRUDTester(t, adapter, fedFixture.ClusterClients)
|
crudtester := framework.NewFederatedTypeCRUDTester(t, adapter, fedFixture.ClusterClients)
|
||||||
obj := adapter.NewTestObject(uuid.New())
|
obj := adapter.NewTestObject(uuid.New())
|
||||||
updatedObj := crudtester.CheckCreate(obj)
|
updatedObj := crudtester.CheckCreate(obj)
|
||||||
|
@ -14,7 +14,6 @@ go_library(
|
|||||||
"controller.go",
|
"controller.go",
|
||||||
"crudtester.go",
|
"crudtester.go",
|
||||||
"federation.go",
|
"federation.go",
|
||||||
"secret.go",
|
|
||||||
"util.go",
|
"util.go",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
@ -23,10 +22,10 @@ go_library(
|
|||||||
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
"//federation/client/clientset_generated/federation_clientset:go_default_library",
|
||||||
"//federation/cmd/federation-apiserver/app:go_default_library",
|
"//federation/cmd/federation-apiserver/app:go_default_library",
|
||||||
"//federation/cmd/federation-apiserver/app/options:go_default_library",
|
"//federation/cmd/federation-apiserver/app/options:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes:go_default_library",
|
||||||
|
"//federation/pkg/federatedtypes/crudtester:go_default_library",
|
||||||
"//federation/pkg/federation-controller/cluster:go_default_library",
|
"//federation/pkg/federation-controller/cluster:go_default_library",
|
||||||
"//federation/pkg/federation-controller/secret:go_default_library",
|
"//federation/pkg/federation-controller/secret:go_default_library",
|
||||||
"//federation/pkg/typeadapters:go_default_library",
|
|
||||||
"//federation/pkg/typeadapters/crudtester:go_default_library",
|
|
||||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||||
"//pkg/master:go_default_library",
|
"//pkg/master:go_default_library",
|
||||||
"//test/integration/framework:go_default_library",
|
"//test/integration/framework:go_default_library",
|
||||||
|
@ -17,30 +17,28 @@ limitations under the License.
|
|||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters"
|
secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ControllerFixture defines operations for managing a federation
|
// ControllerFixture manages a federation controller for testing.
|
||||||
// controller. Tests written to this interface can then target any
|
type ControllerFixture struct {
|
||||||
// controller for which an implementation of this interface exists.
|
stopChan chan struct{}
|
||||||
type ControllerFixture interface {
|
|
||||||
TestFixture
|
|
||||||
|
|
||||||
SetUp(t *testing.T, testClient federationclientset.Interface, config *restclient.Config)
|
|
||||||
|
|
||||||
Kind() string
|
|
||||||
|
|
||||||
Adapter() typeadapters.FederatedTypeAdapter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUpControllerFixture configures the given resource fixture to target the provided api fixture
|
// NewControllerFixture initializes a new controller fixture
|
||||||
func SetUpControllerFixture(t *testing.T, apiFixture *FederationAPIFixture, controllerFixture ControllerFixture) {
|
func NewControllerFixture(t *testing.T, kind string, adapterFactory federatedtypes.AdapterFactory, config *restclient.Config) *ControllerFixture {
|
||||||
client := apiFixture.NewClient(fmt.Sprintf("test-%s", controllerFixture.Kind()))
|
f := &ControllerFixture{
|
||||||
config := apiFixture.NewConfig()
|
stopChan: make(chan struct{}),
|
||||||
controllerFixture.SetUp(t, client, config)
|
}
|
||||||
|
// TODO the generic controller doesn't belong in the secretcontroller package
|
||||||
|
secretcontroller.StartFederationSyncController(kind, adapterFactory, config, f.stopChan, true)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ControllerFixture) TearDown(t *testing.T) {
|
||||||
|
close(f.stopChan)
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters"
|
"k8s.io/kubernetes/federation/pkg/federatedtypes"
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters/crudtester"
|
"k8s.io/kubernetes/federation/pkg/federatedtypes/crudtester"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func (l *IntegrationLogger) Fatal(msg string) {
|
|||||||
l.t.Fatal(msg)
|
l.t.Fatal(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFederatedTypeCRUDTester(t *testing.T, adapter typeadapters.FederatedTypeAdapter, clusterClients []clientset.Interface) *crudtester.FederatedTypeCRUDTester {
|
func NewFederatedTypeCRUDTester(t *testing.T, adapter federatedtypes.FederatedTypeAdapter, clusterClients []clientset.Interface) *crudtester.FederatedTypeCRUDTester {
|
||||||
logger := &IntegrationLogger{t}
|
logger := &IntegrationLogger{t}
|
||||||
return crudtester.NewFederatedTypeCRUDTester(logger, adapter, clusterClients, DefaultWaitInterval, wait.ForeverTestTimeout)
|
return crudtester.NewFederatedTypeCRUDTester(logger, adapter, clusterClients, DefaultWaitInterval, wait.ForeverTestTimeout)
|
||||||
}
|
}
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
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 framework
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
restclient "k8s.io/client-go/rest"
|
|
||||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
|
||||||
secretcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/secret"
|
|
||||||
"k8s.io/kubernetes/federation/pkg/typeadapters"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SecretFixture struct {
|
|
||||||
adapter *typeadapters.SecretAdapter
|
|
||||||
stopChan chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SecretFixture) SetUp(t *testing.T, client federationclientset.Interface, config *restclient.Config) {
|
|
||||||
f.adapter = typeadapters.NewSecretAdapter(client)
|
|
||||||
f.stopChan = make(chan struct{})
|
|
||||||
secretcontroller.StartSecretController(config, f.stopChan, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SecretFixture) TearDown(t *testing.T) {
|
|
||||||
close(f.stopChan)
|
|
||||||
}
|
|
||||||
func (f *SecretFixture) Kind() string {
|
|
||||||
adapter := &typeadapters.SecretAdapter{}
|
|
||||||
return adapter.Kind()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *SecretFixture) Adapter() typeadapters.FederatedTypeAdapter {
|
|
||||||
return f.adapter
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user