diff --git a/controllers/redisreplication_controller.go b/controllers/redisreplication_controller.go index 9929e332c..3751d83bd 100644 --- a/controllers/redisreplication_controller.go +++ b/controllers/redisreplication_controller.go @@ -86,7 +86,11 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req if err != nil { return ctrl.Result{RequeueAfter: time.Second * 60}, err } - + // Set label of redis replication role master or slave + err = k8sutils.UpdateRoleLabelPod(ctx, r.K8sClient, r.Log, instance) + if err != nil { + return ctrl.Result{RequeueAfter: time.Second * 60}, err + } } reqLogger.Info("Will reconcile redis operator in again 10 seconds") diff --git a/k8sutils/redis-replication.go b/k8sutils/redis-replication.go index 81803b10a..ec7dbe1a9 100644 --- a/k8sutils/redis-replication.go +++ b/k8sutils/redis-replication.go @@ -1,8 +1,11 @@ package k8sutils import ( + "context" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" + "github.com/go-logr/logr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/utils/pointer" ) @@ -27,6 +30,7 @@ func CreateReplicationService(cr *redisv1beta2.RedisReplication, cl kubernetes.I } objectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name, cr.Namespace, labels, annotations) headlessObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-headless", cr.Namespace, labels, annotations) + masterObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-master", cr.Namespace, labels, annotations) additionalObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations, epp)) err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisReplicationAsOwner(cr), disableMetrics, true, "ClusterIP", redisPort, cl) if err != nil { @@ -47,6 +51,11 @@ func CreateReplicationService(cr *redisv1beta2.RedisReplication, cl kubernetes.I logger.Error(err, "Cannot create additional service for Redis Replication") return err } + err = CreateOrUpdateService(cr.Namespace, masterObjectMetaInfo, redisReplicationAsOwner(cr), disableMetrics, false, additionalServiceType, redisPort, cl) + if err != nil { + logger.Error(err, "Cannot create additional service for Redis Replication") + return err + } return nil } @@ -198,3 +207,37 @@ func generateRedisReplicationInitContainerParams(cr *redisv1beta2.RedisReplicati return initcontainerProp } + +func updatePodLabel(ctx context.Context, cl kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication, role string, nodes []string) error { + for i := 0; i < len(nodes); i++ { + // read Label + pod, err := cl.CoreV1().Pods(cr.Namespace).Get(context.TODO(), nodes[i], metav1.GetOptions{}) + if err != nil { + logger.Error(err, "Cannot get redis replication pod") + return err + } + // set Label redis-role + metav1.SetMetaDataLabel(&pod.ObjectMeta, "redis-role", role) + // update Label + _, err = cl.CoreV1().Pods(cr.Namespace).Update(context.TODO(), pod, metav1.UpdateOptions{}) + if err != nil { + logger.Error(err, "Cannot update redis replication pod") + return err + } + } + return nil +} + +func UpdateRoleLabelPod(ctx context.Context, cl kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication) error { + role := "master" + err := updatePodLabel(ctx, cl, logger, cr, role, GetRedisNodesByRole(ctx, cl, logger, cr, role)) + if err != nil { + return err + } + role = "slave" + err = updatePodLabel(ctx, cl, logger, cr, role, GetRedisNodesByRole(ctx, cl, logger, cr, role)) + if err != nil { + return err + } + return nil +} diff --git a/k8sutils/services.go b/k8sutils/services.go index 353e68f58..e394357fd 100644 --- a/k8sutils/services.go +++ b/k8sutils/services.go @@ -38,13 +38,17 @@ func generateServiceDef(serviceMeta metav1.ObjectMeta, epp exporterPortProvider, } else { PortName = "redis-client" } + selectorLabels := serviceMeta.GetLabels() + if serviceMeta.GetName() == "redis-replication-master" { + selectorLabels["redis-role"] = "master" + } service := &corev1.Service{ TypeMeta: generateMetaInformation("Service", "v1"), ObjectMeta: serviceMeta, Spec: corev1.ServiceSpec{ Type: generateServiceType(serviceType), ClusterIP: "", - Selector: serviceMeta.GetLabels(), + Selector: selectorLabels, Ports: []corev1.ServicePort{ { Name: PortName, diff --git a/k8sutils/services_test.go b/k8sutils/services_test.go index 786783944..362a59d63 100644 --- a/k8sutils/services_test.go +++ b/k8sutils/services_test.go @@ -229,6 +229,47 @@ func TestGenerateServiceDef(t *testing.T) { }, }, }, + { + name: "Test replication-master with ClusterIP service type", + serviceMeta: metav1.ObjectMeta{ + Name: "test-redis-replication-master", + Labels: map[string]string{ + "redis-role": "master", + }, + }, + enableMetrics: disableMetrics, + headless: false, + serviceType: "ClusterIP", + port: redisPort, + expected: &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-redis-replication-master", + Labels: map[string]string{ + "redis-role": "master", + }, + OwnerReferences: []metav1.OwnerReference{ + {}, + }, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "redis-client", + Port: redisPort, + TargetPort: intstr.FromInt(int(redisPort)), + Protocol: corev1.ProtocolTCP, + }, + }, + Selector: map[string]string{"redis-role": "master"}, + ClusterIP: "", + Type: corev1.ServiceTypeClusterIP, + }, + }, + }, } for _, tt := range tests {