diff --git a/internal/conditions/conditions.go b/internal/conditions/conditions.go index f0e77160..56218e7b 100644 --- a/internal/conditions/conditions.go +++ b/internal/conditions/conditions.go @@ -18,6 +18,7 @@ package conditions import ( "context" + "fmt" "github.com/NVIDIA/k8s-nim-operator/api/apps/v1alpha1" appsv1alpha1 "github.com/NVIDIA/k8s-nim-operator/api/apps/v1alpha1" @@ -57,10 +58,11 @@ const ( ) // Updater is the condition updater + type Updater interface { - SetConditionsReady(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error - SetConditionsNotReady(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error - SetConditionsFailed(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error + SetConditionsReady(ctx context.Context, cr client.Object, reason, message string) error + SetConditionsNotReady(ctx context.Context, cr client.Object, reason, message string) error + SetConditionsFailed(ctx context.Context, cr client.Object, reason, message string) error } type updater struct { @@ -72,7 +74,16 @@ func NewUpdater(c client.Client) Updater { return &updater{client: c} } -func (u *updater) SetConditionsReady(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { +func (u *updater) SetConditionsReady(ctx context.Context, obj client.Object, reason, message string) error { + if cr, ok := obj.(*appsv1alpha1.NIMService); ok { + return u.SetConditionsReadyNIMService(ctx, cr, reason, message) + } else if gr, ok := obj.(*appsv1alpha1.NemoGuardrail); ok { + return u.SetConditionsReadyNemoGuardrail(ctx, gr, reason, message) + } + return fmt.Errorf("unknown CRD type for %v", obj) +} + +func (u *updater) SetConditionsReadyNIMService(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ Type: Ready, Status: metav1.ConditionTrue, @@ -85,12 +96,28 @@ func (u *updater) SetConditionsReady(ctx context.Context, cr *appsv1alpha1.NIMSe Status: metav1.ConditionFalse, Reason: Ready, }) - cr.Status.State = v1alpha1.NIMServiceStatusReady return u.updateNIMServiceStatus(ctx, cr) } -func (u *updater) SetConditionsNotReady(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { +func (u *updater) SetConditionsReadyNemoGuardrail(ctx context.Context, gr *appsv1alpha1.NemoGuardrail, reason, message string) error { + meta.SetStatusCondition(&gr.Status.Conditions, metav1.Condition{ + Type: Ready, + Status: metav1.ConditionTrue, + Reason: reason, + Message: message, + }) + + meta.SetStatusCondition(&gr.Status.Conditions, metav1.Condition{ + Type: Failed, + Status: metav1.ConditionFalse, + Reason: Ready, + }) + gr.Status.State = v1alpha1.NIMServiceStatusReady + return u.updateNemoGuardrailStatus(ctx, gr) +} + +func (u *updater) SetConditionsNotReadyNIMService(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ Type: Ready, Status: metav1.ConditionFalse, @@ -104,12 +131,47 @@ func (u *updater) SetConditionsNotReady(ctx context.Context, cr *appsv1alpha1.NI Reason: Ready, Message: message, }) - cr.Status.State = v1alpha1.NIMServiceStatusNotReady return u.updateNIMServiceStatus(ctx, cr) } -func (u *updater) SetConditionsFailed(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { +func (u *updater) SetConditionsNotReadyNemoGuardrail(ctx context.Context, gr *appsv1alpha1.NemoGuardrail, reason, message string) error { + meta.SetStatusCondition(&gr.Status.Conditions, metav1.Condition{ + Type: Ready, + Status: metav1.ConditionFalse, + Reason: reason, + Message: message, + }) + + meta.SetStatusCondition(&gr.Status.Conditions, metav1.Condition{ + Type: Failed, + Status: metav1.ConditionFalse, + Reason: Ready, + Message: message, + }) + gr.Status.State = v1alpha1.NemoGuardrailStatusNotReady + return u.updateNemoGuardrailStatus(ctx, gr) +} + +func (u *updater) SetConditionsNotReady(ctx context.Context, obj client.Object, reason, message string) error { + if cr, ok := obj.(*appsv1alpha1.NIMService); ok { + return u.SetConditionsNotReadyNIMService(ctx, cr, reason, message) + } else if gr, ok := obj.(*appsv1alpha1.NemoGuardrail); ok { + return u.SetConditionsNotReadyNemoGuardrail(ctx, gr, reason, message) + } + return fmt.Errorf("unknown CRD type for %v", obj) +} + +func (u *updater) SetConditionsFailed(ctx context.Context, obj client.Object, reason, message string) error { + if cr, ok := obj.(*appsv1alpha1.NIMService); ok { + return u.SetConditionsFailedNIMService(ctx, cr, reason, message) + } else if gr, ok := obj.(*appsv1alpha1.NemoGuardrail); ok { + return u.SetConditionsFailedNemoGuardrail(ctx, gr, reason, message) + } + return fmt.Errorf("unknown CRD type for %v", obj) +} + +func (u *updater) SetConditionsFailedNIMService(ctx context.Context, cr *appsv1alpha1.NIMService, reason, message string) error { meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ Type: Ready, Status: metav1.ConditionFalse, @@ -126,6 +188,23 @@ func (u *updater) SetConditionsFailed(ctx context.Context, cr *appsv1alpha1.NIMS return u.updateNIMServiceStatus(ctx, cr) } +func (u *updater) SetConditionsFailedNemoGuardrail(ctx context.Context, cr *appsv1alpha1.NemoGuardrail, reason, message string) error { + meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ + Type: Ready, + Status: metav1.ConditionFalse, + Reason: Failed, + }) + + meta.SetStatusCondition(&cr.Status.Conditions, metav1.Condition{ + Type: Failed, + Status: metav1.ConditionTrue, + Reason: reason, + Message: message, + }) + cr.Status.State = v1alpha1.NemoGuardrailStatusFailed + return u.updateNemoGuardrailStatus(ctx, cr) +} + func (u *updater) updateNIMServiceStatus(ctx context.Context, cr *appsv1alpha1.NIMService) error { obj := &appsv1alpha1.NIMService{} @@ -140,6 +219,19 @@ func (u *updater) updateNIMServiceStatus(ctx context.Context, cr *appsv1alpha1.N return nil } +func (u *updater) updateNemoGuardrailStatus(ctx context.Context, cr *appsv1alpha1.NemoGuardrail) error { + obj := &appsv1alpha1.NemoGuardrail{} + errGet := u.client.Get(ctx, types.NamespacedName{Name: cr.Name, Namespace: cr.GetNamespace()}, obj) + if errGet != nil { + return errGet + } + obj.Status = cr.Status + if err := u.client.Status().Update(ctx, obj); err != nil { + return err + } + return nil +} + // UpdateCondition updates the given condition into the conditions list func UpdateCondition(conditions *[]metav1.Condition, conditionType string, status metav1.ConditionStatus, reason, message string) { for i := range *conditions { diff --git a/internal/controller/nemo_guardrail_controller.go b/internal/controller/nemo_guardrail_controller.go index 1d7f05db..f92d8385 100644 --- a/internal/controller/nemo_guardrail_controller.go +++ b/internal/controller/nemo_guardrail_controller.go @@ -375,7 +375,7 @@ func (r *NemoGuardrailReconciler) reconcileNemoGuardrail(ctx context.Context, Ne return ctrl.Result{}, nil } -func (r *NemoGuardrailReconciler) renderAndSyncResource(ctx context.Context, NemoGuardrail *appsv1alpha1.NemoGuardrail, renderer *render.Renderer, obj client.Object, renderFunc func() (client.Object, error), conditionType string, reason string) error { +func (r *NemoGuardrailReconciler) renderAndSyncResource(ctx context.Context, NemoGuardrail client.Object, renderer *render.Renderer, obj client.Object, renderFunc func() (client.Object, error), conditionType string, reason string) error { logger := log.FromContext(ctx) namespacedName := types.NamespacedName{Name: NemoGuardrail.GetName(), Namespace: NemoGuardrail.GetNamespace()} @@ -383,9 +383,9 @@ func (r *NemoGuardrailReconciler) renderAndSyncResource(ctx context.Context, Nem resource, err := renderFunc() if err != nil { logger.Error(err, "failed to render", conditionType, namespacedName) - statusError := r.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) + statusError := r.updater.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) if statusError != nil { - logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.Name) + logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.GetName()) } return err } @@ -409,9 +409,9 @@ func (r *NemoGuardrailReconciler) renderAndSyncResource(ctx context.Context, Nem if err = controllerutil.SetControllerReference(NemoGuardrail, resource, r.GetScheme()); err != nil { logger.Error(err, "failed to set owner", conditionType, namespacedName) - statusError := r.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) + statusError := r.updater.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) if statusError != nil { - logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.Name) + logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.GetName()) } return err } @@ -419,9 +419,9 @@ func (r *NemoGuardrailReconciler) renderAndSyncResource(ctx context.Context, Nem err = r.syncResource(ctx, obj, resource, namespacedName) if err != nil { logger.Error(err, "failed to sync", conditionType, namespacedName) - statusError := r.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) + statusError := r.updater.SetConditionsFailed(ctx, NemoGuardrail, reason, err.Error()) if statusError != nil { - logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.Name) + logger.Error(statusError, "failed to update status", "NemoGuardrail", NemoGuardrail.GetName()) } return err }