Skip to content

Commit 2c7022a

Browse files
authored
feat(sentinel): enhance RedisSentinel reconciliation logic and update workflow. (#1176)
feat: enhance RedisSentinel reconciliation logic and update workflow. - Added new reconciler functions for handling finalizers, annotations, replication, and sentinel management in the RedisSentinel controller. - Improved error handling and logging for better debugging during reconciliation. - Updated GitHub Actions workflow to include new job types: standalone, replication, sentinel, and cluster. This update enhances the functionality and maintainability of the RedisSentinel operator. Signed-off-by: yangw <wuyangmuc@gmail.com>
1 parent d28caf1 commit 2c7022a

File tree

4 files changed

+79
-25
lines changed

4 files changed

+79
-25
lines changed

.github/workflows/pr-semantics.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ jobs:
6464
docs
6565
release
6666
testdata
67+
standalone
68+
replication
69+
sentinel
70+
cluster
6771
ignoreLabels: |
6872
bot
6973
ignore-semantic-pull-request

pkg/controllers/rediscluster/rediscluster_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
5959
return intctrlutil.Reconciled()
6060
}
6161
if _, found := instance.ObjectMeta.GetAnnotations()["rediscluster.opstreelabs.in/skip-reconcile"]; found {
62+
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)
6263
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
6364
}
6465
instance.SetDefault()

pkg/controllers/redisreplication/redisreplication_controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func (r *Reconciler) reconcileFinalizer(ctx context.Context, instance *redisv1be
127127

128128
func (r *Reconciler) reconcileAnnotation(ctx context.Context, instance *redisv1beta2.RedisReplication) (ctrl.Result, error) {
129129
if _, found := instance.ObjectMeta.GetAnnotations()["redisreplication.opstreelabs.in/skip-reconcile"]; found {
130+
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)
130131
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
131132
}
132133
return intctrlutil.Reconciled()

pkg/controllers/redissentinel/redissentinel_controller.go

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,84 @@ import (
1313
"k8s.io/client-go/kubernetes"
1414
ctrl "sigs.k8s.io/controller-runtime"
1515
"sigs.k8s.io/controller-runtime/pkg/client"
16+
"sigs.k8s.io/controller-runtime/pkg/log"
1617
)
1718

1819
// RedisSentinelReconciler reconciles a RedisSentinel object
1920
type RedisSentinelReconciler struct {
2021
client.Client
21-
K8sClient kubernetes.Interface
22-
Dk8sClient dynamic.Interface
23-
Scheme *runtime.Scheme
24-
22+
K8sClient kubernetes.Interface
23+
Dk8sClient dynamic.Interface
24+
Scheme *runtime.Scheme
2525
ReplicationWatcher *intctrlutil.ResourceWatcher
2626
}
2727

2828
func (r *RedisSentinelReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
2929
instance := &redisv1beta2.RedisSentinel{}
3030

31-
err := r.Client.Get(context.TODO(), req.NamespacedName, instance)
31+
err := r.Client.Get(ctx, req.NamespacedName, instance)
3232
if err != nil {
33-
return intctrlutil.RequeueWithErrorChecking(ctx, err, "")
33+
return intctrlutil.RequeueWithErrorChecking(ctx, err, "failed to get RedisSentinel instance")
3434
}
35-
if instance.ObjectMeta.GetDeletionTimestamp() != nil {
36-
if err = k8sutils.HandleRedisSentinelFinalizer(ctx, r.Client, instance); err != nil {
37-
return intctrlutil.RequeueWithError(ctx, err, "")
35+
36+
var reconcilers []reconciler
37+
if k8sutils.IsDeleted(instance) {
38+
reconcilers = []reconciler{
39+
{typ: "finalizer", rec: r.reconcileFinalizer},
40+
}
41+
} else {
42+
reconcilers = []reconciler{
43+
{typ: "annotation", rec: r.reconcileAnnotation},
44+
{typ: "finalizer", rec: r.reconcileFinalizer},
45+
{typ: "replication", rec: r.reconcileReplication},
46+
{typ: "sentinel", rec: r.reconcileSentinel},
47+
{typ: "pdb", rec: r.reconcilePDB},
48+
{typ: "service", rec: r.reconcileService},
3849
}
39-
return intctrlutil.Reconciled()
4050
}
4151

42-
if _, found := instance.ObjectMeta.GetAnnotations()["redissentinel.opstreelabs.in/skip-reconcile"]; found {
43-
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
52+
for _, reconciler := range reconcilers {
53+
result, err := reconciler.rec(ctx, instance)
54+
if err != nil {
55+
return intctrlutil.RequeueWithError(ctx, err, "")
56+
}
57+
if result.Requeue {
58+
return result, nil
59+
}
4460
}
4561

46-
// Get total Sentinel Replicas
47-
// sentinelReplicas := instance.Spec.GetSentinelCounts("sentinel")
62+
// DO NOT REQUEUE.
63+
// only reconcile on resource(sentinel && watched redis replication) changes
64+
return intctrlutil.Reconciled()
65+
}
4866

49-
if err = k8sutils.AddFinalizer(ctx, instance, k8sutils.RedisSentinelFinalizer, r.Client); err != nil {
67+
type reconciler struct {
68+
typ string
69+
rec func(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error)
70+
}
71+
72+
func (r *RedisSentinelReconciler) reconcileFinalizer(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
73+
if k8sutils.IsDeleted(instance) {
74+
if err := k8sutils.HandleRedisSentinelFinalizer(ctx, r.Client, instance); err != nil {
75+
return intctrlutil.RequeueWithError(ctx, err, "")
76+
}
77+
return intctrlutil.Reconciled()
78+
}
79+
if err := k8sutils.AddFinalizer(ctx, instance, k8sutils.RedisSentinelFinalizer, r.Client); err != nil {
5080
return intctrlutil.RequeueWithError(ctx, err, "")
5181
}
82+
return intctrlutil.Reconciled()
83+
}
5284

85+
func (r *RedisSentinelReconciler) reconcileAnnotation(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
86+
if _, found := instance.ObjectMeta.GetAnnotations()["redissentinel.opstreelabs.in/skip-reconcile"]; found {
87+
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)
88+
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
89+
}
90+
return intctrlutil.Reconciled()
91+
}
92+
93+
func (r *RedisSentinelReconciler) reconcileReplication(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
5394
if instance.Spec.RedisSentinelConfig != nil && !k8sutils.IsRedisReplicationReady(ctx, r.K8sClient, r.Dk8sClient, instance) {
5495
return intctrlutil.RequeueAfter(ctx, time.Second*10, "Redis Replication is specified but not ready")
5596
}
@@ -58,27 +99,34 @@ func (r *RedisSentinelReconciler) Reconcile(ctx context.Context, req ctrl.Reques
5899
r.ReplicationWatcher.Watch(
59100
ctx,
60101
types.NamespacedName{
61-
Namespace: req.Namespace,
102+
Namespace: instance.Namespace,
62103
Name: instance.Spec.RedisSentinelConfig.RedisReplicationName,
63104
},
64-
req.NamespacedName,
105+
types.NamespacedName{
106+
Namespace: instance.Namespace,
107+
Name: instance.Name,
108+
},
65109
)
66110
}
111+
return intctrlutil.Reconciled()
112+
}
67113

68-
// Create Redis Sentinel
69-
err = k8sutils.CreateRedisSentinel(ctx, r.K8sClient, instance, r.K8sClient, r.Dk8sClient)
70-
if err != nil {
114+
func (r *RedisSentinelReconciler) reconcileSentinel(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
115+
if err := k8sutils.CreateRedisSentinel(ctx, r.K8sClient, instance, r.K8sClient, r.Dk8sClient); err != nil {
71116
return intctrlutil.RequeueWithError(ctx, err, "")
72117
}
118+
return intctrlutil.Reconciled()
119+
}
73120

74-
err = k8sutils.ReconcileSentinelPodDisruptionBudget(ctx, instance, instance.Spec.PodDisruptionBudget, r.K8sClient)
75-
if err != nil {
121+
func (r *RedisSentinelReconciler) reconcilePDB(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
122+
if err := k8sutils.ReconcileSentinelPodDisruptionBudget(ctx, instance, instance.Spec.PodDisruptionBudget, r.K8sClient); err != nil {
76123
return intctrlutil.RequeueWithError(ctx, err, "")
77124
}
125+
return intctrlutil.Reconciled()
126+
}
78127

79-
// Create the Service for Redis Sentinel
80-
err = k8sutils.CreateRedisSentinelService(ctx, instance, r.K8sClient)
81-
if err != nil {
128+
func (r *RedisSentinelReconciler) reconcileService(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
129+
if err := k8sutils.CreateRedisSentinelService(ctx, instance, r.K8sClient); err != nil {
82130
return intctrlutil.RequeueWithError(ctx, err, "")
83131
}
84132
return intctrlutil.Reconciled()

0 commit comments

Comments
 (0)