From 0be5bdb7c84a8449482f050fe19d1747d4142899 Mon Sep 17 00:00:00 2001 From: Raffael Sahli Date: Thu, 7 Dec 2023 15:39:12 +0100 Subject: [PATCH] fix: recreate existing reconcilers if the realmspec changed --- .../controllers/keycloakrealm_controller.go | 16 ++++++ .../keycloakrealm_controller_test.go | 54 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/internal/controllers/keycloakrealm_controller.go b/internal/controllers/keycloakrealm_controller.go index 921134d1..4d61d5a3 100644 --- a/internal/controllers/keycloakrealm_controller.go +++ b/internal/controllers/keycloakrealm_controller.go @@ -258,6 +258,17 @@ func (r *KeycloakRealmReconciler) podReconcile(ctx context.Context, realm infrav if current, ok := secret.Data["realm.json"]; ok { needUpdate = raw != string(current) } + + r.Log.Info("xxx", "pod", pod.Annotations) + + specVersion, ok := pod.Annotations["keycloak-controller/realm-spec-version"] + if !needUpdate && podErr == nil && ok { + needUpdate = specVersion != fmt.Sprintf("%d", realm.Generation) + } + + if !ok { + needUpdate = true + } } if secretErr != nil && !apierrors.IsNotFound(secretErr) { @@ -381,6 +392,11 @@ func (r *KeycloakRealmReconciler) podReconcile(ctx context.Context, realm infrav template.ResourceVersion = "" template.UID = "" + if template.Annotations == nil { + template.Annotations = make(map[string]string) + } + template.Annotations["keycloak-controller/realm-spec-version"] = fmt.Sprintf("%d", realm.Generation) + usernameField := "username" passwordField := "password" diff --git a/internal/controllers/keycloakrealm_controller_test.go b/internal/controllers/keycloakrealm_controller_test.go index af4445f4..10c62244 100644 --- a/internal/controllers/keycloakrealm_controller_test.go +++ b/internal/controllers/keycloakrealm_controller_test.go @@ -1445,6 +1445,60 @@ var _ = Describe("KeycloakRealm controller", func() { Expect(pod.Spec.Containers[0].Env).Should(Equal(envs)) Expect(reconciledInstance.Status.SubResourceCatalog).Should(HaveLen(0)) }) + + It("recreates the running reconciler pod if the spec changed", func() { + By("waiting for the reconciliation") + instanceLookupKey := types.NamespacedName{Name: realmName, Namespace: "default"} + reconciledInstance := &v1beta1.KeycloakRealm{} + Expect(k8sClient.Get(ctx, instanceLookupKey, reconciledInstance)).Should(BeNil()) + + beforeChangeStatus := reconciledInstance.Status + reconciledInstance.Spec.ReconcilerTemplate.Spec.Containers[1].Image = "new-image:v1" + Expect(k8sClient.Update(ctx, reconciledInstance)).Should(Succeed()) + + Eventually(func() bool { + err := k8sClient.Get(ctx, instanceLookupKey, reconciledInstance) + if err != nil { + return false + } + + return beforeChangeStatus.Reconciler != reconciledInstance.Status.Reconciler + }, timeout, interval).Should(BeTrue()) + + By("making sure there is a reconciler pod") + pod := &corev1.Pod{} + Expect(k8sClient.Get(ctx, types.NamespacedName{ + Name: reconciledInstance.Status.Reconciler, + Namespace: reconciledInstance.Namespace, + }, pod)).Should(Succeed()) + + Expect(pod.Spec.Containers[1].Image).Should(Equal("new-image:v1")) + }) + + It("recreates the running reconciler pod if the spec annotation is not present", func() { + By("waiting for the reconciliation") + instanceLookupKey := types.NamespacedName{Name: realmName, Namespace: "default"} + reconciledInstance := &v1beta1.KeycloakRealm{} + Expect(k8sClient.Get(ctx, instanceLookupKey, reconciledInstance)).Should(BeNil()) + beforeChangeStatus := reconciledInstance.Status + + pod := &corev1.Pod{} + Expect(k8sClient.Get(ctx, types.NamespacedName{ + Name: reconciledInstance.Status.Reconciler, + Namespace: reconciledInstance.Namespace, + }, pod)).Should(Succeed()) + pod.Annotations = nil + Expect(k8sClient.Update(ctx, pod)).Should(Succeed()) + + Eventually(func() bool { + err := k8sClient.Get(ctx, instanceLookupKey, reconciledInstance) + if err != nil { + return false + } + + return beforeChangeStatus.Reconciler != reconciledInstance.Status.Reconciler + }, timeout, interval).Should(BeTrue()) + }) }) When("a realm without auth credentials is reconciled", func() {