diff --git a/internal/controller/pod_controller.go b/internal/controller/pod_controller.go index 5cd86cf0..12733818 100644 --- a/internal/controller/pod_controller.go +++ b/internal/controller/pod_controller.go @@ -74,7 +74,13 @@ func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result modelValidationName, ok := pod.Labels[constants.ModelValidationLabel] if !ok || modelValidationName == "" { - // Try to remove the pod in case it was previously tracked but label was removed + if controllerutil.ContainsFinalizer(pod, constants.ModelValidationFinalizer) { + controllerutil.RemoveFinalizer(pod, constants.ModelValidationFinalizer) + if err := r.Update(ctx, pod); err != nil { + logger.Error(err, "Failed to remove finalizer from unlabeled pod", "pod", req.NamespacedName) + return reconcile.Result{}, err + } + } if err := r.Tracker.RemovePodByName(ctx, req.NamespacedName); err != nil { logger.Error(err, "Failed to remove pod without label from tracking", "pod", req.NamespacedName) return reconcile.Result{}, err diff --git a/internal/controller/pod_controller_test.go b/internal/controller/pod_controller_test.go index 06a39f92..51fa76ee 100644 --- a/internal/controller/pod_controller_test.go +++ b/internal/controller/pod_controller_test.go @@ -59,6 +59,38 @@ var _ = Describe("PodReconciler", func() { Expect(removeByNameCalls[0].Namespace).To(Equal("default")) }) + It("should remove finalizer when label is removed from a previously injected pod", func() { + pod := testutil.CreateTestPod(testutil.TestPodOptions{ + Name: "unlabeled-pod", + Namespace: "default", + Finalizers: []string{constants.ModelValidationFinalizer}, + }) + + fakeClient := testutil.SetupFakeClientWithObjects(pod) + + reconciler = &PodReconciler{ + Client: fakeClient, + Scheme: runtime.NewScheme(), + Tracker: mockTracker, + } + + req := testutil.CreateReconcileRequest(pod.Namespace, pod.Name) + + result, err := reconciler.Reconcile(ctx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(result).To(Equal(ctrl.Result{})) + + updatedPod := &corev1.Pod{} + err = fakeClient.Get(ctx, req.NamespacedName, updatedPod) + Expect(err).NotTo(HaveOccurred()) + Expect(updatedPod.Finalizers).NotTo(ContainElement(constants.ModelValidationFinalizer), + "Finalizer must be removed when label is absent") + + removeByNameCalls := mockTracker.GetRemovePodByNameCalls() + Expect(removeByNameCalls).To(HaveLen(1)) + Expect(removeByNameCalls[0].Name).To(Equal("unlabeled-pod")) + }) + It("should process pods with finalizer but not being deleted", func() { pod := testutil.CreateTestPod(testutil.TestPodOptions{ Name: "test-pod",