From ed0636dc27e749bc1a766104957d0b5c18194a5d Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Wed, 26 May 2021 10:00:02 +0200 Subject: [PATCH] redis cache - better parsing of connection uri (#2579) (#2622) * better parsing of connection uri * added changelog fragment * fixed tests for ansible 2.9 * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein * Adjustments from PR * Update test_redis.py * Update test_redis.py * Update plugins/cache/redis.py Co-authored-by: Felix Fontein * Update plugins/cache/redis.py Co-authored-by: Felix Fontein * Update tests/unit/plugins/cache/test_redis.py Co-authored-by: Felix Fontein Co-authored-by: Felix Fontein (cherry picked from commit 4764a5deba6b44c988ab21b1b8b2951e71b8499b) Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --- changelogs/fragments/2579-redis-cache-ipv6.yml | 2 ++ plugins/cache/redis.py | 14 ++++++++++++-- tests/unit/plugins/cache/test_redis.py | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/2579-redis-cache-ipv6.yml diff --git a/changelogs/fragments/2579-redis-cache-ipv6.yml b/changelogs/fragments/2579-redis-cache-ipv6.yml new file mode 100644 index 0000000000..aaa5e78b34 --- /dev/null +++ b/changelogs/fragments/2579-redis-cache-ipv6.yml @@ -0,0 +1,2 @@ +bugfixes: + - redis cache - improved connection string parsing (https://github.com/ansible-collections/community.general/issues/497). diff --git a/plugins/cache/redis.py b/plugins/cache/redis.py index 7a376d6d7c..6af7c731e4 100644 --- a/plugins/cache/redis.py +++ b/plugins/cache/redis.py @@ -61,6 +61,7 @@ DOCUMENTATION = ''' type: integer ''' +import re import time import json @@ -91,6 +92,8 @@ class CacheModule(BaseCacheModule): performance. """ _sentinel_service_name = None + re_url_conn = re.compile(r'^([^:]+|\[[^]]+\]):(\d+):(\d+)(?::(.*))?$') + re_sent_conn = re.compile(r'^(.*):(\d+)$') def __init__(self, *args, **kwargs): uri = '' @@ -130,11 +133,18 @@ class CacheModule(BaseCacheModule): self._db = self._get_sentinel_connection(uri, kw) # normal connection else: - connection = uri.split(':') + connection = self._parse_connection(self.re_url_conn, uri) self._db = StrictRedis(*connection, **kw) display.vv('Redis connection: %s' % self._db) + @staticmethod + def _parse_connection(re_patt, uri): + match = re_patt.match(uri) + if not match: + raise AnsibleError("Unable to parse connection string") + return match.groups() + def _get_sentinel_connection(self, uri, kw): """ get sentinel connection details from _uri @@ -158,7 +168,7 @@ class CacheModule(BaseCacheModule): except IndexError: pass # password is optional - sentinels = [tuple(shost.split(':')) for shost in connections] + sentinels = [self._parse_connection(self.re_sent_conn, shost) for shost in connections] display.vv('\nUsing redis sentinels: %s' % sentinels) scon = Sentinel(sentinels, **kw) try: diff --git a/tests/unit/plugins/cache/test_redis.py b/tests/unit/plugins/cache/test_redis.py index e665826769..ee7e1f7913 100644 --- a/tests/unit/plugins/cache/test_redis.py +++ b/tests/unit/plugins/cache/test_redis.py @@ -23,10 +23,23 @@ import pytest pytest.importorskip('redis') +from ansible import constants as C from ansible.plugins.loader import cache_loader +from ansible.release import __version__ as ansible_version from ansible_collections.community.general.plugins.cache.redis import CacheModule as RedisCache def test_redis_cachemodule(): # The _uri option is required for the redis plugin - assert isinstance(cache_loader.get('community.general.redis', **{'_uri': '127.0.0.1:6379:1'}), RedisCache) + connection = '127.0.0.1:6379:1' + if ansible_version.startswith('2.9.'): + C.CACHE_PLUGIN_CONNECTION = connection + assert isinstance(cache_loader.get('community.general.redis', **{'_uri': connection}), RedisCache) + + +def test_redis_cachemodule(): + # The _uri option is required for the redis plugin + connection = '[::1]:6379:1' + if ansible_version.startswith('2.9.'): + C.CACHE_PLUGIN_CONNECTION = connection + assert isinstance(cache_loader.get('community.general.redis', **{'_uri': connection}), RedisCache)