Skip to content

Commit 6cbc6ad

Browse files
kajinamitsqla-tester
authored andcommitted
redis: Add username
Redis introduced ACL feature in 4.0.0, and this feature is supported by redis-py since 3.4.0[1]. When ACL is enabled, authentication requires username in addition to password. This adds the username argument to Redis backend and Redis Sentinel backend, so that username can be passed in arguments along with password, instead of using client_kwargs and sentinel_kwargs. [1] redis/redis-py@8df8cd5 Closes: #251 Pull-request: #251 Pull-request-sha: 172c195 Change-Id: I4c60316bafca0d600f26b13e867f2b569c1087f5
1 parent 6bf3d05 commit 6cbc6ad

File tree

4 files changed

+49
-9
lines changed

4 files changed

+49
-9
lines changed

docs/build/unreleased/251.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. change::
2+
:tags: usecase, redis
3+
4+
Added new paramref:`.RedisBackend.username` parameter. This is used for
5+
authentication in Redis when RBAC is enabled. Also added new
6+
paramref:`.RedisSentinelBackend.username` parameter, which is used for
7+
authentication in both Redis and Sentinel when RBAC is enabled.

dogpile/cache/backends/redis.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ class RedisBackend(BytesBackend):
4545
Arguments accepted in the arguments dictionary:
4646
4747
:param url: string. If provided, will override separate
48-
host/password/port/db params. The format is that accepted by
48+
host/username/password/port/db params. The format is that accepted by
4949
``StrictRedis.from_url()``.
5050
5151
:param host: string, default is ``localhost``.
5252
53+
:param username: string, default is no username.
54+
5355
:param password: string, default is no password.
5456
5557
:param port: integer, default is ``6379``.
@@ -95,13 +97,16 @@ class RedisBackend(BytesBackend):
9597
9698
.. versionadded:: 1.1.6 Added ``connection_kwargs`` parameter.
9799
100+
.. versionadded:: 1.3.1 Added ``username`` parameter.
101+
98102
"""
99103

100104
def __init__(self, arguments):
101105
arguments = arguments.copy()
102106
self._imports()
103107
self.url = arguments.pop("url", None)
104108
self.host = arguments.pop("host", "localhost")
109+
self.username = arguments.pop("username", None)
105110
self.password = arguments.pop("password", None)
106111
self.port = arguments.pop("port", 6379)
107112
self.db = arguments.pop("db", 0)
@@ -149,6 +154,7 @@ def _create_client(self):
149154
else:
150155
args.update(
151156
host=self.host,
157+
username=self.username,
152158
password=self.password,
153159
port=self.port,
154160
db=self.db,
@@ -247,6 +253,10 @@ class RedisSentinelBackend(RedisBackend):
247253
248254
Arguments accepted in the arguments dictionary:
249255
256+
:param username: string, default is no username.
257+
258+
:param password: string, default is no password.
259+
250260
:param db: integer, default is ``0``.
251261
252262
:param redis_expiration_time: integer, number of seconds after setting
@@ -292,6 +302,8 @@ class RedisSentinelBackend(RedisBackend):
292302
asynchronous runners, as they run in a different thread than the one
293303
used to create the lock.
294304
305+
.. versionadded:: 1.3.1 Added ``username`` parameter.
306+
295307
"""
296308

297309
def __init__(self, arguments):
@@ -317,10 +329,12 @@ def _imports(self):
317329
def _create_client(self):
318330
sentinel_kwargs = {}
319331
sentinel_kwargs.update(self.sentinel_kwargs)
332+
sentinel_kwargs.setdefault("username", self.username)
320333
sentinel_kwargs.setdefault("password", self.password)
321334

322335
connection_kwargs = {}
323336
connection_kwargs.update(self.connection_kwargs)
337+
connection_kwargs.setdefault("username", self.username)
324338
connection_kwargs.setdefault("password", self.password)
325339

326340
if self.db is not None:

tests/cache/test_redis_backend.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,20 +149,22 @@ def test_connect_with_defaults(self, MockStrictRedis):
149149
# The defaults, used if keys are missing from the arguments dict.
150150
arguments = {
151151
"host": "localhost",
152-
"password": None,
153152
"port": 6379,
154153
"db": 0,
155154
}
156-
self._test_helper(MockStrictRedis, arguments, {})
155+
expected = arguments.copy()
156+
expected.update({"username": None, "password": None})
157+
self._test_helper(MockStrictRedis, expected, arguments)
157158

158159
def test_connect_with_basics(self, MockStrictRedis):
159160
arguments = {
160161
"host": "127.0.0.1",
161-
"password": None,
162162
"port": 6379,
163163
"db": 0,
164164
}
165-
self._test_helper(MockStrictRedis, arguments)
165+
expected = arguments.copy()
166+
expected.update({"username": None, "password": None})
167+
self._test_helper(MockStrictRedis, expected, arguments)
166168

167169
def test_connect_with_password(self, MockStrictRedis):
168170
arguments = {
@@ -171,17 +173,34 @@ def test_connect_with_password(self, MockStrictRedis):
171173
"port": 6379,
172174
"db": 0,
173175
}
176+
expected = arguments.copy()
177+
expected.update(
178+
{
179+
"username": None,
180+
}
181+
)
182+
self._test_helper(MockStrictRedis, expected, arguments)
183+
184+
def test_connect_with_username_and_password(self, MockStrictRedis):
185+
arguments = {
186+
"host": "127.0.0.1",
187+
"username": "redis",
188+
"password": "some password",
189+
"port": 6379,
190+
"db": 0,
191+
}
174192
self._test_helper(MockStrictRedis, arguments)
175193

176194
def test_connect_with_socket_timeout(self, MockStrictRedis):
177195
arguments = {
178196
"host": "127.0.0.1",
179197
"port": 6379,
180198
"socket_timeout": 0.5,
181-
"password": None,
182199
"db": 0,
183200
}
184-
self._test_helper(MockStrictRedis, arguments)
201+
expected = arguments.copy()
202+
expected.update({"username": None, "password": None})
203+
self._test_helper(MockStrictRedis, expected, arguments)
185204

186205
def test_connect_with_connection_pool(self, MockStrictRedis):
187206
pool = Mock()

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ deps=
4444
{memcached}: python-memcached
4545
{memcached}: python-binary-memcached>=0.29.0
4646
{memcached}: pymemcache>=3.5.0
47-
{redis}: redis
48-
{redis_sentinel}: redis
47+
{redis}: redis>=3.4.0
48+
{redis_sentinel}: redis>=3.4.0
4949
{cov}: pytest-cov
5050

5151
commands=

0 commit comments

Comments
 (0)