Redis connection support password configure in zaqar
Redis connection doesn't support password configure in zaqar, so redis-server can not set a password. If redis service doesn't set a password, it will suffer a large number of attacks. The patch will support password configure in zaqar. In addition, it is needed to add unit test in the previous patch[https://review.openstack.org/#/c/511676/]. Change-Id: I03661584f1c24fdb3e76a819c9eaa0ed32f272c4
This commit is contained in:
parent
764bbb97dd
commit
856884641f
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Redis connection doesn't support password configure in zaqar,
|
||||
so redis-server can not set a password. If redis service doesn't
|
||||
set a password, it will suffer a large number of attacks. The
|
||||
patch will support password configure for redis connection in zaqar.
|
4
tox.ini
4
tox.ini
@ -73,9 +73,9 @@ commands =
|
||||
|
||||
[flake8]
|
||||
exclude = .venv*,.git,.tox,dist,doc,*lib/python*,*.egg,.update-venv
|
||||
# NOTE(flaper87): Our currently max-complexity is 15. Not sure what the ideal complexity
|
||||
# NOTE(flaper87): Our currently max-complexity is 20. Not sure what the ideal complexity
|
||||
# for Zaqar should be but lets keep it to the minimum possible.
|
||||
max-complexity = 16
|
||||
max-complexity = 20
|
||||
# [H904] Delay string interpolations at logging calls.
|
||||
enable-extensions=H904
|
||||
|
||||
|
@ -53,6 +53,13 @@ class ConnectionURI(object):
|
||||
path, sep, query = path.partition('?')
|
||||
else:
|
||||
query = parsed_url.query
|
||||
# NOTE(gengchc2): Redis connection support password configure.
|
||||
self.password = None
|
||||
if '@' in path:
|
||||
self.password, sep, path = path.partition('@')
|
||||
netloc = parsed_url.netloc
|
||||
if '@' in netloc:
|
||||
self.password, sep, netloc = netloc.partition('@')
|
||||
|
||||
query_params = dict(urllib.parse.parse_qsl(query))
|
||||
|
||||
@ -80,7 +87,7 @@ class ConnectionURI(object):
|
||||
|
||||
# NOTE(kgriffs): Have to parse list of sentinel hosts ourselves
|
||||
# since urllib doesn't support it.
|
||||
for each_host in parsed_url.netloc.split(','):
|
||||
for each_host in netloc.split(','):
|
||||
name, sep, port = each_host.partition(':')
|
||||
|
||||
if port:
|
||||
@ -101,8 +108,8 @@ class ConnectionURI(object):
|
||||
'sentinel hosts')
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
elif parsed_url.netloc:
|
||||
if ',' in parsed_url.netloc:
|
||||
elif netloc:
|
||||
if ',' in netloc:
|
||||
# NOTE(kgriffs): They probably were specifying
|
||||
# a list of sentinel hostnames, but forgot to
|
||||
# add 'master' to the query string.
|
||||
@ -276,6 +283,8 @@ def _get_redis_client(driver):
|
||||
if connection_uri.strategy == STRATEGY_SENTINEL:
|
||||
sentinel = redis.sentinel.Sentinel(
|
||||
connection_uri.sentinels,
|
||||
db=connection_uri.dbid,
|
||||
password=connection_uri.password,
|
||||
socket_timeout=connection_uri.socket_timeout)
|
||||
|
||||
# NOTE(prashanthr_): The socket_timeout parameter being generic
|
||||
@ -288,8 +297,11 @@ def _get_redis_client(driver):
|
||||
host=connection_uri.hostname,
|
||||
port=connection_uri.port,
|
||||
db=connection_uri.dbid,
|
||||
password=connection_uri.password,
|
||||
socket_timeout=connection_uri.socket_timeout)
|
||||
else:
|
||||
return redis.StrictRedis(
|
||||
unix_socket_path=connection_uri.unix_socket_path,
|
||||
db=connection_uri.dbid,
|
||||
password=connection_uri.password,
|
||||
socket_timeout=connection_uri.socket_timeout)
|
||||
|
@ -25,10 +25,13 @@ _COMMON_REDIS_OPTIONS = (
|
||||
group=_deprecated_group), ],
|
||||
help=('Redis connection URI, taking one of three forms. '
|
||||
'For a direct connection to a Redis server, use '
|
||||
'the form "redis://host[:port][?options]", where '
|
||||
'port defaults to 6379 if not specified. For an '
|
||||
'HA master-slave Redis cluster using Redis Sentinel, '
|
||||
'use the form "redis://host1[:port1]'
|
||||
'the form "redis://[:password]@host[:port][?options]", '
|
||||
'where password is redis-server\'s password, when'
|
||||
'redis-server is set password, the password option'
|
||||
'needs to be set. port defaults to 6379 if not'
|
||||
'specified. For an HA master-slave Redis cluster using'
|
||||
' Redis Sentinel, use the form '
|
||||
'"redis://[:password]@host1[:port1]'
|
||||
'[,host2[:port2],...,hostN[:portN]][?options]", '
|
||||
'where each host specified corresponds to an '
|
||||
'instance of redis-sentinel. In this form, the '
|
||||
@ -37,8 +40,8 @@ _COMMON_REDIS_OPTIONS = (
|
||||
'string as "master=<name>". Finally, to connect '
|
||||
'to a local instance of Redis over a unix socket, '
|
||||
'you may use the form '
|
||||
'"redis:/path/to/redis.sock[?options]". In all '
|
||||
'forms, the "socket_timeout" option may be '
|
||||
'"redis:[:password]@/path/to/redis.sock[?options]".'
|
||||
' In all forms, the "socket_timeout" option may be'
|
||||
'specified in the query string. Its value is '
|
||||
'given in seconds. If not provided, '
|
||||
'"socket_timeout" defaults to 0.1 seconds.'
|
||||
|
@ -244,6 +244,14 @@ class RedisDriverTest(testing.TestBase):
|
||||
self.assertEqual(7777, uri.port)
|
||||
self.assertEqual(1.0, uri.socket_timeout)
|
||||
|
||||
uri = driver.ConnectionURI(
|
||||
'redis://test123@example.com:7777?socket_timeout=1&dbid=5')
|
||||
self.assertEqual(driver.STRATEGY_TCP, uri.strategy)
|
||||
self.assertEqual(7777, uri.port)
|
||||
self.assertEqual(1.0, uri.socket_timeout)
|
||||
self.assertEqual(5, uri.dbid)
|
||||
self.assertEqual('test123', uri.password)
|
||||
|
||||
def test_connection_uri_unix_socket(self):
|
||||
uri = driver.ConnectionURI('redis:/tmp/redis.sock')
|
||||
self.assertEqual(driver.STRATEGY_UNIX, uri.strategy)
|
||||
@ -255,6 +263,14 @@ class RedisDriverTest(testing.TestBase):
|
||||
self.assertEqual('/tmp/redis.sock', uri.unix_socket_path)
|
||||
self.assertEqual(1.5, uri.socket_timeout)
|
||||
|
||||
uri = driver.ConnectionURI(
|
||||
'redis:test123@/tmp/redis.sock?socket_timeout=1.5&dbid=5')
|
||||
self.assertEqual(driver.STRATEGY_UNIX, uri.strategy)
|
||||
self.assertEqual('/tmp/redis.sock', uri.unix_socket_path)
|
||||
self.assertEqual(1.5, uri.socket_timeout)
|
||||
self.assertEqual(5, uri.dbid)
|
||||
self.assertEqual('test123', uri.password)
|
||||
|
||||
def test_connection_uri_sentinel(self):
|
||||
uri = driver.ConnectionURI('redis://s1?master=dumbledore')
|
||||
self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)
|
||||
@ -281,6 +297,15 @@ class RedisDriverTest(testing.TestBase):
|
||||
self.assertEqual('dumbledore', uri.master)
|
||||
self.assertEqual(0.5, uri.socket_timeout)
|
||||
|
||||
uri = driver.ConnectionURI(
|
||||
'redis://test123@s1?master=dumbledore&socket_timeout=0.5&dbid=5')
|
||||
self.assertEqual(driver.STRATEGY_SENTINEL, uri.strategy)
|
||||
self.assertEqual([('s1', 26379)], uri.sentinels)
|
||||
self.assertEqual('dumbledore', uri.master)
|
||||
self.assertEqual(0.5, uri.socket_timeout)
|
||||
self.assertEqual(5, uri.dbid)
|
||||
self.assertEqual('test123', uri.password)
|
||||
|
||||
|
||||
@testing.requires_redis
|
||||
class RedisQueuesTest(base.QueueControllerTest):
|
||||
|
Loading…
Reference in New Issue
Block a user