diff --git a/federation/pkg/federation-controller/secret/BUILD b/federation/pkg/federation-controller/secret/BUILD index 3ad927bed97..a2ce2020f27 100644 --- a/federation/pkg/federation-controller/secret/BUILD +++ b/federation/pkg/federation-controller/secret/BUILD @@ -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", diff --git a/federation/pkg/federation-controller/secret/secret_controller.go b/federation/pkg/federation-controller/secret/secret_controller.go index c054e7c6157..2119995a001 100644 --- a/federation/pkg/federation-controller/secret/secret_controller.go +++ b/federation/pkg/federation-controller/secret/secret_controller.go @@ -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 diff --git a/federation/pkg/typeadapters/BUILD b/federation/pkg/typeadapters/BUILD index e2acb8be78b..05f4234a95d 100644 --- a/federation/pkg/typeadapters/BUILD +++ b/federation/pkg/typeadapters/BUILD @@ -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", ], ) diff --git a/federation/pkg/typeadapters/adapter.go b/federation/pkg/typeadapters/adapter.go index 62bc2d86825..b5799666a6c 100644 --- a/federation/pkg/typeadapters/adapter.go +++ b/federation/pkg/typeadapters/adapter.go @@ -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 } diff --git a/federation/pkg/typeadapters/secret.go b/federation/pkg/typeadapters/secret.go index c7e2018f0ff..aae439c611e 100644 --- a/federation/pkg/typeadapters/secret.go +++ b/federation/pkg/typeadapters/secret.go @@ -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{