mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
fed: Abstract secret controller interaction with the secret type
This change uses an adapter class to abstracts the interaction of the secret controller with the secret api type. This is the first step to creating a generic controller that can target any type for which an adapter exists.
This commit is contained in:
parent
27cf62ac29
commit
82e73efe83
@ -18,6 +18,7 @@ go_library(
|
||||
"//federation/pkg/federation-controller/util:go_default_library",
|
||||
"//federation/pkg/federation-controller/util/deletionhelper: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/v1:go_default_library",
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
|
@ -18,6 +18,7 @@ package secret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@ -36,6 +37,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/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"
|
||||
@ -72,9 +74,6 @@ type SecretController struct {
|
||||
// Informer controller for secrets that should be federated.
|
||||
secretInformerController cache.Controller
|
||||
|
||||
// Client to federated api server.
|
||||
federatedApiClient federationclientset.Interface
|
||||
|
||||
// Backoff manager for secrets
|
||||
secretBackoff *flowcontrol.Backoff
|
||||
|
||||
@ -87,6 +86,8 @@ type SecretController struct {
|
||||
clusterAvailableDelay time.Duration
|
||||
smallDelay time.Duration
|
||||
updateTimeout time.Duration
|
||||
|
||||
adapter typeadapters.FederatedTypeAdapter
|
||||
}
|
||||
|
||||
// StartSecretController starts a new secret controller
|
||||
@ -103,18 +104,20 @@ func StartSecretController(config *restclient.Config, stopChan <-chan struct{},
|
||||
|
||||
// newSecretController returns a new secret controller
|
||||
func newSecretController(client federationclientset.Interface) *SecretController {
|
||||
adapter := typeadapters.NewSecretAdapter(client)
|
||||
|
||||
broadcaster := record.NewBroadcaster()
|
||||
broadcaster.StartRecordingToSink(eventsink.NewFederatedEventSink(client))
|
||||
recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: "federated-secrets-controller"})
|
||||
recorder := broadcaster.NewRecorder(api.Scheme, clientv1.EventSource{Component: fmt.Sprintf("federated-%v-controller", adapter.Kind())})
|
||||
|
||||
secretcontroller := &SecretController{
|
||||
federatedApiClient: client,
|
||||
secretReviewDelay: time.Second * 10,
|
||||
clusterAvailableDelay: time.Second * 20,
|
||||
smallDelay: time.Second * 3,
|
||||
updateTimeout: time.Second * 30,
|
||||
secretBackoff: flowcontrol.NewBackOff(5*time.Second, time.Minute),
|
||||
eventRecorder: recorder,
|
||||
adapter: adapter,
|
||||
}
|
||||
|
||||
// Build delivereres for triggering reconciliations.
|
||||
@ -125,13 +128,13 @@ func newSecretController(client federationclientset.Interface) *SecretController
|
||||
secretcontroller.secretInformerStore, secretcontroller.secretInformerController = cache.NewInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.Core().Secrets(metav1.NamespaceAll).List(options)
|
||||
return adapter.FedList(metav1.NamespaceAll, options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.Core().Secrets(metav1.NamespaceAll).Watch(options)
|
||||
return adapter.FedWatch(metav1.NamespaceAll, options)
|
||||
},
|
||||
},
|
||||
&apiv1.Secret{},
|
||||
adapter.ObjectType(),
|
||||
controller.NoResyncPeriodFunc(),
|
||||
util.NewTriggerOnAllChanges(func(obj pkgruntime.Object) { secretcontroller.deliverSecretObj(obj, 0, false) }))
|
||||
|
||||
@ -142,13 +145,13 @@ func newSecretController(client federationclientset.Interface) *SecretController
|
||||
return cache.NewInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return targetClient.Core().Secrets(metav1.NamespaceAll).List(options)
|
||||
return adapter.ClusterList(targetClient, metav1.NamespaceAll, options)
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return targetClient.Core().Secrets(metav1.NamespaceAll).Watch(options)
|
||||
return adapter.ClusterWatch(targetClient, metav1.NamespaceAll, options)
|
||||
},
|
||||
},
|
||||
&apiv1.Secret{},
|
||||
adapter.ObjectType(),
|
||||
controller.NoResyncPeriodFunc(),
|
||||
// Trigger reconciliation whenever something in federated cluster is changed. In most cases it
|
||||
// would be just confirmation that some secret operation succeeded.
|
||||
@ -170,19 +173,17 @@ func newSecretController(client federationclientset.Interface) *SecretController
|
||||
// Federated updeater along with Create/Update/Delete operations.
|
||||
secretcontroller.federatedUpdater = util.NewFederatedUpdater(secretcontroller.secretFederatedInformer,
|
||||
func(client kubeclientset.Interface, obj pkgruntime.Object) error {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
_, err := client.Core().Secrets(secret.Namespace).Create(secret)
|
||||
_, err := adapter.ClusterCreate(client, obj)
|
||||
return err
|
||||
},
|
||||
func(client kubeclientset.Interface, obj pkgruntime.Object) error {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
_, err := client.Core().Secrets(secret.Namespace).Update(secret)
|
||||
_, err := adapter.ClusterUpdate(client, obj)
|
||||
return err
|
||||
},
|
||||
func(client kubeclientset.Interface, obj pkgruntime.Object) error {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
namespacedName := adapter.NamespacedName(obj)
|
||||
orphanDependents := false
|
||||
err := client.Core().Secrets(secret.Namespace).Delete(secret.Name, &metav1.DeleteOptions{OrphanDependents: &orphanDependents})
|
||||
err := adapter.ClusterDelete(client, namespacedName, &metav1.DeleteOptions{OrphanDependents: &orphanDependents})
|
||||
return err
|
||||
})
|
||||
|
||||
@ -192,8 +193,7 @@ func newSecretController(client federationclientset.Interface) *SecretController
|
||||
secretcontroller.addFinalizerFunc,
|
||||
// objNameFunc
|
||||
func(obj pkgruntime.Object) string {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return secret.Name
|
||||
return adapter.ObjectMeta(obj).Name
|
||||
},
|
||||
secretcontroller.updateTimeout,
|
||||
secretcontroller.eventRecorder,
|
||||
@ -214,9 +214,9 @@ func (secretcontroller *SecretController) minimizeLatency() {
|
||||
|
||||
// Returns true if the given object has the given finalizer in its ObjectMeta.
|
||||
func (secretcontroller *SecretController) hasFinalizerFunc(obj pkgruntime.Object, finalizer string) bool {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
for i := range secret.ObjectMeta.Finalizers {
|
||||
if string(secret.ObjectMeta.Finalizers[i]) == finalizer {
|
||||
meta := secretcontroller.adapter.ObjectMeta(obj)
|
||||
for i := range meta.Finalizers {
|
||||
if string(meta.Finalizers[i]) == finalizer {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -226,12 +226,13 @@ func (secretcontroller *SecretController) hasFinalizerFunc(obj pkgruntime.Object
|
||||
// Removes the finalizers from the given objects ObjectMeta.
|
||||
// Assumes that the given object is a secret.
|
||||
func (secretcontroller *SecretController) removeFinalizerFunc(obj pkgruntime.Object, finalizers []string) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
adapter := secretcontroller.adapter
|
||||
meta := adapter.ObjectMeta(obj)
|
||||
newFinalizers := []string{}
|
||||
hasFinalizer := false
|
||||
for i := range secret.ObjectMeta.Finalizers {
|
||||
if !deletionhelper.ContainsString(finalizers, secret.ObjectMeta.Finalizers[i]) {
|
||||
newFinalizers = append(newFinalizers, secret.ObjectMeta.Finalizers[i])
|
||||
for i := range meta.Finalizers {
|
||||
if !deletionhelper.ContainsString(finalizers, meta.Finalizers[i]) {
|
||||
newFinalizers = append(newFinalizers, meta.Finalizers[i])
|
||||
} else {
|
||||
hasFinalizer = true
|
||||
}
|
||||
@ -240,10 +241,10 @@ func (secretcontroller *SecretController) removeFinalizerFunc(obj pkgruntime.Obj
|
||||
// Nothing to do.
|
||||
return obj, nil
|
||||
}
|
||||
secret.ObjectMeta.Finalizers = newFinalizers
|
||||
secret, err := secretcontroller.federatedApiClient.Core().Secrets(secret.Namespace).Update(secret)
|
||||
meta.Finalizers = newFinalizers
|
||||
secret, err := secretcontroller.adapter.FedUpdate(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to remove finalizers %v from secret %s: %v", finalizers, secret.Name, err)
|
||||
return nil, fmt.Errorf("failed to remove finalizers %v from %s %s: %v", finalizers, adapter.Kind(), meta.Name, err)
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
@ -251,11 +252,12 @@ func (secretcontroller *SecretController) removeFinalizerFunc(obj pkgruntime.Obj
|
||||
// Adds the given finalizers to the given objects ObjectMeta.
|
||||
// Assumes that the given object is a secret.
|
||||
func (secretcontroller *SecretController) addFinalizerFunc(obj pkgruntime.Object, finalizers []string) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
secret.ObjectMeta.Finalizers = append(secret.ObjectMeta.Finalizers, finalizers...)
|
||||
secret, err := secretcontroller.federatedApiClient.Core().Secrets(secret.Namespace).Update(secret)
|
||||
adapter := secretcontroller.adapter
|
||||
meta := adapter.ObjectMeta(obj)
|
||||
meta.Finalizers = append(meta.Finalizers, finalizers...)
|
||||
secret, err := secretcontroller.adapter.FedUpdate(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add finalizers %v to secret %s: %v", finalizers, secret.Name, err)
|
||||
return nil, fmt.Errorf("failed to add finalizers %v to %s %s: %v", finalizers, adapter.Kind(), meta.Name, err)
|
||||
}
|
||||
return secret, nil
|
||||
}
|
||||
@ -277,9 +279,9 @@ func (secretcontroller *SecretController) Run(stopChan <-chan struct{}) {
|
||||
util.StartBackoffGC(secretcontroller.secretBackoff, stopChan)
|
||||
}
|
||||
|
||||
func (secretcontroller *SecretController) deliverSecretObj(obj interface{}, delay time.Duration, failed bool) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
secretcontroller.deliverSecret(types.NamespacedName{Namespace: secret.Namespace, Name: secret.Name}, delay, failed)
|
||||
func (secretcontroller *SecretController) deliverSecretObj(obj pkgruntime.Object, delay time.Duration, failed bool) {
|
||||
namespacedName := secretcontroller.adapter.NamespacedName(obj)
|
||||
secretcontroller.deliverSecret(namespacedName, delay, failed)
|
||||
}
|
||||
|
||||
// Adds backoff to delay if this delivery is related to some failure. Resets backoff if there was no failure.
|
||||
@ -318,12 +320,15 @@ func (secretcontroller *SecretController) reconcileSecretsOnClusterChange() {
|
||||
secretcontroller.clusterDeliverer.DeliverAt(allClustersKey, nil, time.Now().Add(secretcontroller.clusterAvailableDelay))
|
||||
}
|
||||
for _, obj := range secretcontroller.secretInformerStore.List() {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
secretcontroller.deliverSecret(types.NamespacedName{Namespace: secret.Namespace, Name: secret.Name}, secretcontroller.smallDelay, false)
|
||||
namespacedName := secretcontroller.adapter.NamespacedName(obj.(pkgruntime.Object))
|
||||
secretcontroller.deliverSecret(namespacedName, secretcontroller.smallDelay, false)
|
||||
}
|
||||
}
|
||||
|
||||
func (secretcontroller *SecretController) reconcileSecret(secret types.NamespacedName) {
|
||||
adapter := secretcontroller.adapter
|
||||
kind := adapter.Kind()
|
||||
|
||||
if !secretcontroller.isSynced() {
|
||||
secretcontroller.deliverSecret(secret, secretcontroller.clusterAvailableDelay, false)
|
||||
return
|
||||
@ -332,7 +337,7 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
key := secret.String()
|
||||
baseSecretObjFromStore, exist, err := secretcontroller.secretInformerStore.GetByKey(key)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to query main secret store for %v: %v", key, err)
|
||||
glog.Errorf("Failed to query main %s store for %v: %v", kind, key, err)
|
||||
secretcontroller.deliverSecret(secret, 0, true)
|
||||
return
|
||||
}
|
||||
@ -345,35 +350,42 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
// Create a copy before modifying the obj to prevent race condition with
|
||||
// other readers of obj from store.
|
||||
baseSecretObj, err := api.Scheme.DeepCopy(baseSecretObjFromStore)
|
||||
baseSecret, ok := baseSecretObj.(*apiv1.Secret)
|
||||
if err != nil || !ok {
|
||||
glog.Errorf("Error in retrieving obj from store: %v, %v", ok, err)
|
||||
if err != nil {
|
||||
glog.Errorf("Error in retrieving obj from store: %v", err)
|
||||
secretcontroller.deliverSecret(secret, 0, true)
|
||||
return
|
||||
}
|
||||
if baseSecret.DeletionTimestamp != nil {
|
||||
if err := secretcontroller.delete(baseSecret); err != nil {
|
||||
glog.Errorf("Failed to delete %s: %v", secret, err)
|
||||
if !adapter.IsExpectedType(baseSecretObj) {
|
||||
glog.Errorf("Object is not the expected type: %v", baseSecretObj)
|
||||
secretcontroller.deliverSecret(secret, 0, true)
|
||||
return
|
||||
}
|
||||
|
||||
baseSecret := baseSecretObj.(pkgruntime.Object)
|
||||
meta := adapter.ObjectMeta(baseSecret)
|
||||
|
||||
if meta.DeletionTimestamp != nil {
|
||||
if err := secretcontroller.delete(baseSecret, secret); err != nil {
|
||||
glog.Errorf("Failed to delete %s %s: %v", kind, secret, err)
|
||||
secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "DeleteFailed",
|
||||
"Secret delete failed: %v", err)
|
||||
"%s delete failed: %v", strings.ToTitle(kind), err)
|
||||
secretcontroller.deliverSecret(secret, 0, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
glog.V(3).Infof("Ensuring delete object from underlying clusters finalizer for secret: %s",
|
||||
baseSecret.Name)
|
||||
glog.V(3).Infof("Ensuring delete object from underlying clusters finalizer for %s: %s",
|
||||
kind, secret)
|
||||
// Add the required finalizers before creating a secret in underlying clusters.
|
||||
updatedSecretObj, err := secretcontroller.deletionHelper.EnsureFinalizers(baseSecret)
|
||||
baseSecret, err = secretcontroller.deletionHelper.EnsureFinalizers(baseSecret)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to ensure delete object from underlying clusters finalizer in secret %s: %v",
|
||||
baseSecret.Name, err)
|
||||
glog.Errorf("Failed to ensure delete object from underlying clusters finalizer in %s %s: %v",
|
||||
kind, secret, err)
|
||||
secretcontroller.deliverSecret(secret, 0, false)
|
||||
return
|
||||
}
|
||||
baseSecret = updatedSecretObj.(*apiv1.Secret)
|
||||
|
||||
glog.V(3).Infof("Syncing secret %s in underlying clusters", baseSecret.Name)
|
||||
glog.V(3).Infof("Syncing %s %s in underlying clusters", kind, secret)
|
||||
|
||||
clusters, err := secretcontroller.secretFederatedInformer.GetReadyClusters()
|
||||
if err != nil {
|
||||
@ -392,15 +404,11 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
}
|
||||
|
||||
// The data should not be modified.
|
||||
desiredSecret := &apiv1.Secret{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(baseSecret.ObjectMeta),
|
||||
Data: baseSecret.Data,
|
||||
Type: baseSecret.Type,
|
||||
}
|
||||
desiredSecret := adapter.Copy(baseSecret)
|
||||
|
||||
if !found {
|
||||
secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "CreateInCluster",
|
||||
"Creating secret in cluster %s", cluster.Name)
|
||||
"Creating %s in cluster %s", kind, cluster.Name)
|
||||
|
||||
operations = append(operations, util.FederatedOperation{
|
||||
Type: util.OperationTypeAdd,
|
||||
@ -408,13 +416,12 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
ClusterName: cluster.Name,
|
||||
})
|
||||
} else {
|
||||
clusterSecret := clusterSecretObj.(*apiv1.Secret)
|
||||
clusterSecret := clusterSecretObj.(pkgruntime.Object)
|
||||
|
||||
// Update existing secret, if needed.
|
||||
if !util.SecretEquivalent(*desiredSecret, *clusterSecret) {
|
||||
|
||||
if !adapter.Equivalent(desiredSecret, clusterSecret) {
|
||||
secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInCluster",
|
||||
"Updating secret in cluster %s", cluster.Name)
|
||||
"Updating %s in cluster %s", kind, cluster.Name)
|
||||
operations = append(operations, util.FederatedOperation{
|
||||
Type: util.OperationTypeUpdate,
|
||||
Obj: desiredSecret,
|
||||
@ -431,7 +438,7 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
err = secretcontroller.federatedUpdater.UpdateWithOnError(operations, secretcontroller.updateTimeout,
|
||||
func(op util.FederatedOperation, operror error) {
|
||||
secretcontroller.eventRecorder.Eventf(baseSecret, api.EventTypeNormal, "UpdateInClusterFailed",
|
||||
"Secret update in cluster %s failed: %v", op.ClusterName, operror)
|
||||
"%s update in cluster %s failed: %v", strings.ToTitle(kind), op.ClusterName, operror)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@ -445,20 +452,21 @@ func (secretcontroller *SecretController) reconcileSecret(secret types.Namespace
|
||||
}
|
||||
|
||||
// delete deletes the given secret or returns error if the deletion was not complete.
|
||||
func (secretcontroller *SecretController) delete(secret *apiv1.Secret) error {
|
||||
glog.V(3).Infof("Handling deletion of secret: %v", *secret)
|
||||
_, err := secretcontroller.deletionHelper.HandleObjectInUnderlyingClusters(secret)
|
||||
func (secretcontroller *SecretController) delete(obj pkgruntime.Object, namespacedName types.NamespacedName) error {
|
||||
kind := secretcontroller.adapter.Kind()
|
||||
glog.V(3).Infof("Handling deletion of %s: %v", kind, namespacedName)
|
||||
_, err := secretcontroller.deletionHelper.HandleObjectInUnderlyingClusters(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = secretcontroller.federatedApiClient.Core().Secrets(secret.Namespace).Delete(secret.Name, nil)
|
||||
err = secretcontroller.adapter.FedDelete(namespacedName, nil)
|
||||
if err != nil {
|
||||
// Its all good if the error is not found error. That means it is deleted already and we do not have to do anything.
|
||||
// This is expected when we are processing an update as a result of secret finalizer deletion.
|
||||
// The process that deleted the last finalizer is also going to delete the secret and we do not have to do anything.
|
||||
if !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to delete secret: %v", err)
|
||||
return fmt.Errorf("failed to delete %s: %v", kind, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -22,6 +22,7 @@ go_library(
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"//vendor:k8s.io/apimachinery/pkg/runtime",
|
||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||
"//vendor:k8s.io/apimachinery/pkg/watch",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -20,8 +20,9 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
)
|
||||
|
||||
// FederatedTypeAdapter defines operations for interacting with a
|
||||
@ -31,18 +32,28 @@ type FederatedTypeAdapter interface {
|
||||
SetClient(client federationclientset.Interface)
|
||||
|
||||
Kind() string
|
||||
ObjectType() pkgruntime.Object
|
||||
IsExpectedType(obj interface{}) bool
|
||||
Copy(obj pkgruntime.Object) pkgruntime.Object
|
||||
Equivalent(obj1, obj2 pkgruntime.Object) bool
|
||||
ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta
|
||||
NamespacedName(obj pkgruntime.Object) types.NamespacedName
|
||||
ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta
|
||||
|
||||
// Fed* operations target the federation control plane
|
||||
FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
FedGet(namespacedName types.NamespacedName) (pkgruntime.Object, error)
|
||||
FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
FedDelete(namespacedName types.NamespacedName, options *metav1.DeleteOptions) error
|
||||
FedGet(namespacedName types.NamespacedName) (pkgruntime.Object, error)
|
||||
FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error)
|
||||
FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error)
|
||||
|
||||
// The following operations are intended to target a cluster that is a member of a federation
|
||||
ClusterGet(client clientset.Interface, namespacedName types.NamespacedName) (pkgruntime.Object, error)
|
||||
ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
ClusterDelete(client kubeclientset.Interface, nsName types.NamespacedName, options *metav1.DeleteOptions) error
|
||||
ClusterGet(client kubeclientset.Interface, namespacedName types.NamespacedName) (pkgruntime.Object, error)
|
||||
ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error)
|
||||
ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error)
|
||||
ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error)
|
||||
|
||||
NewTestObject(namespace string) pkgruntime.Object
|
||||
}
|
||||
|
@ -20,10 +20,11 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
pkgruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
|
||||
"k8s.io/kubernetes/federation/pkg/federation-controller/util"
|
||||
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
kubeclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
)
|
||||
|
||||
type SecretAdapter struct {
|
||||
@ -42,43 +43,91 @@ func (a *SecretAdapter) Kind() string {
|
||||
return "secret"
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ObjectType() pkgruntime.Object {
|
||||
return &apiv1.Secret{}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) IsExpectedType(obj interface{}) bool {
|
||||
_, ok := obj.(*apiv1.Secret)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) Copy(obj pkgruntime.Object) pkgruntime.Object {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return &apiv1.Secret{
|
||||
ObjectMeta: util.DeepCopyRelevantObjectMeta(secret.ObjectMeta),
|
||||
Data: secret.Data,
|
||||
Type: secret.Type,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) Equivalent(obj1, obj2 pkgruntime.Object) bool {
|
||||
secret1 := obj1.(*apiv1.Secret)
|
||||
secret2 := obj2.(*apiv1.Secret)
|
||||
return util.SecretEquivalent(*secret1, *secret2)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*apiv1.Secret).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) NamespacedName(obj pkgruntime.Object) types.NamespacedName {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return types.NamespacedName{Namespace: secret.Namespace, Name: secret.Name}
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ObjectMeta(obj pkgruntime.Object) *metav1.ObjectMeta {
|
||||
return &obj.(*apiv1.Secret).ObjectMeta
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedCreate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return a.client.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedDelete(namespacedName types.NamespacedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.CoreV1().Secrets(namespacedName.Namespace).Delete(namespacedName.Name, options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedGet(namespacedName types.NamespacedName) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Secrets(namespacedName.Namespace).Get(namespacedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedList(namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return a.client.CoreV1().Secrets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedUpdate(obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return a.client.CoreV1().Secrets(secret.Namespace).Update(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) FedDelete(namespacedName types.NamespacedName, options *metav1.DeleteOptions) error {
|
||||
return a.client.CoreV1().Secrets(namespacedName.Namespace).Delete(namespacedName.Name, options)
|
||||
func (a *SecretAdapter) FedWatch(namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return a.client.CoreV1().Secrets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterGet(client clientset.Interface, namespacedName types.NamespacedName) (pkgruntime.Object, error) {
|
||||
func (a *SecretAdapter) ClusterCreate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return client.CoreV1().Secrets(secret.Namespace).Create(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterDelete(client kubeclientset.Interface, nsName types.NamespacedName, options *metav1.DeleteOptions) error {
|
||||
return client.CoreV1().Secrets(nsName.Namespace).Delete(nsName.Name, options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterGet(client kubeclientset.Interface, namespacedName types.NamespacedName) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Secrets(namespacedName.Namespace).Get(namespacedName.Name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterList(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (pkgruntime.Object, error) {
|
||||
return client.CoreV1().Secrets(namespace).List(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterUpdate(client kubeclientset.Interface, obj pkgruntime.Object) (pkgruntime.Object, error) {
|
||||
secret := obj.(*apiv1.Secret)
|
||||
return client.CoreV1().Secrets(secret.Namespace).Update(secret)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) ClusterWatch(client kubeclientset.Interface, namespace string, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return client.CoreV1().Secrets(namespace).Watch(options)
|
||||
}
|
||||
|
||||
func (a *SecretAdapter) NewTestObject(namespace string) pkgruntime.Object {
|
||||
return &apiv1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
Loading…
Reference in New Issue
Block a user