@@ -2,13 +2,16 @@ package redis
22
33import (
44 "context"
5+ "crypto/tls"
6+ "crypto/x509"
57 "fmt"
68 "strings"
79
810 commonapi "github.com/OT-CONTAINER-KIT/redis-operator/api/common/v1beta2"
911 rsvb2 "github.com/OT-CONTAINER-KIT/redis-operator/api/redissentinel/v1beta2"
1012 "github.com/OT-CONTAINER-KIT/redis-operator/internal/controller/common"
1113 "github.com/OT-CONTAINER-KIT/redis-operator/internal/service/redis"
14+ "github.com/OT-CONTAINER-KIT/redis-operator/internal/util/cryptutil"
1215 v1 "k8s.io/api/core/v1"
1316 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1417 "k8s.io/apimachinery/pkg/types"
@@ -22,7 +25,7 @@ type Healer interface {
2225 SentinelReset (ctx context.Context , rs * rsvb2.RedisSentinel ) error
2326
2427 // UpdatePodRoleLabel connect to all redis pods and update pod role label `redis-role` to `master` or `slave` according to their role.
25- UpdateRedisRoleLabel (ctx context.Context , ns string , labels map [string ]string , secret * commonapi.ExistingPasswordSecret ) error
28+ UpdateRedisRoleLabel (ctx context.Context , ns string , labels map [string ]string , secret * commonapi.ExistingPasswordSecret , tlsConfig * commonapi. TLSConfig ) error
2629}
2730
2831type healer struct {
@@ -37,7 +40,7 @@ func NewHealer(clientset kubernetes.Interface) Healer {
3740 }
3841}
3942
40- func (h * healer ) UpdateRedisRoleLabel (ctx context.Context , ns string , labels map [string ]string , secret * commonapi.ExistingPasswordSecret ) error {
43+ func (h * healer ) UpdateRedisRoleLabel (ctx context.Context , ns string , labels map [string ]string , secret * commonapi.ExistingPasswordSecret , tlsConfig * commonapi. TLSConfig ) error {
4144 selector := make ([]string , 0 , len (labels ))
4245 for key , value := range labels {
4346 selector = append (selector , fmt .Sprintf ("%s=%s" , key , value ))
@@ -53,11 +56,7 @@ func (h *healer) UpdateRedisRoleLabel(ctx context.Context, ns string, labels map
5356 return err
5457 }
5558 for _ , pod := range pods .Items {
56- connInfo := & redis.ConnectionInfo {
57- IP : pod .Status .PodIP ,
58- Port : "6379" ,
59- Password : password ,
60- }
59+ connInfo := createConnectionInfo (ctx , pod , password , tlsConfig , h .k8s , ns , "6379" )
6160 isMaster , err := h .redis .Connect (connInfo ).IsMaster (ctx )
6261 if err != nil {
6362 return err
@@ -98,11 +97,8 @@ func (h *healer) SentinelReset(ctx context.Context, rs *rsvb2.RedisSentinel) err
9897 }
9998
10099 for _ , pod := range pods .Items {
101- connInfo := & redis.ConnectionInfo {
102- IP : pod .Status .PodIP ,
103- Port : "26379" ,
104- Password : sentinelPass ,
105- }
100+ connInfo := createConnectionInfo (ctx , pod , sentinelPass , rs .Spec .TLS , h .k8s , rs .Namespace , "26379" )
101+
106102 err = h .redis .Connect (connInfo ).SentinelReset (ctx , rs .Spec .RedisSentinelConfig .MasterGroupName )
107103 if err != nil {
108104 return err
@@ -135,13 +131,10 @@ func (h *healer) SentinelMonitor(ctx context.Context, rs *rsvb2.RedisSentinel, m
135131 }
136132
137133 for _ , pod := range pods .Items {
138- connInfo := & redis.ConnectionInfo {
139- IP : pod .Status .PodIP ,
140- Port : "26379" ,
141- Password : sentinelPass ,
142- }
134+ connInfo := createConnectionInfo (ctx , pod , sentinelPass , rs .Spec .TLS , h .k8s , rs .Namespace , "26379" )
135+
143136 masterConnInfo := & redis.ConnectionInfo {
144- IP : master ,
137+ Host : master ,
145138 Port : "6379" ,
146139 Password : masterPass ,
147140 }
@@ -177,3 +170,63 @@ func (h *healer) getSentinelPods(ctx context.Context, rs *rsvb2.RedisSentinel) (
177170 }
178171 return pods , nil
179172}
173+
174+ // getRedisTLSConfig creates a TLS configuration for Redis connections
175+ func getRedisTLSConfig (ctx context.Context , client kubernetes.Interface , namespace , tlsSecretName string ) * tls.Config {
176+ // This is a wrapper to access the k8sutils internal function
177+ // We'll implement a simplified version here for now
178+ secret , err := client .CoreV1 ().Secrets (namespace ).Get (ctx , tlsSecretName , metav1.GetOptions {})
179+ if err != nil {
180+ log .FromContext (ctx ).Error (err , "Failed in getting TLS secret" , "secretName" , tlsSecretName , "namespace" , namespace )
181+ return nil
182+ }
183+
184+ tlsClientCert , certExists := secret .Data ["tls.crt" ]
185+ tlsClientKey , keyExists := secret .Data ["tls.key" ]
186+ tlsCACert , caExists := secret .Data ["ca.crt" ]
187+
188+ if ! certExists || ! keyExists || ! caExists {
189+ log .FromContext (ctx ).Error (fmt .Errorf ("TLS secret missing required keys" ), "TLS secret is missing required keys" , "secretName" , tlsSecretName )
190+ return nil
191+ }
192+
193+ cert , err := tls .X509KeyPair (tlsClientCert , tlsClientKey )
194+ if err != nil {
195+ log .FromContext (ctx ).Error (err , "Failed to load TLS key pair" , "secretName" , tlsSecretName )
196+ return nil
197+ }
198+
199+ caCertPool := x509 .NewCertPool ()
200+ caCertPool .AppendCertsFromPEM (tlsCACert )
201+
202+ return & tls.Config {
203+ Certificates : []tls.Certificate {cert },
204+ RootCAs : caCertPool ,
205+ MinVersion : tls .VersionTLS12 ,
206+ InsecureSkipVerify : true ,
207+ VerifyPeerCertificate : func (rawCerts [][]byte , verifiedChains [][]* x509.Certificate ) error {
208+ _ , _ , err := cryptutil .VerifyCertificateExceptServerName (rawCerts , & tls.Config {RootCAs : caCertPool })
209+ return err
210+ },
211+ }
212+ }
213+
214+ // createConnectionInfo creates a Redis connection info with TLS support
215+ func createConnectionInfo (ctx context.Context , pod v1.Pod , password string , tlsConfig * commonapi.TLSConfig , k8sClient kubernetes.Interface , namespace , port string ) * redis.ConnectionInfo {
216+ connInfo := & redis.ConnectionInfo {
217+ Host : pod .Status .PodIP ,
218+ Port : port ,
219+ Password : password ,
220+ }
221+
222+ // Configure TLS if enabled
223+ if tlsConfig != nil && tlsConfig .Secret .SecretName != "" {
224+ serviceName := common .GetHeadlessServiceNameFromPodName (pod .Name )
225+ connInfo .Host = fmt .Sprintf ("%s.%s.%s.svc.cluster.local" , pod .Name , serviceName , namespace )
226+ // Get TLS configuration
227+ tlsCfg := getRedisTLSConfig (ctx , k8sClient , namespace , tlsConfig .Secret .SecretName )
228+ connInfo .TLSConfig = tlsCfg
229+ }
230+
231+ return connInfo
232+ }
0 commit comments