Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete IAS Application if SKR cluster is not f ound #35

Merged
merged 3 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions controllers/eventingauth_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ package controllers
import (
"context"
"fmt"
"os"
"reflect"

operatorv1alpha1 "github.com/kyma-project/eventing-auth-manager/api/v1alpha1"
"github.com/kyma-project/eventing-auth-manager/internal/ias"
"github.com/kyma-project/eventing-auth-manager/internal/skr"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"os"
"reflect"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Expand Down Expand Up @@ -71,12 +72,6 @@ func (r *eventingAuthReconciler) Reconcile(ctx context.Context, req ctrl.Request
return ctrl.Result{}, client.IgnoreNotFound(err)
}

skrClient, err := skr.NewClient(r.Client, cr.Name)
if err != nil {
logger.Error(err, "Failed to retrieve client of target cluster")
return ctrl.Result{}, err
}

// sync IAS client credentials
r.iasClient, err = r.getIasClient()
if err != nil {
Expand All @@ -89,13 +84,19 @@ func (r *eventingAuthReconciler) Reconcile(ctx context.Context, req ctrl.Request
}
} else {
logger.Info("Handling deletion")
if err = r.handleDeletion(ctx, r.iasClient, skrClient, &cr); err != nil {
if err = r.handleDeletion(ctx, r.iasClient, &cr); err != nil {
return ctrl.Result{}, err
}
// Stop reconciliation as the item is being deleted
return ctrl.Result{}, nil
}

skrClient, err := skr.NewClient(r.Client, cr.Name)
if err != nil {
logger.Error(err, "Failed to retrieve client of target cluster")
return ctrl.Result{}, err
}

appSecretExists, err := skrClient.HasApplicationSecret(ctx)
if err != nil {
logger.Error(err, "Failed to retrieve secret state from target cluster")
Expand Down Expand Up @@ -197,22 +198,22 @@ func (r *eventingAuthReconciler) addFinalizer(ctx context.Context, cr *operatorv
}

// Deletes the secret and IAS app. Finally, removes the finalizer.
func (r *eventingAuthReconciler) handleDeletion(ctx context.Context, iasClient ias.Client, skrClient skr.Client, cr *operatorv1alpha1.EventingAuth) error {
func (r *eventingAuthReconciler) handleDeletion(ctx context.Context, iasClient ias.Client, cr *operatorv1alpha1.EventingAuth) error {
// The object is being deleted
if controllerutil.ContainsFinalizer(cr, eventingAuthFinalizerName) {
// delete k8s secret on SKR
if err := skrClient.DeleteSecret(ctx); err != nil {
return fmt.Errorf("failed to delete secret: %v", err)
}
ctrl.Log.Info("Deleted IAS application secret on SKR", "eventingAuth", cr.Name, "namespace", cr.Namespace)

// delete IAS application clean-up
if err := iasClient.DeleteApplication(ctx, cr.Name); err != nil {
return fmt.Errorf("failed to delete IAS Application: %v", err)
}
ctrl.Log.Info("Deleted IAS application",
"eventingAuth", cr.Name, "namespace", cr.Namespace)

if err := r.deleteK8sSecretOnSkr(ctx, cr); err != nil {
return err
}

// delete the app from the cache
delete(r.existingIasApplications, cr.Name)
ctrl.Log.Info("Deleted IAS Application", "name", cr.Name)

// remove our finalizer from the list and update it.
controllerutil.RemoveFinalizer(cr, eventingAuthFinalizerName)
Expand All @@ -223,6 +224,21 @@ func (r *eventingAuthReconciler) handleDeletion(ctx context.Context, iasClient i
return nil
}

func (r *eventingAuthReconciler) deleteK8sSecretOnSkr(ctx context.Context, eventingAuth *operatorv1alpha1.EventingAuth) error {
skrClient, err := skr.NewClient(r.Client, eventingAuth.Name)
if err != nil {
// SKR kubeconfig secret absence means it might have been deleted
return client.IgnoreNotFound(err)
}
err = skrClient.DeleteSecret(ctx)
if err != nil {
return err
}
ctrl.Log.Info("Deleted SKR k8s secret",
"eventingAuth", eventingAuth.Name, "namespace", eventingAuth.Namespace)
return nil
}

// updateEventingAuthStatus updates the subscription's status changes to k8s.
func (r *eventingAuthReconciler) updateEventingAuthStatus(ctx context.Context, cr *operatorv1alpha1.EventingAuth, conditionType operatorv1alpha1.ConditionType, errToCheck error) error {
_, err := operatorv1alpha1.UpdateConditionAndState(cr, conditionType, errToCheck)
Expand Down
52 changes: 33 additions & 19 deletions controllers/eventingauth_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package controllers_test
import (
"context"
"fmt"
"log"

"github.com/google/uuid"
"github.com/kyma-project/eventing-auth-manager/api/v1alpha1"
"github.com/kyma-project/eventing-auth-manager/internal/skr"
Expand All @@ -13,19 +15,13 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"log"
ctrlClient "sigs.k8s.io/controller-runtime/pkg/client"
)

var appSecretObjectKey = ctrlClient.ObjectKey{Name: skr.ApplicationSecretName, Namespace: skr.ApplicationSecretNamespace}

// Since all tests use the same target cluster and therefore share the same application secret, they need to be executed serially
var _ = Describe("EventingAuth Controller happy tests", Serial, Ordered, func() {
var (
eventingAuth *v1alpha1.EventingAuth
crName string
)

BeforeAll(func() {
// We allow the happy path tests to use the real IAS client if the test env vars are set
if !existIasCreds() {
Expand All @@ -39,17 +35,21 @@ var _ = Describe("EventingAuth Controller happy tests", Serial, Ordered, func()
revertIasNewClientStub()
})

BeforeEach(func() {
crName = generateCrName()
createKubeconfigSecret(crName)
})
Context("Creating and Deleting EventingAuth CR", func() {
var (
eventingAuth *v1alpha1.EventingAuth
crName string
)
BeforeEach(func() {
crName = generateCrName()
createKubeconfigSecret(crName)
})

AfterEach(func() {
deleteEventingAuth(eventingAuth)
deleteKubeconfigSecret(crName)
})
AfterEach(func() {
deleteEventingAuthAndVerify(eventingAuth)
deleteKubeconfigSecret(crName)
})

Context("Creating and Deleting EventingAuth CR", func() {
It("should delete secret with IAS applications credentials", func() {
eventingAuth = createEventingAuth(crName)
verifyEventingAuthStatusReady(eventingAuth)
Expand All @@ -61,9 +61,18 @@ var _ = Describe("EventingAuth Controller happy tests", Serial, Ordered, func()
verifySecretExistsOnTargetCluster()

// Testing deletion
deleteEventingAuth(eventingAuth)
deleteEventingAuthAndVerify(eventingAuth)
verifySecretDoesNotExistOnTargetCluster()
})
It("should deletion succeed when kubeconfig secret is missing", func() {
// given
eventingAuth = createEventingAuth(crName)
verifyEventingAuthStatusReady(eventingAuth)
// when
deleteKubeconfigSecret(crName)
// then, eventingAuth deletion should succeed
deleteEventingAuthAndVerify(eventingAuth)
})
})
})

Expand All @@ -80,7 +89,7 @@ var _ = Describe("EventingAuth Controller unhappy tests", Serial, Ordered, func(

AfterEach(func() {
// as these tests uses mock IAS we can force delete EventingAuth CR
deleteEventingAuth(eventingAuth)
deleteEventingAuthAndVerify(eventingAuth)
deleteApplicationSecretOnTargetCluster()
deleteKubeconfigSecret(crName)
// set SKR client to original
Expand Down Expand Up @@ -237,7 +246,7 @@ func conditionMatcher(t string, s metav1.ConditionStatus, r, m string) gtypes.Go
"Message": Equal(m),
})
}
func deleteEventingAuth(e *v1alpha1.EventingAuth) {
func deleteEventingAuthAndVerify(e *v1alpha1.EventingAuth) {
By(fmt.Sprintf("Deleting EventingAuth %s", e.Name))
if err := k8sClient.Get(context.TODO(), ctrlClient.ObjectKeyFromObject(e), &v1alpha1.EventingAuth{}); err != nil {
Expect(errors.IsNotFound(err)).Should(BeTrue())
Expand Down Expand Up @@ -288,6 +297,11 @@ func deleteKubeconfigSecret(crName string) *corev1.Secret {
Namespace: skr.KcpNamespace,
},
}
Expect(k8sClient.Delete(context.TODO(), &kubeconfigSecret)).Should(Succeed())
Eventually(func(g Gomega) {
err := k8sClient.Delete(context.TODO(), &kubeconfigSecret)
if err != nil {
g.Expect(errors.IsNotFound(err)).Should(BeTrue())
}
}, defaultTimeout).Should(Succeed())
return &kubeconfigSecret
}
2 changes: 1 addition & 1 deletion controllers/kyma_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func deleteKymaResource(kyma *kymav1beta1.Kyma) {
g.Expect(errors.IsNotFound(err)).To(BeTrue())
} else {
// clean up EventingAuth for not real cluster
deleteEventingAuth(eventingAuth)
deleteEventingAuthAndVerify(eventingAuth)
}
}, defaultTimeout).Should(Succeed())
}
Expand Down