From 93e9507083366135fcbeedf7f97338e4a0bd83d0 Mon Sep 17 00:00:00 2001 From: Seyed Soroush Hashemi Date: Thu, 22 Jun 2023 20:06:07 +0330 Subject: [PATCH 1/3] Add generators for master and slave services --- operator/redisfailover/service/constants.go | 2 + operator/redisfailover/service/generator.go | 66 +++++++++++++++++++++ operator/redisfailover/service/names.go | 8 +++ 3 files changed, 76 insertions(+) diff --git a/operator/redisfailover/service/constants.go b/operator/redisfailover/service/constants.go index 4325a8a76..a42e2e13a 100644 --- a/operator/redisfailover/service/constants.go +++ b/operator/redisfailover/service/constants.go @@ -20,6 +20,8 @@ const ( sentinelConfigFileName = "sentinel.conf" redisConfigFileName = "redis.conf" redisName = "r" + redisMasterName = "rm" + redisSlaveName = "rs" redisShutdownName = "r-s" redisReadinessName = "r-readiness" redisRoleName = "redis" diff --git a/operator/redisfailover/service/generator.go b/operator/redisfailover/service/generator.go index e25685f6c..d16fbaa49 100644 --- a/operator/redisfailover/service/generator.go +++ b/operator/redisfailover/service/generator.go @@ -111,6 +111,72 @@ func generateRedisService(rf *redisfailoverv1.RedisFailover, labels map[string]s } } +func generateRedisMasterService(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *corev1.Service { + name := GetRedisMasterName(rf) + namespace := rf.Namespace + + selectorLabels := generateSelectorLabels(redisRoleName, rf.Name) + selectorLabels = util.MergeLabels(selectorLabels, map[string]string{ + redisRoleLabelKey: redisRoleLabelMaster, + }) + labels = util.MergeLabels(labels, selectorLabels) + + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: labels, + OwnerReferences: ownerRefs, + Annotations: rf.Spec.Redis.ServiceAnnotations, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: rf.Spec.Redis.Port, + TargetPort: intstr.FromString("redis"), + Protocol: corev1.ProtocolTCP, + }, + }, + Selector: selectorLabels, + }, + } +} + +func generateRedisSlaveService(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *corev1.Service { + name := GetRedisSlaveName(rf) + namespace := rf.Namespace + + selectorLabels := generateSelectorLabels(redisRoleName, rf.Name) + selectorLabels = util.MergeLabels(selectorLabels, map[string]string{ + redisRoleLabelKey: redisRoleLabelSlave, + }) + labels = util.MergeLabels(labels, selectorLabels) + + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Labels: labels, + OwnerReferences: ownerRefs, + Annotations: rf.Spec.Redis.ServiceAnnotations, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: rf.Spec.Redis.Port, + TargetPort: intstr.FromString("redis"), + Protocol: corev1.ProtocolTCP, + }, + }, + Selector: selectorLabels, + }, + } +} + func generateSentinelConfigMap(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) *corev1.ConfigMap { name := GetSentinelName(rf) namespace := rf.Namespace diff --git a/operator/redisfailover/service/names.go b/operator/redisfailover/service/names.go index 98d761dc6..3c3e633f5 100644 --- a/operator/redisfailover/service/names.go +++ b/operator/redisfailover/service/names.go @@ -34,6 +34,14 @@ func GetSentinelName(rf *redisfailoverv1.RedisFailover) string { return generateName(sentinelName, rf.Name) } +func GetRedisMasterName(rf *redisfailoverv1.RedisFailover) string { + return generateName(redisMasterName, rf.Name) +} + +func GetRedisSlaveName(rf *redisfailoverv1.RedisFailover) string { + return generateName(redisSlaveName, rf.Name) +} + func generateName(typeName, metaName string) string { return fmt.Sprintf("%s%s-%s", baseName, typeName, metaName) } From 99f232d341a5ee19fe3e9f4a6477ca84418973aa Mon Sep 17 00:00:00 2001 From: Seyed Soroush Hashemi Date: Thu, 22 Jun 2023 20:08:21 +0330 Subject: [PATCH 2/3] Add ensurers for master and slave services --- operator/redisfailover/ensurer.go | 8 ++++++++ operator/redisfailover/service/client.go | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/operator/redisfailover/ensurer.go b/operator/redisfailover/ensurer.go index 23b609417..388e25f58 100644 --- a/operator/redisfailover/ensurer.go +++ b/operator/redisfailover/ensurer.go @@ -29,6 +29,14 @@ func (w *RedisFailoverHandler) Ensure(rf *redisfailoverv1.RedisFailover, labels } } + if err := w.rfService.EnsureRedisMasterService(rf, labels, or); err != nil { + return err + } + + if err := w.rfService.EnsureRedisSlaveService(rf, labels, or); err != nil { + return err + } + if err := w.rfService.EnsureRedisShutdownConfigMap(rf, labels, or); err != nil { return err } diff --git a/operator/redisfailover/service/client.go b/operator/redisfailover/service/client.go index 22c8d60ea..d97e964a1 100644 --- a/operator/redisfailover/service/client.go +++ b/operator/redisfailover/service/client.go @@ -19,6 +19,8 @@ type RedisFailoverClient interface { EnsureSentinelDeployment(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error EnsureRedisStatefulset(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error EnsureRedisService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error + EnsureRedisMasterService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error + EnsureRedisSlaveService(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error EnsureRedisShutdownConfigMap(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error EnsureRedisReadinessConfigMap(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error EnsureRedisConfigMap(rFailover *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error @@ -163,6 +165,24 @@ func (r *RedisFailoverKubeClient) EnsureNotPresentRedisService(rf *redisfailover return nil } +// EnsureRedisMasterService makes sure the redis master service exists +func (r *RedisFailoverKubeClient) EnsureRedisMasterService(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { + svc := generateRedisMasterService(rf, labels, ownerRefs) + err := r.K8SService.CreateOrUpdateService(rf.Namespace, svc) + + r.setEnsureOperationMetrics(svc.Namespace, svc.Name, "Service", rf.Name, err) + return err +} + +// EnsureRedisSlaveService makes sure the redis slave service exists +func (r *RedisFailoverKubeClient) EnsureRedisSlaveService(rf *redisfailoverv1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { + svc := generateRedisSlaveService(rf, labels, ownerRefs) + err := r.K8SService.CreateOrUpdateService(rf.Namespace, svc) + + r.setEnsureOperationMetrics(svc.Namespace, svc.Name, "Service", rf.Name, err) + return err +} + // EnsureRedisStatefulset makes sure the pdb exists in the desired state func (r *RedisFailoverKubeClient) ensurePodDisruptionBudget(rf *redisfailoverv1.RedisFailover, name string, component string, labels map[string]string, ownerRefs []metav1.OwnerReference) error { name = generateName(name, rf.Name) From a439356833e2be0a3393dbe341fe83435d736a14 Mon Sep 17 00:00:00 2001 From: Seyed Soroush Hashemi Date: Thu, 22 Jun 2023 20:19:09 +0330 Subject: [PATCH 3/3] Add unit tests --- mocks/log/Logger.go | 2 +- mocks/operator/redisfailover/RedisFailover.go | 12 +- .../service/RedisFailoverCheck.go | 62 ++- .../service/RedisFailoverClient.go | 30 +- .../service/RedisFailoverHeal.go | 2 +- mocks/service/k8s/Services.go | 97 +++- mocks/service/redis/Client.go | 34 +- operator/redisfailover/ensurer_test.go | 2 + .../redisfailover/service/constants_test.go | 2 + .../redisfailover/service/generator_test.go | 482 +++++++++++++++++- 10 files changed, 677 insertions(+), 48 deletions(-) diff --git a/mocks/log/Logger.go b/mocks/log/Logger.go index d8d99b9df..2ae79dfa6 100644 --- a/mocks/log/Logger.go +++ b/mocks/log/Logger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks diff --git a/mocks/operator/redisfailover/RedisFailover.go b/mocks/operator/redisfailover/RedisFailover.go index c3c4826ac..33c086c26 100644 --- a/mocks/operator/redisfailover/RedisFailover.go +++ b/mocks/operator/redisfailover/RedisFailover.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks @@ -24,6 +24,10 @@ func (_m *RedisFailover) ListRedisFailovers(ctx context.Context, namespace strin ret := _m.Called(ctx, namespace, opts) var r0 *redisfailoverv1.RedisFailoverList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, v1.ListOptions) (*redisfailoverv1.RedisFailoverList, error)); ok { + return rf(ctx, namespace, opts) + } if rf, ok := ret.Get(0).(func(context.Context, string, v1.ListOptions) *redisfailoverv1.RedisFailoverList); ok { r0 = rf(ctx, namespace, opts) } else { @@ -32,7 +36,6 @@ func (_m *RedisFailover) ListRedisFailovers(ctx context.Context, namespace strin } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, v1.ListOptions) error); ok { r1 = rf(ctx, namespace, opts) } else { @@ -47,6 +50,10 @@ func (_m *RedisFailover) WatchRedisFailovers(ctx context.Context, namespace stri ret := _m.Called(ctx, namespace, opts) var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, v1.ListOptions) (watch.Interface, error)); ok { + return rf(ctx, namespace, opts) + } if rf, ok := ret.Get(0).(func(context.Context, string, v1.ListOptions) watch.Interface); ok { r0 = rf(ctx, namespace, opts) } else { @@ -55,7 +62,6 @@ func (_m *RedisFailover) WatchRedisFailovers(ctx context.Context, namespace stri } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, v1.ListOptions) error); ok { r1 = rf(ctx, namespace, opts) } else { diff --git a/mocks/operator/redisfailover/service/RedisFailoverCheck.go b/mocks/operator/redisfailover/service/RedisFailoverCheck.go index e58ad55b9..02c2ee339 100644 --- a/mocks/operator/redisfailover/service/RedisFailoverCheck.go +++ b/mocks/operator/redisfailover/service/RedisFailoverCheck.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks @@ -34,13 +34,16 @@ func (_m *RedisFailoverCheck) CheckIfMasterLocalhost(rFailover *v1.RedisFailover ret := _m.Called(rFailover) var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (bool, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) bool); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(bool) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -69,13 +72,16 @@ func (_m *RedisFailoverCheck) CheckRedisSlavesReady(slaveIP string, rFailover *v ret := _m.Called(slaveIP, rFailover) var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(string, *v1.RedisFailover) (bool, error)); ok { + return rf(slaveIP, rFailover) + } if rf, ok := ret.Get(0).(func(string, *v1.RedisFailover) bool); ok { r0 = rf(slaveIP, rFailover) } else { r0 = ret.Get(0).(bool) } - var r1 error if rf, ok := ret.Get(1).(func(string, *v1.RedisFailover) error); ok { r1 = rf(slaveIP, rFailover) } else { @@ -139,13 +145,16 @@ func (_m *RedisFailoverCheck) CheckSentinelQuorum(rFailover *v1.RedisFailover) ( ret := _m.Called(rFailover) var r0 int + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (int, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) int); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(int) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -174,13 +183,16 @@ func (_m *RedisFailoverCheck) GetMasterIP(rFailover *v1.RedisFailover) (string, ret := _m.Called(rFailover) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) string); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -195,13 +207,16 @@ func (_m *RedisFailoverCheck) GetMaxRedisPodTime(rFailover *v1.RedisFailover) (t ret := _m.Called(rFailover) var r0 time.Duration + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (time.Duration, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) time.Duration); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(time.Duration) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -216,13 +231,16 @@ func (_m *RedisFailoverCheck) GetNumberMasters(rFailover *v1.RedisFailover) (int ret := _m.Called(rFailover) var r0 int + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (int, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) int); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(int) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -237,13 +255,16 @@ func (_m *RedisFailoverCheck) GetRedisRevisionHash(podName string, rFailover *v1 ret := _m.Called(podName, rFailover) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, *v1.RedisFailover) (string, error)); ok { + return rf(podName, rFailover) + } if rf, ok := ret.Get(0).(func(string, *v1.RedisFailover) string); ok { r0 = rf(podName, rFailover) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string, *v1.RedisFailover) error); ok { r1 = rf(podName, rFailover) } else { @@ -258,6 +279,10 @@ func (_m *RedisFailoverCheck) GetRedisesIPs(rFailover *v1.RedisFailover) ([]stri ret := _m.Called(rFailover) var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) ([]string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) []string); ok { r0 = rf(rFailover) } else { @@ -266,7 +291,6 @@ func (_m *RedisFailoverCheck) GetRedisesIPs(rFailover *v1.RedisFailover) ([]stri } } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -281,13 +305,16 @@ func (_m *RedisFailoverCheck) GetRedisesMasterPod(rFailover *v1.RedisFailover) ( ret := _m.Called(rFailover) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) string); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -302,6 +329,10 @@ func (_m *RedisFailoverCheck) GetRedisesSlavesPods(rFailover *v1.RedisFailover) ret := _m.Called(rFailover) var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) ([]string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) []string); ok { r0 = rf(rFailover) } else { @@ -310,7 +341,6 @@ func (_m *RedisFailoverCheck) GetRedisesSlavesPods(rFailover *v1.RedisFailover) } } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -325,6 +355,10 @@ func (_m *RedisFailoverCheck) GetSentinelsIPs(rFailover *v1.RedisFailover) ([]st ret := _m.Called(rFailover) var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) ([]string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) []string); ok { r0 = rf(rFailover) } else { @@ -333,7 +367,6 @@ func (_m *RedisFailoverCheck) GetSentinelsIPs(rFailover *v1.RedisFailover) ([]st } } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { @@ -348,13 +381,16 @@ func (_m *RedisFailoverCheck) GetStatefulSetUpdateRevision(rFailover *v1.RedisFa ret := _m.Called(rFailover) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover) (string, error)); ok { + return rf(rFailover) + } if rf, ok := ret.Get(0).(func(*v1.RedisFailover) string); ok { r0 = rf(rFailover) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(*v1.RedisFailover) error); ok { r1 = rf(rFailover) } else { diff --git a/mocks/operator/redisfailover/service/RedisFailoverClient.go b/mocks/operator/redisfailover/service/RedisFailoverClient.go index e96e294fb..61b7c96e2 100644 --- a/mocks/operator/redisfailover/service/RedisFailoverClient.go +++ b/mocks/operator/redisfailover/service/RedisFailoverClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks @@ -42,6 +42,20 @@ func (_m *RedisFailoverClient) EnsureRedisConfigMap(rFailover *v1.RedisFailover, return r0 } +// EnsureRedisMasterService provides a mock function with given fields: rFailover, labels, ownerRefs +func (_m *RedisFailoverClient) EnsureRedisMasterService(rFailover *v1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { + ret := _m.Called(rFailover, labels, ownerRefs) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover, map[string]string, []metav1.OwnerReference) error); ok { + r0 = rf(rFailover, labels, ownerRefs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // EnsureRedisReadinessConfigMap provides a mock function with given fields: rFailover, labels, ownerRefs func (_m *RedisFailoverClient) EnsureRedisReadinessConfigMap(rFailover *v1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { ret := _m.Called(rFailover, labels, ownerRefs) @@ -84,6 +98,20 @@ func (_m *RedisFailoverClient) EnsureRedisShutdownConfigMap(rFailover *v1.RedisF return r0 } +// EnsureRedisSlaveService provides a mock function with given fields: rFailover, labels, ownerRefs +func (_m *RedisFailoverClient) EnsureRedisSlaveService(rFailover *v1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { + ret := _m.Called(rFailover, labels, ownerRefs) + + var r0 error + if rf, ok := ret.Get(0).(func(*v1.RedisFailover, map[string]string, []metav1.OwnerReference) error); ok { + r0 = rf(rFailover, labels, ownerRefs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // EnsureRedisStatefulset provides a mock function with given fields: rFailover, labels, ownerRefs func (_m *RedisFailoverClient) EnsureRedisStatefulset(rFailover *v1.RedisFailover, labels map[string]string, ownerRefs []metav1.OwnerReference) error { ret := _m.Called(rFailover, labels, ownerRefs) diff --git a/mocks/operator/redisfailover/service/RedisFailoverHeal.go b/mocks/operator/redisfailover/service/RedisFailoverHeal.go index ae9a0d2fe..f7d1202c3 100644 --- a/mocks/operator/redisfailover/service/RedisFailoverHeal.go +++ b/mocks/operator/redisfailover/service/RedisFailoverHeal.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks diff --git a/mocks/service/k8s/Services.go b/mocks/service/k8s/Services.go index 54febb9d7..e734f6f47 100644 --- a/mocks/service/k8s/Services.go +++ b/mocks/service/k8s/Services.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks @@ -354,6 +354,10 @@ func (_m *Services) GetClusterRole(name string) (*rbacv1.ClusterRole, error) { ret := _m.Called(name) var r0 *rbacv1.ClusterRole + var r1 error + if rf, ok := ret.Get(0).(func(string) (*rbacv1.ClusterRole, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) *rbacv1.ClusterRole); ok { r0 = rf(name) } else { @@ -362,7 +366,6 @@ func (_m *Services) GetClusterRole(name string) (*rbacv1.ClusterRole, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -377,6 +380,10 @@ func (_m *Services) GetConfigMap(namespace string, name string) (*v1.ConfigMap, ret := _m.Called(namespace, name) var r0 *v1.ConfigMap + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.ConfigMap, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.ConfigMap); ok { r0 = rf(namespace, name) } else { @@ -385,7 +392,6 @@ func (_m *Services) GetConfigMap(namespace string, name string) (*v1.ConfigMap, } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -400,6 +406,10 @@ func (_m *Services) GetDeployment(namespace string, name string) (*appsv1.Deploy ret := _m.Called(namespace, name) var r0 *appsv1.Deployment + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*appsv1.Deployment, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *appsv1.Deployment); ok { r0 = rf(namespace, name) } else { @@ -408,7 +418,6 @@ func (_m *Services) GetDeployment(namespace string, name string) (*appsv1.Deploy } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -423,6 +432,10 @@ func (_m *Services) GetDeploymentPods(namespace string, name string) (*v1.PodLis ret := _m.Called(namespace, name) var r0 *v1.PodList + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.PodList, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.PodList); ok { r0 = rf(namespace, name) } else { @@ -431,7 +444,6 @@ func (_m *Services) GetDeploymentPods(namespace string, name string) (*v1.PodLis } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -446,6 +458,10 @@ func (_m *Services) GetPod(namespace string, name string) (*v1.Pod, error) { ret := _m.Called(namespace, name) var r0 *v1.Pod + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.Pod, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.Pod); ok { r0 = rf(namespace, name) } else { @@ -454,7 +470,6 @@ func (_m *Services) GetPod(namespace string, name string) (*v1.Pod, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -469,6 +484,10 @@ func (_m *Services) GetPodDisruptionBudget(namespace string, name string) (*poli ret := _m.Called(namespace, name) var r0 *policyv1.PodDisruptionBudget + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*policyv1.PodDisruptionBudget, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *policyv1.PodDisruptionBudget); ok { r0 = rf(namespace, name) } else { @@ -477,7 +496,6 @@ func (_m *Services) GetPodDisruptionBudget(namespace string, name string) (*poli } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -492,6 +510,10 @@ func (_m *Services) GetRole(namespace string, name string) (*rbacv1.Role, error) ret := _m.Called(namespace, name) var r0 *rbacv1.Role + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*rbacv1.Role, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *rbacv1.Role); ok { r0 = rf(namespace, name) } else { @@ -500,7 +522,6 @@ func (_m *Services) GetRole(namespace string, name string) (*rbacv1.Role, error) } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -515,6 +536,10 @@ func (_m *Services) GetRoleBinding(namespace string, name string) (*rbacv1.RoleB ret := _m.Called(namespace, name) var r0 *rbacv1.RoleBinding + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*rbacv1.RoleBinding, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *rbacv1.RoleBinding); ok { r0 = rf(namespace, name) } else { @@ -523,7 +548,6 @@ func (_m *Services) GetRoleBinding(namespace string, name string) (*rbacv1.RoleB } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -538,6 +562,10 @@ func (_m *Services) GetSecret(namespace string, name string) (*v1.Secret, error) ret := _m.Called(namespace, name) var r0 *v1.Secret + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.Secret, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.Secret); ok { r0 = rf(namespace, name) } else { @@ -546,7 +574,6 @@ func (_m *Services) GetSecret(namespace string, name string) (*v1.Secret, error) } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -561,6 +588,10 @@ func (_m *Services) GetService(namespace string, name string) (*v1.Service, erro ret := _m.Called(namespace, name) var r0 *v1.Service + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.Service, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.Service); ok { r0 = rf(namespace, name) } else { @@ -569,7 +600,6 @@ func (_m *Services) GetService(namespace string, name string) (*v1.Service, erro } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -584,6 +614,10 @@ func (_m *Services) GetStatefulSet(namespace string, name string) (*appsv1.State ret := _m.Called(namespace, name) var r0 *appsv1.StatefulSet + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*appsv1.StatefulSet, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *appsv1.StatefulSet); ok { r0 = rf(namespace, name) } else { @@ -592,7 +626,6 @@ func (_m *Services) GetStatefulSet(namespace string, name string) (*appsv1.State } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -607,6 +640,10 @@ func (_m *Services) GetStatefulSetPods(namespace string, name string) (*v1.PodLi ret := _m.Called(namespace, name) var r0 *v1.PodList + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*v1.PodList, error)); ok { + return rf(namespace, name) + } if rf, ok := ret.Get(0).(func(string, string) *v1.PodList); ok { r0 = rf(namespace, name) } else { @@ -615,7 +652,6 @@ func (_m *Services) GetStatefulSetPods(namespace string, name string) (*v1.PodLi } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(namespace, name) } else { @@ -630,6 +666,10 @@ func (_m *Services) ListConfigMaps(namespace string) (*v1.ConfigMapList, error) ret := _m.Called(namespace) var r0 *v1.ConfigMapList + var r1 error + if rf, ok := ret.Get(0).(func(string) (*v1.ConfigMapList, error)); ok { + return rf(namespace) + } if rf, ok := ret.Get(0).(func(string) *v1.ConfigMapList); ok { r0 = rf(namespace) } else { @@ -638,7 +678,6 @@ func (_m *Services) ListConfigMaps(namespace string) (*v1.ConfigMapList, error) } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(namespace) } else { @@ -653,6 +692,10 @@ func (_m *Services) ListDeployments(namespace string) (*appsv1.DeploymentList, e ret := _m.Called(namespace) var r0 *appsv1.DeploymentList + var r1 error + if rf, ok := ret.Get(0).(func(string) (*appsv1.DeploymentList, error)); ok { + return rf(namespace) + } if rf, ok := ret.Get(0).(func(string) *appsv1.DeploymentList); ok { r0 = rf(namespace) } else { @@ -661,7 +704,6 @@ func (_m *Services) ListDeployments(namespace string) (*appsv1.DeploymentList, e } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(namespace) } else { @@ -676,6 +718,10 @@ func (_m *Services) ListPods(namespace string) (*v1.PodList, error) { ret := _m.Called(namespace) var r0 *v1.PodList + var r1 error + if rf, ok := ret.Get(0).(func(string) (*v1.PodList, error)); ok { + return rf(namespace) + } if rf, ok := ret.Get(0).(func(string) *v1.PodList); ok { r0 = rf(namespace) } else { @@ -684,7 +730,6 @@ func (_m *Services) ListPods(namespace string) (*v1.PodList, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(namespace) } else { @@ -699,6 +744,10 @@ func (_m *Services) ListRedisFailovers(ctx context.Context, namespace string, op ret := _m.Called(ctx, namespace, opts) var r0 *redisfailoverv1.RedisFailoverList + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, metav1.ListOptions) (*redisfailoverv1.RedisFailoverList, error)); ok { + return rf(ctx, namespace, opts) + } if rf, ok := ret.Get(0).(func(context.Context, string, metav1.ListOptions) *redisfailoverv1.RedisFailoverList); ok { r0 = rf(ctx, namespace, opts) } else { @@ -707,7 +756,6 @@ func (_m *Services) ListRedisFailovers(ctx context.Context, namespace string, op } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, metav1.ListOptions) error); ok { r1 = rf(ctx, namespace, opts) } else { @@ -722,6 +770,10 @@ func (_m *Services) ListServices(namespace string) (*v1.ServiceList, error) { ret := _m.Called(namespace) var r0 *v1.ServiceList + var r1 error + if rf, ok := ret.Get(0).(func(string) (*v1.ServiceList, error)); ok { + return rf(namespace) + } if rf, ok := ret.Get(0).(func(string) *v1.ServiceList); ok { r0 = rf(namespace) } else { @@ -730,7 +782,6 @@ func (_m *Services) ListServices(namespace string) (*v1.ServiceList, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(namespace) } else { @@ -745,6 +796,10 @@ func (_m *Services) ListStatefulSets(namespace string) (*appsv1.StatefulSetList, ret := _m.Called(namespace) var r0 *appsv1.StatefulSetList + var r1 error + if rf, ok := ret.Get(0).(func(string) (*appsv1.StatefulSetList, error)); ok { + return rf(namespace) + } if rf, ok := ret.Get(0).(func(string) *appsv1.StatefulSetList); ok { r0 = rf(namespace) } else { @@ -753,7 +808,6 @@ func (_m *Services) ListStatefulSets(namespace string) (*appsv1.StatefulSetList, } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(namespace) } else { @@ -894,6 +948,10 @@ func (_m *Services) WatchRedisFailovers(ctx context.Context, namespace string, o ret := _m.Called(ctx, namespace, opts) var r0 watch.Interface + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string, metav1.ListOptions) (watch.Interface, error)); ok { + return rf(ctx, namespace, opts) + } if rf, ok := ret.Get(0).(func(context.Context, string, metav1.ListOptions) watch.Interface); ok { r0 = rf(ctx, namespace, opts) } else { @@ -902,7 +960,6 @@ func (_m *Services) WatchRedisFailovers(ctx context.Context, namespace string, o } } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, string, metav1.ListOptions) error); ok { r1 = rf(ctx, namespace, opts) } else { diff --git a/mocks/service/redis/Client.go b/mocks/service/redis/Client.go index b44674d51..6950584ee 100644 --- a/mocks/service/redis/Client.go +++ b/mocks/service/redis/Client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.9.6. DO NOT EDIT. +// Code generated by mockery v2.20.0. DO NOT EDIT. package mocks @@ -14,13 +14,16 @@ func (_m *Client) GetNumberSentinelSlavesInMemory(ip string) (int32, error) { ret := _m.Called(ip) var r0 int32 + var r1 error + if rf, ok := ret.Get(0).(func(string) (int32, error)); ok { + return rf(ip) + } if rf, ok := ret.Get(0).(func(string) int32); ok { r0 = rf(ip) } else { r0 = ret.Get(0).(int32) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(ip) } else { @@ -35,13 +38,16 @@ func (_m *Client) GetNumberSentinelsInMemory(ip string) (int32, error) { ret := _m.Called(ip) var r0 int32 + var r1 error + if rf, ok := ret.Get(0).(func(string) (int32, error)); ok { + return rf(ip) + } if rf, ok := ret.Get(0).(func(string) int32); ok { r0 = rf(ip) } else { r0 = ret.Get(0).(int32) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(ip) } else { @@ -56,20 +62,23 @@ func (_m *Client) GetSentinelMonitor(ip string) (string, string, error) { ret := _m.Called(ip) var r0 string + var r1 string + var r2 error + if rf, ok := ret.Get(0).(func(string) (string, string, error)); ok { + return rf(ip) + } if rf, ok := ret.Get(0).(func(string) string); ok { r0 = rf(ip) } else { r0 = ret.Get(0).(string) } - var r1 string if rf, ok := ret.Get(1).(func(string) string); ok { r1 = rf(ip) } else { r1 = ret.Get(1).(string) } - var r2 error if rf, ok := ret.Get(2).(func(string) error); ok { r2 = rf(ip) } else { @@ -84,13 +93,16 @@ func (_m *Client) GetSlaveOf(ip string, port string, password string) (string, e ret := _m.Called(ip, port, password) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string, string) (string, error)); ok { + return rf(ip, port, password) + } if rf, ok := ret.Get(0).(func(string, string, string) string); ok { r0 = rf(ip, port, password) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string, string, string) error); ok { r1 = rf(ip, port, password) } else { @@ -105,13 +117,16 @@ func (_m *Client) IsMaster(ip string, port string, password string) (bool, error ret := _m.Called(ip, port, password) var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(string, string, string) (bool, error)); ok { + return rf(ip, port, password) + } if rf, ok := ret.Get(0).(func(string, string, string) bool); ok { r0 = rf(ip, port, password) } else { r0 = ret.Get(0).(bool) } - var r1 error if rf, ok := ret.Get(1).(func(string, string, string) error); ok { r1 = rf(ip, port, password) } else { @@ -252,13 +267,16 @@ func (_m *Client) SlaveIsReady(ip string, port string, password string) (bool, e ret := _m.Called(ip, port, password) var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(string, string, string) (bool, error)); ok { + return rf(ip, port, password) + } if rf, ok := ret.Get(0).(func(string, string, string) bool); ok { r0 = rf(ip, port, password) } else { r0 = ret.Get(0).(bool) } - var r1 error if rf, ok := ret.Get(1).(func(string, string, string) error); ok { r1 = rf(ip, port, password) } else { diff --git a/operator/redisfailover/ensurer_test.go b/operator/redisfailover/ensurer_test.go index 254e36383..2b5bddc19 100644 --- a/operator/redisfailover/ensurer_test.go +++ b/operator/redisfailover/ensurer_test.go @@ -117,6 +117,8 @@ func TestEnsure(t *testing.T) { mrfs.On("EnsureSentinelDeployment", rf, mock.Anything, mock.Anything).Once().Return(nil) } + mrfs.On("EnsureRedisMasterService", rf, mock.Anything, mock.Anything).Once().Return(nil) + mrfs.On("EnsureRedisSlaveService", rf, mock.Anything, mock.Anything).Once().Return(nil) mrfs.On("EnsureRedisConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil) mrfs.On("EnsureRedisShutdownConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil) mrfs.On("EnsureRedisReadinessConfigMap", rf, mock.Anything, mock.Anything).Once().Return(nil) diff --git a/operator/redisfailover/service/constants_test.go b/operator/redisfailover/service/constants_test.go index 0808eb0b6..fc2aa79b3 100644 --- a/operator/redisfailover/service/constants_test.go +++ b/operator/redisfailover/service/constants_test.go @@ -5,4 +5,6 @@ const ( namespace = "testns" sentinelName = "rfs-test" redisName = "rfr-test" + masterName = "rfrm-test" + slaveName = "rfrs-test" ) diff --git a/operator/redisfailover/service/generator_test.go b/operator/redisfailover/service/generator_test.go index 3b520621f..54794571e 100644 --- a/operator/redisfailover/service/generator_test.go +++ b/operator/redisfailover/service/generator_test.go @@ -536,7 +536,7 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) { client := rfservice.NewRedisFailoverKubeClient(ms, log.Dummy, metrics.Dummy) err := client.EnsureRedisStatefulset(rf, nil, test.ownerRefs) - // Check that the storage-related fields are as spected + // Check that the storage-related fields are as expected assert.Equal(test.expectedSS.Spec.Template.Spec.Volumes, generatedStatefulSet.Spec.Template.Spec.Volumes) assert.Equal(test.expectedSS.Spec.Template.Spec.Containers[0].VolumeMounts, generatedStatefulSet.Spec.Template.Spec.Containers[0].VolumeMounts) assert.Equal(test.expectedSS.Spec.VolumeClaimTemplates, generatedStatefulSet.Spec.VolumeClaimTemplates) @@ -1293,6 +1293,486 @@ func TestRedisService(t *testing.T) { } } +func TestRedisMasterService(t *testing.T) { + tests := []struct { + name string + rfName string + rfNamespace string + rfLabels map[string]string + rfAnnotations map[string]string + expectedService corev1.Service + }{ + { + name: "with defaults", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: masterName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Name provided", + rfName: "custom-name", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rfrm-custom-name", + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": "custom-name", + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": "custom-name", + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Namespace provided", + rfNamespace: "custom-namespace", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: masterName, + Namespace: "custom-namespace", + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Labels provided", + rfLabels: map[string]string{"some": "label"}, + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: masterName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + "some": "label", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Annotations provided", + rfAnnotations: map[string]string{"some": "annotation"}, + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: masterName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Annotations: map[string]string{ + "some": "annotation", + }, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "master", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert := assert.New(t) + + // Generate a default RedisFailover and attaching the required annotations + rf := generateRF() + if test.rfName != "" { + rf.Name = test.rfName + } + if test.rfNamespace != "" { + rf.Namespace = test.rfNamespace + } + rf.Spec.Redis.Port = 6379 + rf.Spec.Redis.ServiceAnnotations = test.rfAnnotations + + generatedMasterService := corev1.Service{} + + ms := &mK8SService.Services{} + ms.On("CreateOrUpdateService", rf.Namespace, mock.Anything).Once().Run(func(args mock.Arguments) { + s := args.Get(1).(*corev1.Service) + generatedMasterService = *s + }).Return(nil) + + client := rfservice.NewRedisFailoverKubeClient(ms, log.Dummy, metrics.Dummy) + err := client.EnsureRedisMasterService(rf, test.rfLabels, []metav1.OwnerReference{{Name: "testing"}}) + + assert.Equal(test.expectedService, generatedMasterService) + assert.NoError(err) + }) + } +} + +func TestRedisSlaveService(t *testing.T) { + tests := []struct { + name string + rfName string + rfNamespace string + rfLabels map[string]string + rfAnnotations map[string]string + expectedService corev1.Service + }{ + { + name: "with defaults", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: slaveName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Name provided", + rfName: "custom-name", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rfrs-custom-name", + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": "custom-name", + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": "custom-name", + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Namespace provided", + rfNamespace: "custom-namespace", + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: slaveName, + Namespace: "custom-namespace", + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Labels provided", + rfLabels: map[string]string{"some": "label"}, + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: slaveName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + "some": "label", + }, + Annotations: nil, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + { + name: "with Annotations provided", + rfAnnotations: map[string]string{"some": "annotation"}, + expectedService: corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: slaveName, + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Annotations: map[string]string{ + "some": "annotation", + }, + OwnerReferences: []metav1.OwnerReference{ + { + Name: "testing", + }, + }, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "app.kubernetes.io/component": "redis", + "app.kubernetes.io/name": name, + "app.kubernetes.io/part-of": "redis-failover", + "redisfailovers-role": "slave", + }, + Ports: []corev1.ServicePort{ + { + Name: "redis", + Port: 6379, + Protocol: corev1.ProtocolTCP, + TargetPort: intstr.FromString("redis"), + }, + }, + }, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert := assert.New(t) + + // Generate a default RedisFailover and attaching the required annotations + rf := generateRF() + if test.rfName != "" { + rf.Name = test.rfName + } + if test.rfNamespace != "" { + rf.Namespace = test.rfNamespace + } + rf.Spec.Redis.Port = 6379 + rf.Spec.Redis.ServiceAnnotations = test.rfAnnotations + + generatedSlaveService := corev1.Service{} + + ms := &mK8SService.Services{} + ms.On("CreateOrUpdateService", rf.Namespace, mock.Anything).Once().Run(func(args mock.Arguments) { + s := args.Get(1).(*corev1.Service) + generatedSlaveService = *s + }).Return(nil) + + client := rfservice.NewRedisFailoverKubeClient(ms, log.Dummy, metrics.Dummy) + err := client.EnsureRedisSlaveService(rf, test.rfLabels, []metav1.OwnerReference{{Name: "testing"}}) + + assert.Equal(test.expectedService, generatedSlaveService) + assert.NoError(err) + }) + } +} + func TestRedisHostNetworkAndDnsPolicy(t *testing.T) { tests := []struct { name string