dynamo/deploy/cloud/operator/internal/controller_common/finalizer.go

68 lines
2.0 KiB
Go

package controller_common
import (
"context"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/log"
)
const (
finalizerName = "nvidia.com/finalizer"
)
func AddFinalizer(obj client.Object) {
controllerutil.AddFinalizer(obj, finalizerName)
}
func RemoveFinalizer(obj client.Object) {
controllerutil.RemoveFinalizer(obj, finalizerName)
}
func ContainsFinalizer(obj client.Object) bool {
return controllerutil.ContainsFinalizer(obj, finalizerName)
}
type Finalizer[T client.Object] interface {
FinalizeResource(ctx context.Context, obj T) error
}
func HandleFinalizer[T client.Object](ctx context.Context, obj T, writer client.Writer, finalizer Finalizer[T]) (bool, error) {
logger := log.FromContext(ctx)
// Check if the CR is being deleted
if obj.GetDeletionTimestamp().IsZero() {
// object is not being deleted, add the finalizer if it doesn't exist
if !ContainsFinalizer(obj) {
logger.Info("Adding finalizer to object", "resourceVersion", obj.GetResourceVersion())
AddFinalizer(obj)
err := writer.Update(ctx, obj)
if err != nil {
logger.Error(err, "Failed to add finalizer")
return false, err
}
logger.Info("Finalizer added to object", "resourceVersion", obj.GetResourceVersion())
}
} else {
// object is being deleted, if the finalizer exists, call the finalizer and remove the finalizer
if ContainsFinalizer(obj) {
logger.Info("Calling finalizer", "resourceVersion", obj.GetResourceVersion())
err := finalizer.FinalizeResource(ctx, obj)
if err != nil {
logger.Error(err, "Failed to call finalizer")
return false, err
}
logger.Info("Removing finalizer from object", "resourceVersion", obj.GetResourceVersion())
RemoveFinalizer(obj)
err = writer.Update(ctx, obj)
if err != nil {
logger.Error(err, "Failed to remove finalizer")
return false, err
}
logger.Info("Finalizer removed from object", "resourceVersion", obj.GetResourceVersion())
return true, nil
}
}
return false, nil
}