Skip to content

Commit 70c95d4

Browse files
handles tls min version argument
Signed-off-by: Elena Kolevska <elena@kolevska.com>
1 parent a02fcc4 commit 70c95d4

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def describe_profile(profile_name):
127127
@click.option('--ssl-ca-data', default=lambda: get_env_or_default('REDIS_SSL_CA_DATA', None), help='CA certificate data as string')
128128
@click.option('--ssl-check-hostname', is_flag=True, default=lambda: get_env_or_default('REDIS_SSL_CHECK_HOSTNAME', True, bool), help='Check SSL hostname')
129129
@click.option('--ssl-password', default=lambda: get_env_or_default('REDIS_SSL_PASSWORD', None), help='Password for SSL private key')
130-
@click.option('--ssl-min-version', default=lambda: get_env_or_default('REDIS_SSL_MIN_VERSION', None), help='Minimum SSL/TLS version')
130+
@click.option('--ssl-min-version', default=lambda: get_env_or_default('REDIS_SSL_MIN_VERSION', None), help='Minimum SSL/TLS version (TLSv1, TLSv1_1, TLSv1_2, TLSv1_3 or 1.0, 1.1, 1.2, 1.3)')
131131
@click.option('--ssl-ciphers', default=lambda: get_env_or_default('REDIS_SSL_CIPHERS', None), help='SSL cipher suite')
132132
@click.option('--socket-timeout', type=float, default=lambda: get_env_or_default('REDIS_SOCKET_TIMEOUT', None), help='Socket timeout in seconds')
133133
@click.option('--socket-connect-timeout', type=float, default=lambda: get_env_or_default('REDIS_SOCKET_CONNECT_TIMEOUT', None), help='Socket connect timeout in seconds')

config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import json
88
import importlib.metadata
99
import re
10+
import ssl as ssl_module
1011

1112

1213
def get_redis_version() -> str:
@@ -80,7 +81,6 @@ class RedisConnectionConfig:
8081
username: Optional[str] = None
8182
password: Optional[str] = None
8283
database: int = 0 # Changed from 'db' to match lettuce
83-
use_tls: bool = False # Changed from 'ssl' to match lettuce
8484
verify_peer: bool = False
8585
protocol: int = 3 # 2 for RESP2, 3 for RESP3
8686

@@ -98,7 +98,7 @@ class RedisConnectionConfig:
9898
ssl_ca_data: Optional[str] = None
9999
ssl_check_hostname: bool = True
100100
ssl_password: Optional[str] = None
101-
ssl_min_version: Optional[Any] = None # ssl.TLSVersion
101+
ssl_min_version: Optional[ssl_module.TLSVersion] = None # ssl.TLSVersion
102102
ssl_ciphers: Optional[str] = None
103103

104104
# Connection settings

redis_client.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Redis client management with support for standalone, cluster, and TLS connections.
33
"""
44
import time
5+
import ssl
56
from typing import Optional, List, Dict, Any, Union
67
import redis
78
import redis.sentinel
@@ -18,6 +19,59 @@
1819
from 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+
2175
class 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

Comments
 (0)