diff --git a/Makefile b/Makefile index fb8eae7c..7d5a0460 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ export KUBEBUILDER_ASSETS = $(LOCAL_TESTBIN)/k8s/$(ENVTEST_K8S_VERSION)-$(platfo .PHONY: kubebuilder-assets kubebuilder-assets: $(KUBEBUILDER_ASSETS) - @echo "export KUBEBUILDER_ASSETS = $(LOCAL_TESTBIN)/k8s/$(ENVTEST_K8S_VERSION)-$(platform)-$(ARCHITECTURE)" + @echo "export KUBEBUILDER_ASSETS=$(LOCAL_TESTBIN)/k8s/$(ENVTEST_K8S_VERSION)-$(platform)-$(ARCHITECTURE)" $(KUBEBUILDER_ASSETS): setup-envtest --os $(platform) --arch $(ARCHITECTURE) --bin-dir $(LOCAL_TESTBIN) use $(ENVTEST_K8S_VERSION) diff --git a/controllers/user_controller.go b/controllers/user_controller.go index 9d045148..a3389b77 100644 --- a/controllers/user_controller.go +++ b/controllers/user_controller.go @@ -97,7 +97,9 @@ func (r *UserReconciler) declareCredentials(ctx context.Context, user *topology. // https://github.com/rabbitmq/cluster-operator/blob/057b61eb50102a66f504b31464e5956526cbdc90/internal/resource/statefulset.go#L220-L226 // https://github.com/rabbitmq/messaging-topology-operator/issues/194 for i := range credentialSecret.ObjectMeta.OwnerReferences { - credentialSecret.ObjectMeta.OwnerReferences[i].BlockOwnerDeletion = ptr.To(false) + if credentialSecret.ObjectMeta.OwnerReferences[i].Kind == user.Kind { + credentialSecret.ObjectMeta.OwnerReferences[i].BlockOwnerDeletion = ptr.To(false) + } } return nil }) diff --git a/controllers/user_controller_test.go b/controllers/user_controller_test.go index 68385ade..5853fe57 100644 --- a/controllers/user_controller_test.go +++ b/controllers/user_controller_test.go @@ -8,6 +8,7 @@ import ( "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "io" "k8s.io/apimachinery/pkg/labels" + "k8s.io/utils/ptr" "net/http" "time" @@ -16,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cache" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/config" + k "sigs.k8s.io/controller-runtime/pkg/envtest/komega" "sigs.k8s.io/controller-runtime/pkg/metrics/server" rabbithole "github.com/michaelklishin/rabbit-hole/v3" @@ -105,6 +107,15 @@ var _ = Describe("UserController", func() { } } + objectStatus := func() []topology.Condition { + _ = k8sClient.Get( + ctx, + types.NamespacedName{Name: user.Name, Namespace: user.Namespace}, + &user, + ) + return user.Status.Conditions + } + AfterEach(func() { managerCancel() // Sad workaround to avoid controllers racing for the reconciliation of other's @@ -188,6 +199,11 @@ var _ = Describe("UserController", func() { }) Context("user limits", func() { + AfterEach(func() { + userLimits.Connections = nil + userLimits.Channels = nil + }) + When("the user has limits defined", func() { BeforeEach(func() { userName = "test-user-limits" @@ -422,4 +438,39 @@ var _ = Describe("UserController", func() { }) }) }) + + It("sets an owner reference and does not block owner deletion", func() { + userName = "test-owner-reference" + initialiseUser() + user.Labels = map[string]string{"test": userName} + fakeRabbitMQClient.PutUserReturns(&http.Response{Status: "201 Created", StatusCode: http.StatusCreated}, nil) + initialiseManager("test", userName) + + Expect(k8sClient.Create(ctx, &user)).To(Succeed()) + Eventually(objectStatus). + Within(statusEventsUpdateTimeout). + WithPolling(time.Second). + Should(ContainElement(MatchFields(IgnoreExtras, Fields{ + "Type": Equal(topology.ConditionType("Ready")), + "Reason": Equal("SuccessfulCreateOrUpdate"), + "Status": Equal(corev1.ConditionTrue), + })), "User should have been created and have a True Ready condition") + + generatedSecret := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: user.Name + "-user-credentials", Namespace: user.Namespace}} + Eventually(k.Get(generatedSecret)). + Within(10 * time.Second). + Should(Succeed()) + + idFn := func(e any) string { + ownRef := e.(metav1.OwnerReference) + return ownRef.Kind + } + Expect(generatedSecret.OwnerReferences).To(MatchElements(idFn, IgnoreExtras, + Elements{ + "User": MatchFields(IgnoreExtras, Fields{ + "BlockOwnerDeletion": Equal(ptr.To(false)), + }), + }, + )) + }) })