Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sentinel): enhance RedisSentinel reconciliation logic and update workflow. #1176

Merged
merged 1 commit into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/pr-semantics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ jobs:
docs
release
testdata
standalone
replication
sentinel
cluster
ignoreLabels: |
bot
ignore-semantic-pull-request
Expand Down
1 change: 1 addition & 0 deletions pkg/controllers/rediscluster/rediscluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
return intctrlutil.Reconciled()
}
if _, found := instance.ObjectMeta.GetAnnotations()["rediscluster.opstreelabs.in/skip-reconcile"]; found {
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)

Check warning on line 62 in pkg/controllers/rediscluster/rediscluster_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/rediscluster/rediscluster_controller.go#L62

Added line #L62 was not covered by tests
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
}
instance.SetDefault()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@

func (r *Reconciler) reconcileAnnotation(ctx context.Context, instance *redisv1beta2.RedisReplication) (ctrl.Result, error) {
if _, found := instance.ObjectMeta.GetAnnotations()["redisreplication.opstreelabs.in/skip-reconcile"]; found {
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)

Check warning on line 130 in pkg/controllers/redisreplication/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redisreplication/redisreplication_controller.go#L130

Added line #L130 was not covered by tests
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
}
return intctrlutil.Reconciled()
Expand Down
98 changes: 73 additions & 25 deletions pkg/controllers/redissentinel/redissentinel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,84 @@
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
)

// RedisSentinelReconciler reconciles a RedisSentinel object
type RedisSentinelReconciler struct {
client.Client
K8sClient kubernetes.Interface
Dk8sClient dynamic.Interface
Scheme *runtime.Scheme

K8sClient kubernetes.Interface
Dk8sClient dynamic.Interface
Scheme *runtime.Scheme
ReplicationWatcher *intctrlutil.ResourceWatcher
}

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

err := r.Client.Get(context.TODO(), req.NamespacedName, instance)
err := r.Client.Get(ctx, req.NamespacedName, instance)
if err != nil {
return intctrlutil.RequeueWithErrorChecking(ctx, err, "")
return intctrlutil.RequeueWithErrorChecking(ctx, err, "failed to get RedisSentinel instance")

Check warning on line 33 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L33

Added line #L33 was not covered by tests
}
if instance.ObjectMeta.GetDeletionTimestamp() != nil {
if err = k8sutils.HandleRedisSentinelFinalizer(ctx, r.Client, instance); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")

var reconcilers []reconciler
if k8sutils.IsDeleted(instance) {
reconcilers = []reconciler{
{typ: "finalizer", rec: r.reconcileFinalizer},
}

Check warning on line 40 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L38-L40

Added lines #L38 - L40 were not covered by tests
} else {
reconcilers = []reconciler{
{typ: "annotation", rec: r.reconcileAnnotation},
{typ: "finalizer", rec: r.reconcileFinalizer},
{typ: "replication", rec: r.reconcileReplication},
{typ: "sentinel", rec: r.reconcileSentinel},
{typ: "pdb", rec: r.reconcilePDB},
{typ: "service", rec: r.reconcileService},
}
return intctrlutil.Reconciled()
}

if _, found := instance.ObjectMeta.GetAnnotations()["redissentinel.opstreelabs.in/skip-reconcile"]; found {
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
for _, reconciler := range reconcilers {
result, err := reconciler.rec(ctx, instance)
if err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}

Check warning on line 56 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L55-L56

Added lines #L55 - L56 were not covered by tests
if result.Requeue {
return result, nil
}

Check warning on line 59 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L58-L59

Added lines #L58 - L59 were not covered by tests
}

// Get total Sentinel Replicas
// sentinelReplicas := instance.Spec.GetSentinelCounts("sentinel")
// DO NOT REQUEUE.
// only reconcile on resource(sentinel && watched redis replication) changes
return intctrlutil.Reconciled()
}

if err = k8sutils.AddFinalizer(ctx, instance, k8sutils.RedisSentinelFinalizer, r.Client); err != nil {
type reconciler struct {
typ string
rec func(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error)
}

func (r *RedisSentinelReconciler) reconcileFinalizer(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if k8sutils.IsDeleted(instance) {
if err := k8sutils.HandleRedisSentinelFinalizer(ctx, r.Client, instance); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}
return intctrlutil.Reconciled()

Check warning on line 77 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L74-L77

Added lines #L74 - L77 were not covered by tests
}
if err := k8sutils.AddFinalizer(ctx, instance, k8sutils.RedisSentinelFinalizer, r.Client); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}
return intctrlutil.Reconciled()
}

func (r *RedisSentinelReconciler) reconcileAnnotation(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if _, found := instance.ObjectMeta.GetAnnotations()["redissentinel.opstreelabs.in/skip-reconcile"]; found {
log.FromContext(ctx).Info("found skip reconcile annotation", "namespace", instance.Namespace, "name", instance.Name)
return intctrlutil.RequeueAfter(ctx, time.Second*10, "found skip reconcile annotation")
}

Check warning on line 89 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L87-L89

Added lines #L87 - L89 were not covered by tests
return intctrlutil.Reconciled()
}

func (r *RedisSentinelReconciler) reconcileReplication(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if instance.Spec.RedisSentinelConfig != nil && !k8sutils.IsRedisReplicationReady(ctx, r.K8sClient, r.Dk8sClient, instance) {
return intctrlutil.RequeueAfter(ctx, time.Second*10, "Redis Replication is specified but not ready")
}
Expand All @@ -58,27 +99,34 @@
r.ReplicationWatcher.Watch(
ctx,
types.NamespacedName{
Namespace: req.Namespace,
Namespace: instance.Namespace,

Check warning on line 102 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L102

Added line #L102 was not covered by tests
Name: instance.Spec.RedisSentinelConfig.RedisReplicationName,
},
req.NamespacedName,
types.NamespacedName{
Namespace: instance.Namespace,
Name: instance.Name,
},

Check warning on line 108 in pkg/controllers/redissentinel/redissentinel_controller.go

View check run for this annotation

Codecov / codecov/patch

pkg/controllers/redissentinel/redissentinel_controller.go#L105-L108

Added lines #L105 - L108 were not covered by tests
)
}
return intctrlutil.Reconciled()
}

// Create Redis Sentinel
err = k8sutils.CreateRedisSentinel(ctx, r.K8sClient, instance, r.K8sClient, r.Dk8sClient)
if err != nil {
func (r *RedisSentinelReconciler) reconcileSentinel(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if err := k8sutils.CreateRedisSentinel(ctx, r.K8sClient, instance, r.K8sClient, r.Dk8sClient); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}
return intctrlutil.Reconciled()
}

err = k8sutils.ReconcileSentinelPodDisruptionBudget(ctx, instance, instance.Spec.PodDisruptionBudget, r.K8sClient)
if err != nil {
func (r *RedisSentinelReconciler) reconcilePDB(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if err := k8sutils.ReconcileSentinelPodDisruptionBudget(ctx, instance, instance.Spec.PodDisruptionBudget, r.K8sClient); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}
return intctrlutil.Reconciled()
}

// Create the Service for Redis Sentinel
err = k8sutils.CreateRedisSentinelService(ctx, instance, r.K8sClient)
if err != nil {
func (r *RedisSentinelReconciler) reconcileService(ctx context.Context, instance *redisv1beta2.RedisSentinel) (ctrl.Result, error) {
if err := k8sutils.CreateRedisSentinelService(ctx, instance, r.K8sClient); err != nil {
return intctrlutil.RequeueWithError(ctx, err, "")
}
return intctrlutil.Reconciled()
Expand Down
Loading