Skip to content

Commit 804061e

Browse files
zmotsoSergK
authored andcommitted
fix: Handle not found error when deleting KeycloakRealmUser (#181)
1 parent 577a02f commit 804061e

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

internal/controller/keycloakrealmuser/keycloakrealmuser_controller_integration_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,4 +460,61 @@ var _ = Describe("KeycloakRealmUser controller", Ordered, func() {
460460
g.Expect(createdUser.Status.Value).Should(ContainSubstring("unable to sync realm user"))
461461
}, time.Second*3, time.Second).Should(Succeed())
462462
})
463+
It("Should delete KeycloakRealmUser if user not found", func() {
464+
By("Creating a KeycloakRealmUser")
465+
user := &keycloakApi.KeycloakRealmUser{
466+
ObjectMeta: metav1.ObjectMeta{
467+
Name: "test-keycloak-realm-user-not-found",
468+
Namespace: ns,
469+
},
470+
Spec: keycloakApi.KeycloakRealmUserSpec{
471+
RealmRef: common.RealmRef{
472+
Kind: keycloakApi.KeycloakRealmKind,
473+
Name: KeycloakRealmCR,
474+
},
475+
Username: "test-user-not-found",
476+
PasswordSecret: keycloakApi.PasswordSecret{
477+
Name: userSecretName,
478+
Key: "password",
479+
},
480+
KeepResource: true,
481+
},
482+
}
483+
Expect(k8sClient.Create(ctx, user)).Should(Succeed())
484+
Eventually(func(g Gomega) {
485+
createdUser := &keycloakApi.KeycloakRealmUser{}
486+
err := k8sClient.Get(ctx, types.NamespacedName{Name: user.Name, Namespace: ns}, createdUser)
487+
g.Expect(err).ShouldNot(HaveOccurred())
488+
g.Expect(createdUser.Status.Value).Should(Equal(helper.StatusOK))
489+
}).WithTimeout(time.Second * 20).WithPolling(time.Second).Should(Succeed())
490+
491+
By("Manually deleting the user from Keycloak to simulate user not found scenario")
492+
users, err := keycloakApiClient.GetUsers(ctx, getKeyCloakToken(), KeycloakRealmCR, gocloak.GetUsersParams{
493+
Username: gocloak.StringP(user.Spec.Username),
494+
Exact: gocloak.BoolP(true),
495+
})
496+
Expect(err).ShouldNot(HaveOccurred())
497+
Expect(users).Should(HaveLen(1))
498+
499+
err = keycloakApiClient.DeleteUser(ctx, getKeyCloakToken(), KeycloakRealmCR, *users[0].ID)
500+
Expect(err).ShouldNot(HaveOccurred())
501+
502+
By("Verifying user is deleted from Keycloak")
503+
Eventually(func(g Gomega) {
504+
users, err := keycloakApiClient.GetUsers(ctx, getKeyCloakToken(), KeycloakRealmCR, gocloak.GetUsersParams{
505+
Username: gocloak.StringP(user.Spec.Username),
506+
Exact: gocloak.BoolP(true),
507+
})
508+
g.Expect(err).ShouldNot(HaveOccurred())
509+
g.Expect(users).Should(HaveLen(0))
510+
}, time.Minute, time.Second*5).Should(Succeed())
511+
512+
By("Deleting KeycloakRealmUser CR - should succeed even though user doesn't exist in Keycloak")
513+
Expect(k8sClient.Delete(ctx, user)).Should(Succeed())
514+
Eventually(func(g Gomega) {
515+
deletedUser := &keycloakApi.KeycloakRealmUser{}
516+
err := k8sClient.Get(ctx, types.NamespacedName{Name: user.Name, Namespace: ns}, deletedUser)
517+
g.Expect(k8sErrors.IsNotFound(err)).Should(BeTrue())
518+
}, timeout, interval).Should(Succeed())
519+
})
463520
})

internal/controller/keycloakrealmuser/terminator.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
ctrl "sigs.k8s.io/controller-runtime"
88

99
"github.com/epam/edp-keycloak-operator/pkg/client/keycloak"
10+
keycloakadapter "github.com/epam/edp-keycloak-operator/pkg/client/keycloak/adapter"
1011
)
1112

1213
type terminator struct {
@@ -25,6 +26,12 @@ func (t *terminator) DeleteResource(ctx context.Context) error {
2526
log.Info("Start deleting keycloak realm user")
2627

2728
if err := t.kClient.DeleteRealmUser(ctx, t.realmName, t.userName); err != nil {
29+
if keycloakadapter.IsErrNotFound(err) {
30+
log.Info("Realm user not found, skipping deletion.")
31+
32+
return nil
33+
}
34+
2835
return fmt.Errorf("unable to delete realm user %w", err)
2936
}
3037

0 commit comments

Comments
 (0)