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:
Maru Newby 2017-02-05 20:28:20 -08:00
parent 27cf62ac29
commit 82e73efe83
5 changed files with 152 additions and 82 deletions

View File

@ -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",

View File

@ -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

View File

@ -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",
],
)

View File

@ -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
}

View File

@ -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{