diff --git a/internal/controller/promise_controller.go b/internal/controller/promise_controller.go index f2cdc011..99be5002 100644 --- a/internal/controller/promise_controller.go +++ b/internal/controller/promise_controller.go @@ -19,6 +19,7 @@ package controller import ( "context" + stderrors "errors" "fmt" "reflect" "strings" @@ -1189,6 +1190,20 @@ func (r *PromiseReconciler) deletePromise(o opts, promise *v1alpha1.Promise) (ct requeue, err := reconcileDelete(jobOpts) if err != nil { + if stderrors.Is(err, workflow.ErrDeletePipelineFailed) { + r.EventRecorder.Event(promise, "Warning", "Failed Pipeline", "The Delete Pipeline has failed") + condition := metav1.Condition{ + Type: string(resourceutil.DeleteWorkflowCompletedCondition), + Status: metav1.ConditionFalse, + Message: "The Delete Pipeline has failed", + Reason: resourceutil.DeleteWorkflowCompletedFailedReason, + LastTransitionTime: metav1.NewTime(time.Now()), + } + updateConditionOnPromise(promise, condition) + if err := r.Client.Status().Update(o.ctx, promise); err != nil { + logging.Error(o.logger, err, "failed to update promise status", "promise", promise.GetName()) + } + } return ctrl.Result{}, err } diff --git a/internal/controller/promise_controller_test.go b/internal/controller/promise_controller_test.go index 52163461..2f3c5259 100644 --- a/internal/controller/promise_controller_test.go +++ b/internal/controller/promise_controller_test.go @@ -1123,6 +1123,38 @@ var _ = Describe("PromiseController", func() { Expect(result).To(Equal(ctrl.Result{})) }) + When("the delete pipeline fails", func() { + BeforeEach(func() { + setReconcileDeleteWorkflowToReturnError(promise) + Expect(fakeK8sClient.Delete(ctx, promise)).To(Succeed()) + result, err := t.reconcileUntilCompletion(reconciler, promise) + Expect(result).To(Equal(ctrl.Result{})) + Expect(err).To(MatchError(workflow.ErrDeletePipelineFailed)) + }) + + It("sets the DeleteWorkflowCompleted condition to Failed", func() { + Expect(fakeK8sClient.Get(ctx, promiseName, promise)).To(Succeed()) + condition := apimeta.FindStatusCondition(promise.Status.Conditions, string(resourceutil.DeleteWorkflowCompletedCondition)) + Expect(condition).NotTo(BeNil()) + Expect(condition.Status).To(Equal(metav1.ConditionFalse)) + Expect(condition.Reason).To(Equal(resourceutil.DeleteWorkflowCompletedFailedReason)) + Expect(condition.Message).To(ContainSubstring("The Delete Pipeline has failed")) + }) + + It("records an event on the promise", func() { + Eventually(func() string { + var event string + for len(eventRecorder.Events) > 0 { + event = <-eventRecorder.Events + if strings.Contains(event, "Warning Failed Pipeline The Delete Pipeline has failed") { + return event + } + } + return "" + }).Should(ContainSubstring("Warning Failed Pipeline The Delete Pipeline has failed")) + }) + }) + When("the Promise is updated to no longer have a delete workflow", func() { BeforeEach(func() { Expect(fakeK8sClient.Get(ctx, promiseName, promise)).To(Succeed())