@@ -65,8 +65,51 @@ func ExtractPortFromPodName(podName string) int32 {
6565 return int32 (port )
6666}
6767
68+ // CreateOrUpdateRedisConfigMap creates or updates the ConfigMap for custom redis configuration
69+ func CreateOrUpdateRedisConfigMap (ctx context.Context , k8scl kubernetes.Interface , redisCluster * redisv1beta1.RedisCluster , logger logr.Logger , port int32 ) error {
70+ if len (redisCluster .Spec .RedisConfig ) == 0 {
71+ return nil // No custom config, skip ConfigMap creation
72+ }
73+
74+ configMap := GenerateRedisConfigMap (redisCluster , port )
75+ configMapName := configMap .Name
76+
77+ // Try to get existing ConfigMap
78+ existingConfigMap , err := k8scl .CoreV1 ().ConfigMaps (redisCluster .Namespace ).Get (ctx , configMapName , metav1.GetOptions {})
79+ if err != nil {
80+ if errors .IsNotFound (err ) {
81+ // Create new ConfigMap
82+ _ , err = k8scl .CoreV1 ().ConfigMaps (redisCluster .Namespace ).Create (ctx , configMap , metav1.CreateOptions {})
83+ if err != nil {
84+ logger .Error (err , "Failed to create ConfigMap" , "ConfigMap" , configMapName )
85+ return err
86+ }
87+ logger .Info ("ConfigMap created successfully" , "ConfigMap" , configMapName )
88+ return nil
89+ }
90+ logger .Error (err , "Failed to get ConfigMap" , "ConfigMap" , configMapName )
91+ return err
92+ }
93+
94+ // Update existing ConfigMap
95+ existingConfigMap .Data = configMap .Data
96+ _ , err = k8scl .CoreV1 ().ConfigMaps (redisCluster .Namespace ).Update (ctx , existingConfigMap , metav1.UpdateOptions {})
97+ if err != nil {
98+ logger .Error (err , "Failed to update ConfigMap" , "ConfigMap" , configMapName )
99+ return err
100+ }
101+ logger .Info ("ConfigMap updated successfully" , "ConfigMap" , configMapName )
102+ return nil
103+ }
104+
68105// CreateMasterPod creates a Redis master Pod with the given port
69106func CreateMasterPod (ctx context.Context , k8scl kubernetes.Interface , redisCluster * redisv1beta1.RedisCluster , logger logr.Logger , port int32 ) error {
107+ // Create or update ConfigMap if custom redis config is provided
108+ if err := CreateOrUpdateRedisConfigMap (ctx , k8scl , redisCluster , logger , port ); err != nil {
109+ logger .Error (err , "Failed to create or update ConfigMap" )
110+ return err
111+ }
112+
70113 podName := fmt .Sprintf ("rediscluster-%s-%d" , redisCluster .Name , port )
71114 masterPod := GenerateRedisPodDef (redisCluster , port , "" )
72115 _ , err := k8scl .CoreV1 ().Pods (redisCluster .Namespace ).Create (ctx , masterPod , metav1.CreateOptions {})
@@ -100,6 +143,12 @@ func CreateMasterPod(ctx context.Context, k8scl kubernetes.Interface, redisClust
100143
101144// CreateReplicaPod creates a Redis replica Pod attached to the specified master node
102145func CreateReplicaPod (ctx context.Context , k8scl kubernetes.Interface , redisCluster * redisv1beta1.RedisCluster , logger logr.Logger , port int32 , masterNodeID string ) error {
146+ // Create or update ConfigMap if custom redis config is provided
147+ if err := CreateOrUpdateRedisConfigMap (ctx , k8scl , redisCluster , logger , port ); err != nil {
148+ logger .Error (err , "Failed to create or update ConfigMap" )
149+ return err
150+ }
151+
103152 podName := fmt .Sprintf ("rediscluster-%s-%d" , redisCluster .Name , port )
104153 replicaPod := GenerateRedisPodDef (redisCluster , port , masterNodeID )
105154 _ , err := k8scl .CoreV1 ().Pods (redisCluster .Namespace ).Create (ctx , replicaPod , metav1.CreateOptions {})
@@ -187,6 +236,79 @@ func UpdatePodLabelWithRedisID(ctx context.Context, k8scl kubernetes.Interface,
187236 return nil
188237}
189238
239+ // GenerateRedisConfigMap creates a ConfigMap for custom redis configuration
240+ func GenerateRedisConfigMap (redisCluster * redisv1beta1.RedisCluster , port int32 ) * corev1.ConfigMap {
241+ configMapName := fmt .Sprintf ("rediscluster-%s-config" , redisCluster .Name )
242+
243+ // Build redis.conf content from redisConfig map
244+ var redisConf strings.Builder
245+
246+ // Add essential cluster configuration if not already present
247+ hasPort := false
248+ hasClusterEnabled := false
249+ hasClusterPort := false
250+ hasClusterNodeTimeout := false
251+ hasMaxMemory := false
252+ hasProtectedMode := false
253+
254+ for key , value := range redisCluster .Spec .RedisConfig {
255+ if key == "port" {
256+ hasPort = true
257+ }
258+ if key == "cluster-enabled" {
259+ hasClusterEnabled = true
260+ }
261+ if key == "cluster-port" {
262+ hasClusterPort = true
263+ }
264+ if key == "cluster-node-timeout" {
265+ hasClusterNodeTimeout = true
266+ }
267+ if key == "maxmemory" {
268+ hasMaxMemory = true
269+ }
270+ if key == "protected-mode" {
271+ hasProtectedMode = true
272+ }
273+ redisConf .WriteString (fmt .Sprintf ("%s %s\n " , key , value ))
274+ }
275+
276+ // Add required cluster settings if not provided by user
277+ if ! hasPort {
278+ redisConf .WriteString (fmt .Sprintf ("port %d\n " , port ))
279+ }
280+ if ! hasClusterEnabled {
281+ redisConf .WriteString ("cluster-enabled yes\n " )
282+ }
283+ if ! hasClusterPort {
284+ redisConf .WriteString (fmt .Sprintf ("cluster-port %d\n " , port + 10000 ))
285+ }
286+ if ! hasClusterNodeTimeout {
287+ redisConf .WriteString ("cluster-node-timeout 5000\n " )
288+ }
289+ if ! hasMaxMemory {
290+ redisConf .WriteString (fmt .Sprintf ("maxmemory %s\n " , redisCluster .Spec .Maxmemory ))
291+ }
292+ if ! hasProtectedMode {
293+ redisConf .WriteString ("protected-mode no\n " )
294+ }
295+
296+ configMap := & corev1.ConfigMap {
297+ ObjectMeta : metav1.ObjectMeta {
298+ Name : configMapName ,
299+ Namespace : redisCluster .Namespace ,
300+ OwnerReferences : []metav1.OwnerReference {
301+ * metav1 .NewControllerRef (redisCluster , redisv1beta1 .GroupVersion .WithKind ("RedisCluster" )),
302+ },
303+ },
304+ Data : map [string ]string {
305+ "redis.conf" : redisConf .String (),
306+ },
307+ }
308+
309+ return configMap
310+ }
311+
190312// GenerateRedisPodDef generates a Pod definition for a Redis instance
191313func GenerateRedisPodDef (redisCluster * redisv1beta1.RedisCluster , port int32 , matchMasterNodeID string ) * corev1.Pod {
192314 podName := fmt .Sprintf ("rediscluster-%s-%d" , redisCluster .Name , port )
@@ -196,6 +318,24 @@ func GenerateRedisPodDef(redisCluster *redisv1beta1.RedisCluster, port int32, ma
196318 image = fmt .Sprintf ("%s:%s" , redisCluster .Spec .Image , redisCluster .Spec .Tag )
197319 }
198320
321+ // Build redis-server command
322+ redisCommand := []string {"redis-server" }
323+
324+ // If custom redis config is provided, use ConfigMap mount
325+ if len (redisCluster .Spec .RedisConfig ) > 0 {
326+ redisCommand = append (redisCommand , "/redis-config/redis.conf" )
327+ } else {
328+ // Use default command-line arguments
329+ redisCommand = append (redisCommand ,
330+ "--port" , fmt .Sprintf ("%d" , port ),
331+ "--cluster-enabled" , "yes" ,
332+ "--cluster-port" , fmt .Sprintf ("%d" , port + 10000 ),
333+ "--cluster-node-timeout" , "5000" ,
334+ "--maxmemory" , redisCluster .Spec .Maxmemory ,
335+ "--protected-mode" , "no" ,
336+ )
337+ }
338+
199339 pod := & corev1.Pod {
200340 ObjectMeta : metav1.ObjectMeta {
201341 Name : podName ,
@@ -223,15 +363,7 @@ func GenerateRedisPodDef(redisCluster *redisv1beta1.RedisCluster, port int32, ma
223363 Name : "redis-bus" ,
224364 },
225365 },
226- Command : []string {
227- "redis-server" ,
228- "--port" , fmt .Sprintf ("%d" , port ),
229- "--cluster-enabled" , "yes" ,
230- "--cluster-port" , fmt .Sprintf ("%d" , port + 10000 ),
231- "--cluster-node-timeout" , "5000" ,
232- "--maxmemory" , redisCluster .Spec .Maxmemory ,
233- "--protected-mode" , "no" ,
234- },
366+ Command : redisCommand ,
235367 ReadinessProbe : GenerateRedisProbe (port ),
236368 LivenessProbe : GenerateRedisProbe (port ),
237369 },
@@ -277,6 +409,25 @@ func GenerateRedisPodDef(redisCluster *redisv1beta1.RedisCluster, port int32, ma
277409 pod .Spec .Containers [0 ].Resources = * redisCluster .Spec .Resources
278410 }
279411
412+ // Add ConfigMap volume and mount if custom redis config is provided
413+ if len (redisCluster .Spec .RedisConfig ) > 0 {
414+ configMapName := fmt .Sprintf ("rediscluster-%s-config" , redisCluster .Name )
415+ pod .Spec .Volumes = append (pod .Spec .Volumes , corev1.Volume {
416+ Name : "redis-config" ,
417+ VolumeSource : corev1.VolumeSource {
418+ ConfigMap : & corev1.ConfigMapVolumeSource {
419+ LocalObjectReference : corev1.LocalObjectReference {
420+ Name : configMapName ,
421+ },
422+ },
423+ },
424+ })
425+ pod .Spec .Containers [0 ].VolumeMounts = append (pod .Spec .Containers [0 ].VolumeMounts , corev1.VolumeMount {
426+ Name : "redis-config" ,
427+ MountPath : "/redis-config" ,
428+ })
429+ }
430+
280431 // Add imagePullSecrets if specified
281432 if len (redisCluster .Spec .ImagePullSecrets ) > 0 {
282433 pod .Spec .ImagePullSecrets = redisCluster .Spec .ImagePullSecrets
0 commit comments