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 18, 2023
1 parent 8f5d179 commit 2b057d8
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 9 deletions.
16 changes: 8 additions & 8 deletions config/samples/clusters_v1beta1_redis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ metadata:
app.kubernetes.io/created-by: operator
name: redis-sample
spec:
name: "testRedis"
name: "mykyta-testRedis"
version: "7.0.11"
slaTier: "NON_PRODUCTION"
clientEncryption: false
passwordAndUserAuth: true
userRefs:
# - name: redisuser-sample-1
# namespace: default
# - name: redisuser-sample-2
# namespace: default
# - name: redisuser-sample-3
# namespace: default
- name: redisuser-sample-1
namespace: default
- name: redisuser-sample-2
namespace: default
- name: redisuser-sample-3
namespace: default
# twoFactorDelete:
# - email: "[email protected]"
dataCentres:
Expand All @@ -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
54 changes: 53 additions & 1 deletion controllers/clusterresources/redisuser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,6 +213,12 @@ func (r *RedisUserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
continue
}

if event == models.ClusterDeletingEvent {
_ = r.detachUserFromDeletedCluster(ctx, clusterID, user, l)

continue
}

userID := fmt.Sprintf(instaclustr.RedisUserIDFmt, clusterID, username)
err = r.API.UpdateRedisUser(user.ToInstAPIUpdate(password, userID))
if err != nil {
Expand Down Expand Up @@ -254,6 +260,52 @@ 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 nil
}

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 nil
}
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 nil
}

func (r *RedisUserReconciler) handleDeleteUser(
ctx context.Context,
l logr.Logger,
Expand Down
117 changes: 117 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 Expand Up @@ -652,6 +716,59 @@ func (r *RedisReconciler) handleUserEvent(
}
}

//func (r *RedisReconciler) handleUsersDelete(
// ctx context.Context,
// l logr.Logger,
// c *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(c, models.Warning, models.NotFound,
// "User is not found, create a new one Redis User or provide correct userRef."+
// "Current provided reference: %v", uRef)
// return err
// }
//
// l.Error(err, "Cannot get Redis user", "user", u.Spec)
// r.EventRecorder.Eventf(c, models.Warning, models.DeletionFailed,
// "Cannot get Redis user. User reference: %v", uRef)
// return err
// }
//
// if _, exist := u.Status.ClustersEvents[c.Status.ID]; !exist {
// l.Info("User is not existing on the cluster",
// "user reference", uRef)
// r.EventRecorder.Eventf(c, models.Normal, models.DeletionFailed,
// "User is not existing on the cluster. User reference: %v", uRef)
//
// return nil
// }
//
// patch := u.NewPatch()
//
// u.Status.ClustersEvents[c.Status.ID] = models.DeletingEvent
//
// err = r.Status().Patch(ctx, u, patch)
// if err != nil {
// l.Error(err, "Cannot patch the Redis User status with the DeletingEvent",
// "cluster name", c.Spec.Name, "cluster ID", c.Status.ID)
// r.EventRecorder.Eventf(c, models.Warning, models.DeletionFailed,
// "Cannot patch the Redis User status with the DeletingEvent. Reason: %v", err)
// return err
// }
//
// return nil
//}

func (r *RedisReconciler) handleUsersDelete(
ctx context.Context,
l logr.Logger,
Expand Down

0 comments on commit 2b057d8

Please sign in to comment.