22Redis client management with support for standalone, cluster, and TLS connections.
33"""
44import time
5+ import ssl
56from typing import Optional , List , Dict , Any , Union
67import redis
78import redis .sentinel
1819from metrics import get_metrics_collector
1920
2021
22+ def _convert_ssl_min_version (version_str : Optional [str ]) -> Optional [ssl .TLSVersion ]:
23+ """Convert string SSL version to ssl.TLSVersion enum."""
24+ if not version_str :
25+ return None
26+
27+ # Mapping of string values to ssl.TLSVersion enum values
28+ version_mapping = {
29+ 'TLSv1' : ssl .TLSVersion .TLSv1 ,
30+ 'TLSv1_1' : ssl .TLSVersion .TLSv1_1 ,
31+ 'TLSv1_2' : ssl .TLSVersion .TLSv1_2 ,
32+ 'TLSv1_3' : ssl .TLSVersion .TLSv1_3 ,
33+ # Also support lowercase variants
34+ 'tlsv1' : ssl .TLSVersion .TLSv1 ,
35+ 'tlsv1_1' : ssl .TLSVersion .TLSv1_1 ,
36+ 'tlsv1_2' : ssl .TLSVersion .TLSv1_2 ,
37+ 'tlsv1_3' : ssl .TLSVersion .TLSv1_3 ,
38+ # Support numeric versions
39+ '1.0' : ssl .TLSVersion .TLSv1 ,
40+ '1.1' : ssl .TLSVersion .TLSv1_1 ,
41+ '1.2' : ssl .TLSVersion .TLSv1_2 ,
42+ '1.3' : ssl .TLSVersion .TLSv1_3 ,
43+ }
44+
45+ if version_str in version_mapping :
46+ return version_mapping [version_str ]
47+ else :
48+ raise ValueError (f"Unsupported SSL version: { version_str } . "
49+ f"Supported versions: { list (version_mapping .keys ())} " )
50+
51+
52+ def _convert_ssl_cert_reqs (cert_reqs : Union [str , int ]) -> Union [ssl .VerifyMode , int ]:
53+ """Convert string cert requirements to ssl.VerifyMode enum."""
54+ if isinstance (cert_reqs , int ):
55+ return cert_reqs
56+
57+ # Mapping of string values to ssl.VerifyMode enum values
58+ cert_reqs_mapping = {
59+ 'none' : ssl .CERT_NONE ,
60+ 'optional' : ssl .CERT_OPTIONAL ,
61+ 'required' : ssl .CERT_REQUIRED ,
62+ # Also support uppercase variants
63+ 'NONE' : ssl .CERT_NONE ,
64+ 'OPTIONAL' : ssl .CERT_OPTIONAL ,
65+ 'REQUIRED' : ssl .CERT_REQUIRED ,
66+ }
67+
68+ if cert_reqs in cert_reqs_mapping :
69+ return cert_reqs_mapping [cert_reqs ]
70+ else :
71+ raise ValueError (f"Unsupported SSL cert requirements: { cert_reqs } . "
72+ f"Supported values: { list (cert_reqs_mapping .keys ())} " )
73+
74+
2175class RedisClient :
2276 """Manages Redis connections with automatic reconnection and error handling."""
2377
@@ -60,13 +114,15 @@ def _build_pool_kwargs(self) -> Dict[str, Any]:
60114 if self .config .ssl :
61115 ssl_kwargs = {'ssl' : True }
62116
117+
118+
63119 # Add SSL parameters directly as redis-py expects them
64120 if self .config .ssl_keyfile is not None :
65121 ssl_kwargs ['ssl_keyfile' ] = self .config .ssl_keyfile
66122 if self .config .ssl_certfile is not None :
67123 ssl_kwargs ['ssl_certfile' ] = self .config .ssl_certfile
68124 if self .config .ssl_cert_reqs is not None :
69- ssl_kwargs ['ssl_cert_reqs' ] = self .config .ssl_cert_reqs
125+ ssl_kwargs ['ssl_cert_reqs' ] = _convert_ssl_cert_reqs ( self .config .ssl_cert_reqs )
70126 if self .config .ssl_ca_certs is not None :
71127 ssl_kwargs ['ssl_ca_certs' ] = self .config .ssl_ca_certs
72128 if self .config .ssl_ca_path is not None :
@@ -78,7 +134,7 @@ def _build_pool_kwargs(self) -> Dict[str, Any]:
78134 if self .config .ssl_password is not None :
79135 ssl_kwargs ['ssl_password' ] = self .config .ssl_password
80136 if self .config .ssl_min_version is not None :
81- ssl_kwargs ['ssl_min_version' ] = self .config .ssl_min_version
137+ ssl_kwargs ['ssl_min_version' ] = _convert_ssl_min_version ( self .config .ssl_min_version )
82138 if self .config .ssl_ciphers is not None :
83139 ssl_kwargs ['ssl_ciphers' ] = self .config .ssl_ciphers
84140
0 commit comments