diff --git a/docs/user/settings.rst b/docs/user/settings.rst index 9c20368c..da816f0e 100644 --- a/docs/user/settings.rst +++ b/docs/user/settings.rst @@ -460,6 +460,33 @@ framework. - **Valid Values:** ``True``, ``False``. - **Default:** ``False``. +``REDIS_CACHE_URL`` +~~~~~~~~~~~~~~~~~~~ + +- **Explanation:** Allows freely redefining the Redis database URL for the + Django cache. +- **Valid Values:** STRING. +- **Default:** + ``redis://:@:/0``. + +``CHANNEL_REDIS_URL`` +~~~~~~~~~~~~~~~~~~~~~ + +- **Explanation:** Allows freely redefining the Redis database URL for + Django Channels' layer. +- **Valid Values:** STRING. +- **Default:** + ``redis://:@:/1``. + +``CELERY_BROKER_URL`` +~~~~~~~~~~~~~~~~~~~~~ + +- **Explanation:** Allows freely redefining the Redis database URL for the + Celery broker. +- **Valid Values:** STRING. +- **Default:** + ``redis://:@:/2``. + DJANGO_LOG_LEVEL ~~~~~~~~~~~~~~~~ @@ -1044,6 +1071,13 @@ Misc Services - **Valid Values:** INTEGER. - **Default:** ``6379``. +``REDIS_USER`` +~~~~~~~~~~~~~~ + +- **Explanation:** Redis username, optional. +- **Valid Values:** STRING. +- **Default:** ``""`` (empty string). + ``REDIS_PASS`` ~~~~~~~~~~~~~~ @@ -1051,6 +1085,13 @@ Misc Services - **Valid Values:** STRING. - **Default:** ``None``. +``REDIS_USE_TLS`` +~~~~~~~~~~~~~~~~~ + +- **Explanation:** Whether to use TLS for redis connection. +- **Valid Values:** ``True``, ``False``. +- **Default:** ``False``. + ``DASHBOARD_APP_SERVICE`` ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/images/common/openwisp/settings.py b/images/common/openwisp/settings.py index 0260bde1..42b7beea 100644 --- a/images/common/openwisp/settings.py +++ b/images/common/openwisp/settings.py @@ -2,6 +2,7 @@ import logging import os import sys +from urllib.parse import quote import tldextract from openwisp.utils import ( @@ -138,17 +139,27 @@ REDIS_HOST = os.environ["REDIS_HOST"] REDIS_PORT = os.environ.get("REDIS_PORT", 6379) +REDIS_USER = os.environ.get("REDIS_USER") REDIS_PASS = os.environ.get("REDIS_PASS") +REDIS_SCHEME = ( + "rediss" if env_bool(os.environ.get("REDIS_USE_TLS", "False")) else "redis" +) -if not REDIS_PASS: - CHANNEL_REDIS_HOST = f"redis://{REDIS_HOST}:{REDIS_PORT}/1" -else: - CHANNEL_REDIS_HOST = f"redis://:{REDIS_PASS}@{REDIS_HOST}:{REDIS_PORT}/1" +# Build base Redis URL -if not REDIS_PASS: - CELERY_BROKER_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}/2" +if REDIS_USER and REDIS_PASS: + credentials = f"{quote(REDIS_USER)}:{quote(REDIS_PASS)}@" +elif REDIS_PASS: + # Password only + credentials = f":{quote(REDIS_PASS)}@" else: - CELERY_BROKER_URL = f"redis://:{REDIS_PASS}@{REDIS_HOST}:{REDIS_PORT}/2" + credentials = "" +REDIS_BASE_URL = f"{REDIS_SCHEME}://{credentials}{REDIS_HOST}:{REDIS_PORT}" + +REDIS_CACHE_URL = os.environ.get("REDIS_CACHE_URL", f"{REDIS_BASE_URL}/0") +CHANNEL_REDIS_HOST = os.environ.get("CHANNEL_REDIS_URL", f"{REDIS_BASE_URL}/1") +CELERY_BROKER_URL = os.environ.get("CELERY_BROKER_URL", f"{REDIS_BASE_URL}/2") + CELERY_TASK_ACKS_LATE = True CELERY_WORKER_PREFETCH_MULTIPLIER = 1 CELERY_BROKER_TRANSPORT_OPTIONS = {"max_retries": 10} @@ -203,7 +214,7 @@ CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", - "LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}/0", + "LOCATION": REDIS_CACHE_URL, "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", }, diff --git a/images/common/services.py b/images/common/services.py index 8569e7bd..ce962bbd 100644 --- a/images/common/services.py +++ b/images/common/services.py @@ -47,12 +47,19 @@ def dashboard_status(): def redis_status(): kwargs = {} + redis_user = os.environ.get("REDIS_USER") redis_pass = os.environ.get("REDIS_PASS") redis_port = os.environ.get("REDIS_PORT", 6379) + redis_use_tls = os.environ.get("REDIS_USE_TLS", "False").lower() == "true" + + if redis_user: + kwargs["username"] = redis_user if redis_pass: kwargs["password"] = redis_pass if redis_port: kwargs["port"] = redis_port + if redis_use_tls: + kwargs["ssl"] = redis_use_tls rs = redis.Redis(os.environ["REDIS_HOST"], **kwargs) try: rs.ping()