Support authentication with Redis Sentinel

... so that users can enable authentication in both Redis and Redis
Sentinel.

Change-Id: I3e68e23cf89081cca829d4f78f1d1b35a11d9496
This commit is contained in:
Takashi Kajinami 2024-04-06 20:53:06 +09:00
parent a45f70e938
commit fbe83c8a7b
3 changed files with 42 additions and 4 deletions

View File

@ -0,0 +1,6 @@
---
features:
- |
Now Redis driver supports authentication with Redis Sentinel. To use this
feature, add the ``redis_password`` query to the Redis URI.
The ``redis_username`` can be used when ACL feature is enabled.

View File

@ -85,6 +85,8 @@ class ConnectionURI(object):
# Sentinel # Sentinel
self.master = None self.master = None
self.sentinels = [] self.sentinels = []
self.sentinel_username = query_params.get('sentinel_username')
self.sentinel_password = query_params.get('sentinel_password')
if 'master' in query_params: if 'master' in query_params:
# NOTE(prashanthr_): Configure redis driver in sentinel mode # NOTE(prashanthr_): Configure redis driver in sentinel mode
@ -322,11 +324,12 @@ def _get_redis_client(driver):
db=connection_uri.dbid, db=connection_uri.dbid,
username=connection_uri.username, username=connection_uri.username,
password=connection_uri.password, password=connection_uri.password,
sentinel_kwargs={
'socket_timeout': connection_uri.socket_timeout,
'username': connection_uri.sentinel_username,
'password': connection_uri.sentinel_password
},
socket_timeout=connection_uri.socket_timeout) socket_timeout=connection_uri.socket_timeout)
# NOTE(prashanthr_): The socket_timeout parameter being generic
# to all redis connections is inherited from the parameters for
# sentinel.
return sentinel.master_for(connection_uri.master) return sentinel.master_for(connection_uri.master)
elif connection_uri.strategy == STRATEGY_TCP: elif connection_uri.strategy == STRATEGY_TCP:

View File

@ -337,6 +337,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertIsNone(uri.password) self.assertIsNone(uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI('redis://s1,s2?master=dumbledore') uri = driver.ConnectionURI('redis://s1,s2?master=dumbledore')
self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy) self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)
@ -346,6 +348,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertIsNone(uri.password) self.assertIsNone(uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI('redis://s1:26389,s1?master=dumbledore') uri = driver.ConnectionURI('redis://s1:26389,s1?master=dumbledore')
self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy) self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)
@ -355,6 +359,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertIsNone(uri.password) self.assertIsNone(uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI( uri = driver.ConnectionURI(
'redis://[::1]:26389,[::2]?master=dumbledore') 'redis://[::1]:26389,[::2]?master=dumbledore')
@ -365,6 +371,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertIsNone(uri.password) self.assertIsNone(uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI( uri = driver.ConnectionURI(
'redis://s1?master=dumbledore&socket_timeout=0.5') 'redis://s1?master=dumbledore&socket_timeout=0.5')
@ -375,6 +383,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertIsNone(uri.password) self.assertIsNone(uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI( uri = driver.ConnectionURI(
'redis://:test123@s1?master=dumbledore&socket_timeout=0.5&dbid=5') 'redis://:test123@s1?master=dumbledore&socket_timeout=0.5&dbid=5')
@ -385,6 +395,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(5, uri.dbid) self.assertEqual(5, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertEqual('test123', uri.password) self.assertEqual('test123', uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
# NOTE(tkajinam): Test fallback for backword compatibility # NOTE(tkajinam): Test fallback for backword compatibility
uri = driver.ConnectionURI( uri = driver.ConnectionURI(
@ -396,6 +408,8 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertIsNone(uri.username) self.assertIsNone(uri.username)
self.assertEqual('test123', uri.password) self.assertEqual('test123', uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI( uri = driver.ConnectionURI(
'redis://default:test123@s1?master=dumbledore') 'redis://default:test123@s1?master=dumbledore')
@ -406,6 +420,21 @@ class RedisDriverTest(testing.TestBase):
self.assertEqual(0, uri.dbid) self.assertEqual(0, uri.dbid)
self.assertEqual('default', uri.username) self.assertEqual('default', uri.username)
self.assertEqual('test123', uri.password) self.assertEqual('test123', uri.password)
self.assertIsNone(uri.sentinel_username)
self.assertIsNone(uri.sentinel_password)
uri = driver.ConnectionURI(
'redis://default:test123@s1?master=dumbledore'
'&sentinel_username=sentinel&sentinel_password=test456')
self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)
self.assertEqual([('s1', 26379)], uri.sentinels)
self.assertEqual('dumbledore', uri.master)
self.assertEqual(0.1, uri.socket_timeout)
self.assertEqual(0, uri.dbid)
self.assertEqual('default', uri.username)
self.assertEqual('test123', uri.password)
self.assertEqual('sentinel', uri.sentinel_username)
self.assertEqual('test456', uri.sentinel_password)
@testing.requires_redis @testing.requires_redis