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: add redisreplication status masterNode #849

Merged
merged 4 commits into from
Mar 30, 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: 3 additions & 1 deletion api/v1beta1/redisreplication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ func (cr *RedisReplicationSpec) GetReplicationCounts(t string) int32 {
}

// RedisStatus defines the observed state of Redis
type RedisReplicationStatus struct{}
type RedisReplicationStatus struct {
MasterNode string `json:"masterNode,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
Expand Down
4 changes: 3 additions & 1 deletion api/v1beta2/redisreplication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ func (cr *RedisReplicationSpec) GetReplicationCounts(t string) int32 {
}

// RedisStatus defines the observed state of Redis
type RedisReplicationStatus struct{}
type RedisReplicationStatus struct {
MasterNode string `json:"masterNode,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3834,6 +3834,9 @@ spec:
type: object
status:
description: RedisStatus defines the observed state of Redis
properties:
masterNode:
type: string
type: object
required:
- spec
Expand Down Expand Up @@ -8255,6 +8258,9 @@ spec:
type: object
status:
description: RedisStatus defines the observed state of Redis
properties:
masterNode:
type: string
type: object
required:
- spec
Expand Down
26 changes: 23 additions & 3 deletions controllers/redisreplication_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,39 @@
return ctrl.Result{RequeueAfter: time.Second * 60}, nil
}

if len(k8sutils.GetRedisNodesByRole(ctx, r.K8sClient, r.Log, instance, "master")) > int(leaderReplicas) {
var realMaster string
masterNodes := k8sutils.GetRedisNodesByRole(ctx, r.K8sClient, r.Log, instance, "master")
if len(masterNodes) > int(leaderReplicas) {

Check warning on line 82 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L80-L82

Added lines #L80 - L82 were not covered by tests
reqLogger.Info("Creating redis replication by executing replication creation commands", "Replication.Ready", strconv.Itoa(int(redisReplicationInfo.Status.ReadyReplicas)))
masterNodes := k8sutils.GetRedisNodesByRole(ctx, r.K8sClient, r.Log, instance, "master")
slaveNodes := k8sutils.GetRedisNodesByRole(ctx, r.K8sClient, r.Log, instance, "slave")
err := k8sutils.CreateMasterSlaveReplication(ctx, r.K8sClient, r.Log, instance, masterNodes, slaveNodes)
realMaster = k8sutils.GetRedisReplicationRealMaster(ctx, r.K8sClient, r.Log, instance, masterNodes)
if len(slaveNodes) == 0 {
realMaster = masterNodes[0]

Check warning on line 87 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L85-L87

Added lines #L85 - L87 were not covered by tests
}
err := k8sutils.CreateMasterSlaveReplication(ctx, r.K8sClient, r.Log, instance, masterNodes, realMaster)

Check warning on line 89 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L89

Added line #L89 was not covered by tests
if err != nil {
return ctrl.Result{RequeueAfter: time.Second * 60}, err
}
}
realMaster = k8sutils.GetRedisReplicationRealMaster(ctx, r.K8sClient, r.Log, instance, masterNodes)
if err := r.UpdateRedisReplicationMaster(ctx, instance, realMaster); err != nil {
return ctrl.Result{}, err

Check warning on line 96 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L94-L96

Added lines #L94 - L96 were not covered by tests
}
reqLogger.Info("Will reconcile redis operator in again 10 seconds")
return ctrl.Result{RequeueAfter: time.Second * 10}, nil
}

func (r *RedisReplicationReconciler) UpdateRedisReplicationMaster(ctx context.Context, instance *redisv1beta2.RedisReplication, masterNode string) error {
if instance.Status.MasterNode == masterNode {
return nil

Check warning on line 104 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L102-L104

Added lines #L102 - L104 were not covered by tests
}
instance.Status.MasterNode = masterNode
if err := r.Client.Status().Update(ctx, instance); err != nil {
return err

Check warning on line 108 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L106-L108

Added lines #L106 - L108 were not covered by tests
}
return nil

Check warning on line 110 in controllers/redisreplication_controller.go

View check run for this annotation

Codecov / codecov/patch

controllers/redisreplication_controller.go#L110

Added line #L110 was not covered by tests
}

// SetupWithManager sets up the controller with the Manager.
func (r *RedisReplicationReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
Expand Down
12 changes: 12 additions & 0 deletions controllers/redissentinel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/workqueue"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
)

// RedisSentinelReconciler reconciles a RedisSentinel object
Expand Down Expand Up @@ -84,5 +87,14 @@ func (r *RedisSentinelReconciler) Reconcile(ctx context.Context, req ctrl.Reques
func (r *RedisSentinelReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&redisv1beta2.RedisSentinel{}).
Watches(&redisv1beta2.RedisReplication{}, &handler.Funcs{
CreateFunc: nil,
UpdateFunc: func(ctx context.Context, event event.UpdateEvent, limitingInterface workqueue.RateLimitingInterface) {
_ = event.ObjectNew.GetName()
_ = event.ObjectNew.GetNamespace()
},
DeleteFunc: nil,
GenericFunc: nil,
}).
Complete(r)
}
32 changes: 13 additions & 19 deletions k8sutils/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,25 +554,7 @@
return 0
}

func CreateMasterSlaveReplication(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication, masterPods []string, slavePods []string) error {
var realMasterPod string

for _, podName := range masterPods {
redisClient := configureRedisReplicationClient(client, logger, cr, podName)
defer redisClient.Close()

if checkAttachedSlave(ctx, redisClient, logger, podName) > 0 {
realMasterPod = podName
break
}
}
// realMasterPod = checkAttachedSlave(ctx, client, logger, cr, masterPods)

if len(slavePods) < 1 {
realMasterPod = masterPods[0]
logger.V(1).Info("No Master Node Found with attached slave promoting the following pod to master", "pod", masterPods[0])
}

func CreateMasterSlaveReplication(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication, masterPods []string, realMasterPod string) error {

Check warning on line 557 in k8sutils/redis.go

View check run for this annotation

Codecov / codecov/patch

k8sutils/redis.go#L557

Added line #L557 was not covered by tests
logger.V(1).Info("Redis Master Node is set to", "pod", realMasterPod)
realMasterInfo := RedisDetails{
PodName: realMasterPod,
Expand All @@ -596,3 +578,15 @@

return nil
}

func GetRedisReplicationRealMaster(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication, masterPods []string) string {
for _, podName := range masterPods {
redisClient := configureRedisReplicationClient(client, logger, cr, podName)
defer redisClient.Close()

Check warning on line 585 in k8sutils/redis.go

View check run for this annotation

Codecov / codecov/patch

k8sutils/redis.go#L582-L585

Added lines #L582 - L585 were not covered by tests

if checkAttachedSlave(ctx, redisClient, logger, podName) > 0 {
return podName

Check warning on line 588 in k8sutils/redis.go

View check run for this annotation

Codecov / codecov/patch

k8sutils/redis.go#L587-L588

Added lines #L587 - L588 were not covered by tests
}
}
return ""

Check warning on line 591 in k8sutils/redis.go

View check run for this annotation

Codecov / codecov/patch

k8sutils/redis.go#L591

Added line #L591 was not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ spec:
file: ready-svc.yaml
- assert:
file: ready-pvc.yaml
- assert:
file: ready-replication.yaml
catch:
- description: Redis Operator Logs
podLogs:
Expand Down Expand Up @@ -51,16 +53,4 @@ spec:
content: |
kubectl exec --namespace ${NAMESPACE} redis-replication-0 -- redis-cli -p 6379 set foo-0 bar-0
check:
($stdout=='OK'): true
# - script:
# timeout: 10s
# content: |
# kubectl exec --namespace ${NAMESPACE} redis-replication-1 -- redis-cli -p 6379 set foo-1 bar-1
# check:
# ($stdout==`READONLY You can't write against a read only replica.`): true
# - script:
# timeout: 10s
# content: |
# kubectl exec --namespace ${NAMESPACE} redis-replication-2 -- redis-cli -p 6379 set foo-2 bar-2
# check:
# ($stdout==`READONLY You can't write against a read only replica.`): true
($stdout=='OK'): true
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: redis.redis.opstreelabs.in/v1beta2
kind: RedisReplication
metadata:
name: redis-replication
status:
# by default, the first pod is being selected as master
masterNode: redis-replication-0
Loading