Procházet zdrojové kódy

Merge branch 'beach-team' of https://github.com/external-secrets/external-secrets into beach-team

Lilly Daniell před 4 roky
rodič
revize
2c0382c74a

+ 1 - 0
go.mod

@@ -218,6 +218,7 @@ require (
 	github.com/mattn/go-colorable v0.1.12 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+	github.com/maxbrunsfeld/counterfeiter/v6 v6.5.0 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
 	github.com/mitchellh/go-testing-interface v1.14.1 // indirect

+ 171 - 8
pkg/controllers/pushsecret/internal/fakes/recorder.go

@@ -1,16 +1,179 @@
+// Code generated by counterfeiter. DO NOT EDIT.
 package fakes
 
-import "k8s.io/apimachinery/pkg/runtime"
+import (
+	"sync"
 
-type FakeRecorder struct {
-	EventCallCounter int
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/tools/record"
+)
+
+type FakeEventRecorder struct {
+	AnnotatedEventfStub        func(runtime.Object, map[string]string, string, string, string, ...interface{})
+	annotatedEventfMutex       sync.RWMutex
+	annotatedEventfArgsForCall []struct {
+		arg1 runtime.Object
+		arg2 map[string]string
+		arg3 string
+		arg4 string
+		arg5 string
+		arg6 []interface{}
+	}
+	EventStub        func(runtime.Object, string, string, string)
+	eventMutex       sync.RWMutex
+	eventArgsForCall []struct {
+		arg1 runtime.Object
+		arg2 string
+		arg3 string
+		arg4 string
+	}
+	EventfStub        func(runtime.Object, string, string, string, ...interface{})
+	eventfMutex       sync.RWMutex
+	eventfArgsForCall []struct {
+		arg1 runtime.Object
+		arg2 string
+		arg3 string
+		arg4 string
+		arg5 []interface{}
+	}
+	invocations      map[string][][]interface{}
+	invocationsMutex sync.RWMutex
+}
+
+func (fake *FakeEventRecorder) AnnotatedEventf(arg1 runtime.Object, arg2 map[string]string, arg3 string, arg4 string, arg5 string, arg6 ...interface{}) {
+	fake.annotatedEventfMutex.Lock()
+	fake.annotatedEventfArgsForCall = append(fake.annotatedEventfArgsForCall, struct {
+		arg1 runtime.Object
+		arg2 map[string]string
+		arg3 string
+		arg4 string
+		arg5 string
+		arg6 []interface{}
+	}{arg1, arg2, arg3, arg4, arg5, arg6})
+	stub := fake.AnnotatedEventfStub
+	fake.recordInvocation("AnnotatedEventf", []interface{}{arg1, arg2, arg3, arg4, arg5, arg6})
+	fake.annotatedEventfMutex.Unlock()
+	if stub != nil {
+		fake.AnnotatedEventfStub(arg1, arg2, arg3, arg4, arg5, arg6...)
+	}
+}
+
+func (fake *FakeEventRecorder) AnnotatedEventfCallCount() int {
+	fake.annotatedEventfMutex.RLock()
+	defer fake.annotatedEventfMutex.RUnlock()
+	return len(fake.annotatedEventfArgsForCall)
+}
+
+func (fake *FakeEventRecorder) AnnotatedEventfCalls(stub func(runtime.Object, map[string]string, string, string, string, ...interface{})) {
+	fake.annotatedEventfMutex.Lock()
+	defer fake.annotatedEventfMutex.Unlock()
+	fake.AnnotatedEventfStub = stub
+}
+
+func (fake *FakeEventRecorder) AnnotatedEventfArgsForCall(i int) (runtime.Object, map[string]string, string, string, string, []interface{}) {
+	fake.annotatedEventfMutex.RLock()
+	defer fake.annotatedEventfMutex.RUnlock()
+	argsForCall := fake.annotatedEventfArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5, argsForCall.arg6
+}
+
+func (fake *FakeEventRecorder) Event(arg1 runtime.Object, arg2 string, arg3 string, arg4 string) {
+	fake.eventMutex.Lock()
+	fake.eventArgsForCall = append(fake.eventArgsForCall, struct {
+		arg1 runtime.Object
+		arg2 string
+		arg3 string
+		arg4 string
+	}{arg1, arg2, arg3, arg4})
+	stub := fake.EventStub
+	fake.recordInvocation("Event", []interface{}{arg1, arg2, arg3, arg4})
+	fake.eventMutex.Unlock()
+	if stub != nil {
+		fake.EventStub(arg1, arg2, arg3, arg4)
+	}
+}
+
+func (fake *FakeEventRecorder) EventCallCount() int {
+	fake.eventMutex.RLock()
+	defer fake.eventMutex.RUnlock()
+	return len(fake.eventArgsForCall)
 }
 
-func (r *FakeRecorder) Event(object runtime.Object, eventtype string, reason string, message string) {
-	r.EventCallCounter += 1
+func (fake *FakeEventRecorder) EventCalls(stub func(runtime.Object, string, string, string)) {
+	fake.eventMutex.Lock()
+	defer fake.eventMutex.Unlock()
+	fake.EventStub = stub
 }
-func (r FakeRecorder) EventCallCount() int { return r.EventCallCounter }
-func (r FakeRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
+
+func (fake *FakeEventRecorder) EventArgsForCall(i int) (runtime.Object, string, string, string) {
+	fake.eventMutex.RLock()
+	defer fake.eventMutex.RUnlock()
+	argsForCall := fake.eventArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4
+}
+
+func (fake *FakeEventRecorder) Eventf(arg1 runtime.Object, arg2 string, arg3 string, arg4 string, arg5 ...interface{}) {
+	fake.eventfMutex.Lock()
+	fake.eventfArgsForCall = append(fake.eventfArgsForCall, struct {
+		arg1 runtime.Object
+		arg2 string
+		arg3 string
+		arg4 string
+		arg5 []interface{}
+	}{arg1, arg2, arg3, arg4, arg5})
+	stub := fake.EventfStub
+	fake.recordInvocation("Eventf", []interface{}{arg1, arg2, arg3, arg4, arg5})
+	fake.eventfMutex.Unlock()
+	if stub != nil {
+		fake.EventfStub(arg1, arg2, arg3, arg4, arg5...)
+	}
 }
-func (r FakeRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) {
+
+func (fake *FakeEventRecorder) EventfCallCount() int {
+	fake.eventfMutex.RLock()
+	defer fake.eventfMutex.RUnlock()
+	return len(fake.eventfArgsForCall)
 }
+
+func (fake *FakeEventRecorder) EventfCalls(stub func(runtime.Object, string, string, string, ...interface{})) {
+	fake.eventfMutex.Lock()
+	defer fake.eventfMutex.Unlock()
+	fake.EventfStub = stub
+}
+
+func (fake *FakeEventRecorder) EventfArgsForCall(i int) (runtime.Object, string, string, string, []interface{}) {
+	fake.eventfMutex.RLock()
+	defer fake.eventfMutex.RUnlock()
+	argsForCall := fake.eventfArgsForCall[i]
+	return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5
+}
+
+func (fake *FakeEventRecorder) Invocations() map[string][][]interface{} {
+	fake.invocationsMutex.RLock()
+	defer fake.invocationsMutex.RUnlock()
+	fake.annotatedEventfMutex.RLock()
+	defer fake.annotatedEventfMutex.RUnlock()
+	fake.eventMutex.RLock()
+	defer fake.eventMutex.RUnlock()
+	fake.eventfMutex.RLock()
+	defer fake.eventfMutex.RUnlock()
+	copiedInvocations := map[string][][]interface{}{}
+	for key, value := range fake.invocations {
+		copiedInvocations[key] = value
+	}
+	return copiedInvocations
+}
+
+func (fake *FakeEventRecorder) recordInvocation(key string, args []interface{}) {
+	fake.invocationsMutex.Lock()
+	defer fake.invocationsMutex.Unlock()
+	if fake.invocations == nil {
+		fake.invocations = map[string][][]interface{}{}
+	}
+	if fake.invocations[key] == nil {
+		fake.invocations[key] = [][]interface{}{}
+	}
+	fake.invocations[key] = append(fake.invocations[key], args)
+}
+
+var _ record.EventRecorder = new(FakeEventRecorder)

+ 23 - 23
pkg/controllers/pushsecret/pushsecret_controller.go

@@ -56,8 +56,8 @@ type Reconciler struct {
 
 func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
 	log := r.Log.WithValues("pushsecret", req.NamespacedName)
-	var ss esapi.PushSecret
-	err := r.Get(ctx, req.NamespacedName, &ss)
+	var ps esapi.PushSecret
+	err := r.Get(ctx, req.NamespacedName, &ps)
 	if apierrors.IsNotFound(err) {
 		return ctrl.Result{}, nil
 	} else if err != nil {
@@ -65,50 +65,50 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
 		return ctrl.Result{}, fmt.Errorf("get resource: %w", err)
 	}
 
-	p := client.MergeFrom(ss.DeepCopy())
+	p := client.MergeFrom(ps.DeepCopy())
 	defer func() {
-		err := r.Client.Status().Patch(ctx, &ss, p)
+		err := r.Client.Status().Patch(ctx, &ps, p)
 		if err != nil {
 			log.Error(err, errPatchStatus)
 		}
 	}()
-	secret, err := r.GetSecret(ctx, ss)
+	secret, err := r.GetSecret(ctx, ps)
 	if err != nil {
 		cond := NewPushSecretCondition(esapi.PushSecretReady, v1.ConditionFalse, esapi.ReasonErrored, errFailedGetSecret)
-		ss = SetPushSecretCondition(ss, *cond)
-		r.recorder.Event(&ss, v1.EventTypeWarning, esapi.ReasonErrored, errFailedGetSecret)
+		ps = SetPushSecretCondition(ps, *cond)
+		r.recorder.Event(&ps, v1.EventTypeWarning, esapi.ReasonErrored, errFailedGetSecret)
 		return ctrl.Result{}, err
 	}
-	secretStores, err := r.GetSecretStores(ctx, ss)
+	secretStores, err := r.GetSecretStores(ctx, ps)
 	if err != nil {
 		cond := NewPushSecretCondition(esapi.PushSecretReady, v1.ConditionFalse, esapi.ReasonErrored, err.Error())
-		ss = SetPushSecretCondition(ss, *cond)
-		r.recorder.Event(&ss, v1.EventTypeWarning, esapi.ReasonErrored, err.Error())
+		ps = SetPushSecretCondition(ps, *cond)
+		r.recorder.Event(&ps, v1.EventTypeWarning, esapi.ReasonErrored, err.Error())
 		return ctrl.Result{}, err
 	}
-	err = r.SetSecretToProviders(ctx, secretStores, ss, secret)
+	err = r.SetSecretToProviders(ctx, secretStores, ps, secret)
 	if err != nil {
 		msg := fmt.Sprintf(errFailedSetSecret, err)
 		cond := NewPushSecretCondition(esapi.PushSecretReady, v1.ConditionFalse, esapi.ReasonErrored, msg)
-		ss = SetPushSecretCondition(ss, *cond)
-		r.recorder.Event(&ss, v1.EventTypeWarning, esapi.ReasonErrored, msg)
+		ps = SetPushSecretCondition(ps, *cond)
+		r.recorder.Event(&ps, v1.EventTypeWarning, esapi.ReasonErrored, msg)
 		return ctrl.Result{}, err
 	}
 	msg := "PushSecret synced successfully"
 	cond := NewPushSecretCondition(esapi.PushSecretReady, v1.ConditionTrue, esapi.ReasonSynced, msg)
-	ss = SetPushSecretCondition(ss, *cond)
+	ps = SetPushSecretCondition(ps, *cond)
 	// Set status for PushSecret
-	r.recorder.Event(&ss, v1.EventTypeNormal, esapi.ReasonSynced, msg)
+	r.recorder.Event(&ps, v1.EventTypeNormal, esapi.ReasonSynced, msg)
 	return ctrl.Result{}, nil
 }
 
-func (r *Reconciler) SetSecretToProviders(ctx context.Context, stores []v1beta1.GenericStore, ss esapi.PushSecret, secret *v1.Secret) error {
+func (r *Reconciler) SetSecretToProviders(ctx context.Context, stores []v1beta1.GenericStore, ps esapi.PushSecret, secret *v1.Secret) error {
 	for _, store := range stores {
 		provider, err := v1beta1.GetProvider(store)
 		if err != nil {
 			return fmt.Errorf(errGetProviderFailed)
 		}
-		client, err := provider.NewClient(ctx, store, r.Client, ss.Namespace)
+		client, err := provider.NewClient(ctx, store, r.Client, ps.Namespace)
 		if err != nil {
 			return fmt.Errorf(errGetSecretsClientFailed)
 		}
@@ -118,7 +118,7 @@ func (r *Reconciler) SetSecretToProviders(ctx context.Context, stores []v1beta1.
 				r.Log.Error(err, errCloseStoreClient)
 			}
 		}()
-		for _, ref := range ss.Spec.Data {
+		for _, ref := range ps.Spec.Data {
 			for _, match := range ref.Match {
 				secretValue, ok := secret.Data[match.SecretKey]
 				if !ok {
@@ -136,8 +136,8 @@ func (r *Reconciler) SetSecretToProviders(ctx context.Context, stores []v1beta1.
 	return nil
 }
 
-func (r *Reconciler) GetSecret(ctx context.Context, ss esapi.PushSecret) (*v1.Secret, error) {
-	secretName := types.NamespacedName{Name: ss.Spec.Selector.Secret.Name, Namespace: ss.Namespace}
+func (r *Reconciler) GetSecret(ctx context.Context, ps esapi.PushSecret) (*v1.Secret, error) {
+	secretName := types.NamespacedName{Name: ps.Spec.Selector.Secret.Name, Namespace: ps.Namespace}
 	secret := &v1.Secret{}
 	err := r.Client.Get(ctx, secretName, secret)
 	if err != nil {
@@ -146,9 +146,9 @@ func (r *Reconciler) GetSecret(ctx context.Context, ss esapi.PushSecret) (*v1.Se
 	return secret, nil
 }
 
-func (r *Reconciler) GetSecretStores(ctx context.Context, ss esapi.PushSecret) ([]v1beta1.GenericStore, error) {
+func (r *Reconciler) GetSecretStores(ctx context.Context, ps esapi.PushSecret) ([]v1beta1.GenericStore, error) {
 	stores := make([]v1beta1.GenericStore, 0)
-	for _, refStore := range ss.Spec.SecretStoreRefs {
+	for _, refStore := range ps.Spec.SecretStoreRefs {
 		ref := types.NamespacedName{
 			Name: refStore.Name,
 		}
@@ -161,7 +161,7 @@ func (r *Reconciler) GetSecretStores(ctx context.Context, ss esapi.PushSecret) (
 			}
 			stores = append(stores, &store)
 		} else {
-			ref.Namespace = ss.Namespace
+			ref.Namespace = ps.Namespace
 
 			var store v1beta1.SecretStore
 			err := r.Get(ctx, ref, &store)

+ 78 - 47
pkg/controllers/pushsecret/pushsecret_controller_test.go

@@ -39,11 +39,11 @@ var _ = Describe("pushsecret", func() {
 	var (
 		reconciler *Reconciler
 		client     *fakes.Client
-		recorder   *fakes.FakeRecorder
+		recorder   *fakes.FakeEventRecorder
 	)
 	BeforeEach(func() {
 		client = new(fakes.Client)
-		recorder = &fakes.FakeRecorder{}
+		recorder = &fakes.FakeEventRecorder{}
 		reconciler = &Reconciler{client, logr.Discard(), nil, recorder, 0, ""}
 	})
 	Describe("#Reconcile", func() {
@@ -70,6 +70,9 @@ var _ = Describe("pushsecret", func() {
 			_, _, patch, _ := statusWriter.PatchArgsForCall(0)
 			Expect(patch.Type()).To(Equal(types.MergePatchType))
 			Expect(recorder.EventCallCount()).To(Equal(1))
+			_, _, reason, message := recorder.EventArgsForCall(0)
+			Expect(reason).To(Equal(esapi.ReasonSynced))
+			Expect(message).To(Equal("PushSecret synced successfully"))
 		})
 
 		When("an error returns in get", func() {
@@ -86,51 +89,79 @@ var _ = Describe("pushsecret", func() {
 				Expect(client.StatusCallCount()).To(Equal(0))
 			})
 		})
-		// When("an error returns in get secret", func() {
-		// 	BeforeEach(func() {
-		// 		// TODO: get r.GetSecret to return error "GetSecretError"
-
-		// 	})
-
-		// 	It("returns the error", func() {
-		// 		namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
-		// 		_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
-
-		// 		Expect(err).To(MatchError("GetSecretError"))
-		// 		// Expect(client.GetCallCount()).To(Equal(1))
-		// 		// Expect(client.StatusCallCount()).To(Equal(0))
-		// 	})
-		// })
-
-		// When("an error returns in get secret stores", func() {
-		// 	BeforeEach(func() {
-		// 		// TODO: get r.GetSecretStores to return error "GetSecretStoresError"
-		// 	})
-
-		// 	It("returns the error", func() {
-		// 		namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
-		// 		_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
-
-		// 		Expect(err).To(MatchError("GetSecretStoresError"))
-		// 		// Expect(client.GetCallCount()).To(Equal(1))
-		// 		// Expect(client.StatusCallCount()).To(Equal(0))
-		// 	})
-		// })
-
-		// When("an error returns in set secret to providers", func() {
-		// 	BeforeEach(func() {
-		// 		// TODO: get r.SetSecretToProviders to return error "SetSecretToProviders"
-		// 	})
-
-		// 	It("returns the error", func() {
-		// 		namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
-		// 		_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
-
-		// 		Expect(err).To(MatchError("SetSecretToProviders"))
-		// 		// Expect(client.GetCallCount()).To(Equal(1))
-		// 		// Expect(client.StatusCallCount()).To(Equal(0))
-		// 	})
-		// })
+		When("an error returns in get secret", func() {
+			BeforeEach(func() {
+				client.GetStub = func(context context.Context, name types.NamespacedName, obj kubeclient.Object) error {
+					switch obj.(type) {
+					case *v1.Secret:
+						return fmt.Errorf("GetSecretError")
+					default:
+						return nil
+					}
+				}
+			})
+
+			It("returns the error", func() {
+				namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
+				_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
+
+				Expect(err).To(MatchError("GetSecretError"))
+			})
+		})
+
+		When("an error returns in get secret store", func() {
+			BeforeEach(func() {
+				client.GetStub = func(context context.Context, name types.NamespacedName, obj kubeclient.Object) error {
+					switch v := obj.(type) {
+					case *esapi.PushSecret:
+						v.Spec.SecretStoreRefs = []esapi.PushSecretStoreRef{
+							{Name: "a", Kind: "secretstore"},
+						}
+					}
+					switch obj.(type) {
+					case *v1beta1.SecretStore:
+						return fmt.Errorf("BORK")
+					default:
+						return nil
+					}
+
+				}
+			})
+
+			It("returns the error", func() {
+				namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
+				_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
+
+				Expect(err).To(MatchError("could not get SecretStore \"a\", BORK"))
+			})
+		})
+
+		When("an error returns in set secret to providers", func() {
+			BeforeEach(func() {
+				client.GetStub = func(context context.Context, name types.NamespacedName, obj kubeclient.Object) error {
+					switch v := obj.(type) {
+					case *esapi.PushSecret:
+						v.Spec.SecretStoreRefs = []esapi.PushSecretStoreRef{
+							{Name: "a", Kind: "secretstore"},
+						}
+					case *v1beta1.SecretStore:
+						v.Kind = "PotatoStore"
+					}
+					switch obj.(type) {
+					default:
+						return nil
+					}
+
+				}
+			})
+
+			It("returns the error", func() {
+				namspacedName := types.NamespacedName{Namespace: "foo", Name: "Bar"}
+				_, err := reconciler.Reconcile(context.Background(), ctrl.Request{NamespacedName: namspacedName})
+
+				Expect(err).To(MatchError("could not start provider"))
+			})
+		})
 
 		When("an object is not found", func() {
 			BeforeEach(func() {