From 37d9aff1db1b0f299cad02d50bd690efcc476594 Mon Sep 17 00:00:00 2001 From: Julio Chana Date: Tue, 5 Mar 2019 12:15:23 +0100 Subject: [PATCH] Make command for redis and sentinel configurable Signed-off-by: Julio Chana --- api/redisfailover/v1alpha2/types.go | 2 + operator/redisfailover/service/generator.go | 34 ++++-- .../redisfailover/service/generator_test.go | 103 ++++++++++++++++++ 3 files changed, 130 insertions(+), 9 deletions(-) diff --git a/api/redisfailover/v1alpha2/types.go b/api/redisfailover/v1alpha2/types.go index 3c7936dbd..d7ecdb40f 100644 --- a/api/redisfailover/v1alpha2/types.go +++ b/api/redisfailover/v1alpha2/types.go @@ -47,6 +47,7 @@ type RedisSettings struct { Image string `json:"image,omitempty"` Version string `json:"version,omitempty"` CustomConfig []string `json:"customConfig,omitempty"` + Command []string `json:"command,omitempty"` ShutdownConfigMap string `json:"shutdownConfigMap,omitempty"` Storage RedisStorage `json:"storage,omitempty"` } @@ -56,6 +57,7 @@ type SentinelSettings struct { Replicas int32 `json:"replicas,omitempty"` Resources RedisFailoverResources `json:"resources,omitempty"` CustomConfig []string `json:"customConfig,omitempty"` + Command []string `json:"command,omitempty"` } // RedisFailoverResources sets the limits and requests for a container diff --git a/operator/redisfailover/service/generator.go b/operator/redisfailover/service/generator.go index 8f6379930..cdb21d0ff 100644 --- a/operator/redisfailover/service/generator.go +++ b/operator/redisfailover/service/generator.go @@ -159,6 +159,7 @@ func generateRedisStatefulSet(rf *redisfailoverv1alpha2.RedisFailover, labels ma spec := rf.Spec redisImage := getRedisImage(rf) + redisCommand := getRedisCommand(rf) resources := getRedisResources(spec) labels = util.MergeLabels(labels, generateLabels(redisRoleName, rf.Name)) volumeMounts := getRedisVolumeMounts(rf) @@ -203,10 +204,7 @@ func generateRedisStatefulSet(rf *redisfailoverv1alpha2.RedisFailover, labels ma }, }, VolumeMounts: volumeMounts, - Command: []string{ - "redis-server", - fmt.Sprintf("/redis/%s", redisConfigFileName), - }, + Command: redisCommand, ReadinessProbe: &corev1.Probe{ InitialDelaySeconds: graceTime, TimeoutSeconds: 5, @@ -274,6 +272,7 @@ func generateSentinelDeployment(rf *redisfailoverv1alpha2.RedisFailover, labels spec := rf.Spec redisImage := getRedisImage(rf) + sentinelCommand := getSentinelCommand(rf) resources := getSentinelResources(spec) labels = util.MergeLabels(labels, generateLabels(sentinelRoleName, rf.Name)) @@ -349,11 +348,7 @@ func generateSentinelDeployment(rf *redisfailoverv1alpha2.RedisFailover, labels MountPath: "/redis", }, }, - Command: []string{ - "redis-server", - fmt.Sprintf("/redis/%s", sentinelConfigFileName), - "--sentinel", - }, + Command: sentinelCommand, ReadinessProbe: &corev1.Probe{ InitialDelaySeconds: graceTime, TimeoutSeconds: 5, @@ -653,3 +648,24 @@ func getRedisDataVolumeName(rf *redisfailoverv1alpha2.RedisFailover) string { return redisStorageVolumeName } } + +func getRedisCommand(rf *redisfailoverv1alpha2.RedisFailover) []string { + if len(rf.Spec.Redis.Command) > 0 { + return rf.Spec.Redis.Command + } + return []string{ + "redis-server", + fmt.Sprintf("/redis/%s", redisConfigFileName), + } +} + +func getSentinelCommand(rf *redisfailoverv1alpha2.RedisFailover) []string { + if len(rf.Spec.Sentinel.Command) > 0 { + return rf.Spec.Sentinel.Command + } + return []string{ + "redis-server", + fmt.Sprintf("/redis/%s", sentinelConfigFileName), + "--sentinel", + } +} diff --git a/operator/redisfailover/service/generator_test.go b/operator/redisfailover/service/generator_test.go index fb8fb9ffb..fdcd6d8e4 100644 --- a/operator/redisfailover/service/generator_test.go +++ b/operator/redisfailover/service/generator_test.go @@ -452,3 +452,106 @@ func TestRedisStatefulSetStorageGeneration(t *testing.T) { assert.NoError(err) } } + +func TestRedisStatefulSetCommands(t *testing.T) { + tests := []struct { + name string + givenCommands []string + expectedCommands []string + }{ + { + name: "Default values", + givenCommands: []string{}, + expectedCommands: []string{ + "redis-server", + "/redis/redis.conf", + }, + }, + { + name: "Given commands should be used in redis container", + givenCommands: []string{ + "test", + "command", + }, + expectedCommands: []string{ + "test", + "command", + }, + }, + } + + for _, test := range tests { + assert := assert.New(t) + + // Generate a default RedisFailover and attaching the required storage + rf := generateRF() + rf.Spec.Redis.Command = test.givenCommands + + gotCommands := []string{} + + ms := &mK8SService.Services{} + ms.On("CreateOrUpdatePodDisruptionBudget", namespace, mock.Anything).Once().Return(nil, nil) + ms.On("CreateOrUpdateStatefulSet", namespace, mock.Anything).Once().Run(func(args mock.Arguments) { + ss := args.Get(1).(*appsv1beta2.StatefulSet) + gotCommands = ss.Spec.Template.Spec.Containers[0].Command + }).Return(nil) + + client := rfservice.NewRedisFailoverKubeClient(ms, log.Dummy) + err := client.EnsureRedisStatefulset(rf, nil, []metav1.OwnerReference{}) + + assert.Equal(test.expectedCommands, gotCommands) + assert.NoError(err) + } +} + +func TestSentinelDeploymentCommands(t *testing.T) { + tests := []struct { + name string + givenCommands []string + expectedCommands []string + }{ + { + name: "Default values", + givenCommands: []string{}, + expectedCommands: []string{ + "redis-server", + "/redis/sentinel.conf", + "--sentinel", + }, + }, + { + name: "Given commands should be used in sentinel container", + givenCommands: []string{ + "test", + "command", + }, + expectedCommands: []string{ + "test", + "command", + }, + }, + } + + for _, test := range tests { + assert := assert.New(t) + + // Generate a default RedisFailover and attaching the required storage + rf := generateRF() + rf.Spec.Sentinel.Command = test.givenCommands + + gotCommands := []string{} + + ms := &mK8SService.Services{} + ms.On("CreateOrUpdatePodDisruptionBudget", namespace, mock.Anything).Once().Return(nil, nil) + ms.On("CreateOrUpdateDeployment", namespace, mock.Anything).Once().Run(func(args mock.Arguments) { + d := args.Get(1).(*appsv1beta2.Deployment) + gotCommands = d.Spec.Template.Spec.Containers[0].Command + }).Return(nil) + + client := rfservice.NewRedisFailoverKubeClient(ms, log.Dummy) + err := client.EnsureSentinelDeployment(rf, nil, []metav1.OwnerReference{}) + + assert.Equal(test.expectedCommands, gotCommands) + assert.NoError(err) + } +}