From c7240e1fe12cad6064478aa1aaf3c9794d508485 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Mon, 15 May 2017 13:53:03 +0200 Subject: [PATCH] Allow to use a Redis Sentinel --- cloud_platform/models/cloud_platform.py | 7 +++--- session_redis/http.py | 32 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/cloud_platform/models/cloud_platform.py b/cloud_platform/models/cloud_platform.py index e799b47..5355512 100644 --- a/cloud_platform/models/cloud_platform.py +++ b/cloud_platform/models/cloud_platform.py @@ -116,9 +116,10 @@ class CloudPlatform(models.AbstractModel): "Redis must be activated on prod, integration, test instances." "This is done by setting ODOO_SESSION_REDIS=1." ) - assert os.environ.get('ODOO_SESSION_REDIS_HOST'), ( - "ODOO_SESSION_REDIS_HOST environment variable is required " - "to connect on Redis" + assert (os.environ.get('ODOO_SESSION_REDIS_HOST') or + os.environ.get('ODOO_SESSION_REDIS_SENTINEL_HOST')), ( + "ODOO_SESSION_REDIS_HOST or ODOO_SESSION_REDIS_SENTINEL_HOST " + "environment variable is required to connect on Redis" ) assert os.environ.get('ODOO_SESSION_REDIS_PREFIX'), ( "ODOO_SESSION_REDIS_PREFIX environment variable is required " diff --git a/session_redis/http.py b/session_redis/http.py index e7576fd..1de4b1e 100644 --- a/session_redis/http.py +++ b/session_redis/http.py @@ -17,6 +17,7 @@ _logger = logging.getLogger(__name__) try: import redis + from redis.sentinel import Sentinel except ImportError: redis = None # noqa _logger.debug("Cannot 'import redis'.") @@ -26,8 +27,18 @@ def is_true(strval): return bool(strtobool(strval or '0'.lower())) -host = os.environ.get('ODOO_SESSION_REDIS_HOST') or 'localhost' -port = int(os.environ.get('ODOO_SESSION_REDIS_PORT') or 6379) +sentinel_host = os.environ.get('ODOO_SESSION_REDIS_SENTINEL_HOST') +sentinel_master_name = os.environ.get( + 'ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME' +) +if sentinel_host and not sentinel_master_name: + raise Exception( + "ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME must be defined " + "when using session_redis" + ) +sentinel_port = int(os.environ.get('ODOO_SESSION_REDIS_SENTINEL_PORT', 26379)) +host = os.environ.get('ODOO_SESSION_REDIS_HOST', 'localhost') +port = int(os.environ.get('ODOO_SESSION_REDIS_PORT', 6379)) prefix = os.environ.get('ODOO_SESSION_REDIS_PREFIX') password = os.environ.get('ODOO_SESSION_REDIS_PASSWORD') expiration = os.environ.get('ODOO_SESSION_REDIS_EXPIRATION') @@ -35,7 +46,12 @@ expiration = os.environ.get('ODOO_SESSION_REDIS_EXPIRATION') @lazy_property def session_store(self): - redis_client = redis.Redis(host=host, port=port, password=password) + if sentinel_host: + sentinel = Sentinel([(sentinel_host, sentinel_port)], + password=password) + redis_client = sentinel.master_for(sentinel_master_name) + else: + redis_client = redis.Redis(host=host, port=port, password=password) return RedisSessionStore(redis=redis_client, prefix=prefix, expiration=expiration, session_class=http.OpenERPSession) @@ -60,8 +76,14 @@ def purge_fs_sessions(path): if is_true(os.environ.get('ODOO_SESSION_REDIS')): - _logger.debug("HTTP sessions stored in Redis %s:%s with prefix '%s'", - host, port, prefix or '') + if sentinel_host: + _logger.debug("HTTP sessions stored in Redis with prefix '%s'. " + "Using Sentinel on %s:%s", + sentinel_host, sentinel_port, prefix or '') + else: + _logger.debug("HTTP sessions stored in Redis with prefix '%s' on " + "%s:%s", host, port, prefix or '') + http.Root.session_store = session_store http.session_gc = session_gc # clean the existing sessions on the file system