Skip to content

Commit

Permalink
issue-469, delete all users from deleted cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksiienkoMykyta committed Jul 19, 2023
1 parent 8f5d179 commit 58cb36a
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 9 deletions.
2 changes: 1 addition & 1 deletion config/samples/clusters_v1beta1_redis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
# nodeSize: "t3.medium-80-r"
nodeSize: "t3.small-20-r"
masterNodes: 3
nodesNumber: 3
nodesNumber: 0
# - region: "US_WEST_2"
# name: "testDC2"
# cloudProvider: "AWS_VPC"
Expand Down
78 changes: 70 additions & 8 deletions controllers/clusterresources/redisuser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
if finalizerNeeded {
err = r.Update(ctx, secret)
if err != nil {
l.Error(err, "Cannot update Cassandra user secret",
l.Error(err, "Cannot update Redis user secret with deletion finalizer",
"secret name", secret.Name,
"secret namespace", secret.Namespace)
r.EventRecorder.Eventf(user, models.Warning, models.UpdatedEvent,
"Cannot assign Cassandra user to a k8s secret. Reason: %v", err)
"Cannot assign Redis user to a k8s secret. Reason: %v", err)

return models.ReconcileRequeue, nil
}
Expand All @@ -156,11 +156,11 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
controllerutil.AddFinalizer(user, user.DeletionUserFinalizer(clusterID, username))
err = r.Patch(ctx, user, patch)
if err != nil {
l.Error(err, "Cannot patch Cassandra user resource",
l.Error(err, "Cannot patch Redis user resource with deletion finalizer",
"secret name", secret.Name,
"secret namespace", secret.Namespace)
r.EventRecorder.Eventf(user, models.Warning, models.PatchFailed,
"Resource patch is failed. Reason: %v", err)
"Resource patch with deletion user finalizer is failed. Reason: %v", err)

return models.ReconcileRequeue, nil
}
Expand All @@ -174,9 +174,9 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
userID := fmt.Sprintf(instaclustr.RedisUserIDFmt, clusterID, user.Namespace)
err = r.API.DeleteRedisUser(userID)
if err != nil {
l.Error(err, "Cannot delete Redis user", "user", user.Name)
l.Error(err, "Cannot delete Redis user on Instaclustr", "user", user.Name)
r.EventRecorder.Eventf(user, models.Warning, models.DeletingEvent,
"Cannot delete user. Reason: %v", err)
"Cannot delete Redis user on Instaclustr. Reason: %v", err)

return models.ReconcileRequeue, nil
}
Expand All @@ -201,7 +201,7 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
controllerutil.RemoveFinalizer(user, user.DeletionUserFinalizer(clusterID, user.Namespace))
err = r.Patch(ctx, user, patch)
if err != nil {
l.Error(err, "Cannot patch Cassandra user resource",
l.Error(err, "Cannot patch Redis user resource",
"secret name", secret.Name,
"secret namespace", secret.Namespace)
r.EventRecorder.Eventf(user, models.Warning, models.PatchFailed,
Expand All @@ -213,10 +213,23 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
continue
}

if event == models.ClusterDeletingEvent {
err = r.detachUserFromDeletedCluster(ctx, clusterID, user, l)
if err != nil {
l.Error(err, "Cannot delete Redis user resource",
"secret name", secret.Name,
"secret namespace", secret.Namespace)
r.EventRecorder.Eventf(user, models.Warning, models.PatchFailed,
"Resource deleting is failed. Reason: %v", err)

return models.ReconcileRequeue, nil
}
}

userID := fmt.Sprintf(instaclustr.RedisUserIDFmt, clusterID, username)
err = r.API.UpdateRedisUser(user.ToInstAPIUpdate(password, userID))
if err != nil {
l.Error(err, "Cannot update redis user",
l.Error(err, "Cannot update redis user password",
"secret name", user.Spec.SecretRef.Name,
"secret namespace", user.Spec.SecretRef.Namespace,
"username", username,
Expand Down Expand Up @@ -254,6 +267,55 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return models.ExitReconcile, nil
}

func (r *RedisUserReconciler) detachUserFromDeletedCluster(
ctx context.Context,
clusterID string,
user *v1beta1.RedisUser,
logger logr.Logger,
) error {

patch := user.NewPatch()
delete(user.Status.ClustersEvents, clusterID)

err := r.Status().Patch(ctx, user, patch)
if err != nil {
logger.Error(err, "Cannot detach clusterID from the Redis user resource",
"cluster ID", clusterID,
)
r.EventRecorder.Eventf(
user, models.Warning, models.PatchFailed,
"Detaching clusterID from the Redis user resource has been failed. Reason: %v",
err,
)
return err
}

patch = user.NewPatch()
controllerutil.RemoveFinalizer(user, getDeletionUserFinalizer(clusterID))

err = r.Patch(ctx, user, patch)
if err != nil {
logger.Error(err, "Cannot delete finalizer from the Redis user resource",
"cluster ID", clusterID,
)
r.EventRecorder.Eventf(
user, models.Warning, models.PatchFailed,
"Deleting finalizer from the Redis user resource has been failed. Reason: %v",
err,
)
return err
}
logger.Info("Redis user has been deleted from the cluster",
"cluster ID", clusterID,
)
r.EventRecorder.Eventf(
user, models.Normal, models.Deleted,
"Redis user resource has been deleted from the cluster (clusterID: %v)", clusterID,
)

return err
}

func (r *RedisUserReconciler) handleDeleteUser(
ctx context.Context,
l logr.Logger,
Expand Down
64 changes: 64 additions & 0 deletions controllers/clusters/redis_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ func (r *RedisReconciler) handleDeleteCluster(
redis *v1beta1.Redis,
logger logr.Logger,
) reconcile.Result {

_, err := r.API.GetRedis(redis.Status.ID)
if err != nil && !errors.Is(err, instaclustr.NotFound) {
logger.Error(err, "Cannot get Redis cluster status from Instaclustr",
Expand All @@ -476,6 +477,23 @@ func (r *RedisReconciler) handleDeleteCluster(
return models.ReconcileRequeue
}

for _, ref := range redis.Spec.UserRefs {
err = r.detachUserResource(ctx, logger, redis, ref)
if err != nil {
logger.Error(err, "Cannot delete Redis user cluster",
"cluster name", redis.Spec.Name,
"cluster status", redis.Status.State,
)

r.EventRecorder.Eventf(
redis, models.Warning, models.DeletionFailed,
"Cluster deletion on the Instaclustr is failed. Reason: %v",
err,
)
return models.ReconcileRequeue
}
}

if !errors.Is(err, instaclustr.NotFound) {
logger.Info("Sending cluster deletion to the Instaclustr API",
"cluster name", redis.Spec.Name,
Expand Down Expand Up @@ -596,6 +614,52 @@ func (r *RedisReconciler) handleDeleteCluster(
return models.ExitReconcile
}

func (r *RedisReconciler) detachUserResource(
ctx context.Context,
l logr.Logger,
redis *v1beta1.Redis,
uRef *v1beta1.UserReference,
) error {
req := types.NamespacedName{
Namespace: uRef.Namespace,
Name: uRef.Name,
}

u := &clusterresourcesv1beta1.RedisUser{}
err := r.Get(ctx, req, u)
if err != nil {
if k8serrors.IsNotFound(err) {
l.Error(err, "Redis user is not found", "request", req)
r.EventRecorder.Eventf(redis, models.Warning, models.NotFound,
"User resource is not found, please provide correct userRef."+
"Current provided reference: %v", uRef)
return err
}

l.Error(err, "Cannot get Redis user", "user", u.Spec)
r.EventRecorder.Eventf(redis, models.Warning, models.DeletionFailed,
"Cannot get Redis user. user reference: %v", uRef)
return err
}

if _, exist := u.Status.ClustersEvents[redis.Status.ID]; !exist {
return nil
}

patch := u.NewPatch()
u.Status.ClustersEvents[redis.Status.ID] = models.ClusterDeletingEvent
err = r.Status().Patch(ctx, u, patch)
if err != nil {
l.Error(err, "Cannot patch the Redis user status with the ClusterDeletingEvent",
"cluster name", redis.Spec.Name, "cluster ID", redis.Status.ID)
r.EventRecorder.Eventf(redis, models.Warning, models.DeletionFailed,
"Cannot patch the Redis user status with the ClusterDeletingEvent. Reason: %v", err)
return err
}

return nil
}

func (r *RedisReconciler) handleUserEvent(
newObj *v1beta1.Redis,
oldUsers []*v1beta1.UserReference,
Expand Down

0 comments on commit 58cb36a

Please sign in to comment.