Allow configuring redis to use unix sockets

related: https://github.com/netbox-community/netbox/issues/4377
This commit is contained in:
Evelyn Alicke 2024-03-30 12:33:06 +01:00
parent 699dd72597
commit 886b41a6c1
No known key found for this signature in database
GPG Key ID: 8092413A3F6DD75F
2 changed files with 59 additions and 10 deletions

View File

@ -105,11 +105,11 @@ REDIS = {
### Using Redis Sentinel ### Using Redis Sentinel
If you are using [Redis Sentinel](https://redis.io/topics/sentinel) for high-availability purposes, there is minimal If you are using [Redis Sentinel](https://redis.io/topics/sentinel) for high-availability purposes, there is minimal
configuration necessary to convert NetBox to recognize it. It requires the removal of the `HOST` and `PORT` keys from configuration necessary to convert NetBox to recognize it. It requires the removal of the `HOST` and `PORT` keys from
above and the addition of three new keys. above and the addition of three new keys.
* `SENTINELS`: List of tuples or tuple of tuples with each inner tuple containing the name or IP address * `SENTINELS`: List of tuples or tuple of tuples with each inner tuple containing the name or IP address
of the Redis server and port for each sentinel instance to connect to of the Redis server and port for each sentinel instance to connect to
* `SENTINEL_SERVICE`: Name of the master / service to connect to * `SENTINEL_SERVICE`: Name of the master / service to connect to
* `SENTINEL_TIMEOUT`: Connection timeout, in seconds * `SENTINEL_TIMEOUT`: Connection timeout, in seconds
@ -142,6 +142,36 @@ REDIS = {
!!! note !!! note
It is permissible to use Sentinel for only one database and not the other. It is permissible to use Sentinel for only one database and not the other.
### Using Redis with Unix Sockets
If you'd like to configure NetBox to access Redis over unix sockets, set `PROTO: 'unix'`
Example:
```python
REDIS = {
'tasks': {
'PROTO': 'unix',
'HOST': '/var/run/redis/redis.sock',
'PASSWORD': '',
'USERNAME': '',
}
}
```
Alternatively, you may specify the location string yourself:
```python
REDIS = {
'tasks': {
'LOCATION': 'unix://netbox@/var/run/redis/redis.sock?db=0'
'PASSWORD': '',
}
}
!!! note
the `PASSWORD` option is still provided even when using `LOCATION` directly so you don't have to url-encode your password yourself.
--- ---
## SECRET_KEY ## SECRET_KEY

View File

@ -277,11 +277,14 @@ TASKS_REDIS_DATABASE = TASKS_REDIS.get('DATABASE', 0)
TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False) TASKS_REDIS_SSL = TASKS_REDIS.get('SSL', False)
TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False) TASKS_REDIS_SKIP_TLS_VERIFY = TASKS_REDIS.get('INSECURE_SKIP_TLS_VERIFY', False)
TASKS_REDIS_CA_CERT_PATH = TASKS_REDIS.get('CA_CERT_PATH', False) TASKS_REDIS_CA_CERT_PATH = TASKS_REDIS.get('CA_CERT_PATH', False)
TASKS_REDIS_PROTO = 'rediss' if TASKS_REDIS_SSL else TASKS_REDIS.get('PROTO', 'redis')
TASKS_REDIS_LOCATION_FROM_KEYS = f'unix://{TASKS_REDIS_USERNAME_HOST}?db={TASKS_REDIS_DATABASE}'
TASKS_REDIS_LOCATION = TASKS_REDIS.get('LOCATION', TASKS_REDIS_LOCATION_FROM_KEYS)
# Caching # Caching
if 'caching' not in REDIS: if 'caching' not in REDIS:
raise ImproperlyConfigured( raise ImproperlyConfigured(
"REDIS section in configuration.py is missing caching subsection." "REDIS section in configuration.py is missing 'caching' subsection."
) )
CACHING_REDIS_HOST = REDIS['caching'].get('HOST', 'localhost') CACHING_REDIS_HOST = REDIS['caching'].get('HOST', 'localhost')
CACHING_REDIS_PORT = REDIS['caching'].get('PORT', 6379) CACHING_REDIS_PORT = REDIS['caching'].get('PORT', 6379)
@ -291,18 +294,30 @@ CACHING_REDIS_USERNAME_HOST = '@'.join(filter(None, [CACHING_REDIS_USERNAME, CAC
CACHING_REDIS_PASSWORD = REDIS['caching'].get('PASSWORD', '') CACHING_REDIS_PASSWORD = REDIS['caching'].get('PASSWORD', '')
CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', []) CACHING_REDIS_SENTINELS = REDIS['caching'].get('SENTINELS', [])
CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default') CACHING_REDIS_SENTINEL_SERVICE = REDIS['caching'].get('SENTINEL_SERVICE', 'default')
CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else 'redis' CACHING_REDIS_PROTO = 'rediss' if REDIS['caching'].get('SSL', False) else REDIS['caching'].get('PROTO', 'redis')
CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False) CACHING_REDIS_SKIP_TLS_VERIFY = REDIS['caching'].get('INSECURE_SKIP_TLS_VERIFY', False)
CACHING_REDIS_CA_CERT_PATH = REDIS['caching'].get('CA_CERT_PATH', False) CACHING_REDIS_CA_CERT_PATH = REDIS['caching'].get('CA_CERT_PATH', False)
if CACHING_REDIS_PROTO == 'unix':
CACHING_REDIS_LOCATION_FROM_KEYS = f'unix://{CACHING_REDIS_USERNAME_HOST}?db={CACHING_REDIS_DATABASE}'
elif CACHING_REDIS_PROTO == 'rediss' or CACHING_REDIS_PROTO == 'redis':
CACHING_REDIS_LOCATION_FROM_KEYS = f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_USERNAME_HOST}:{CACHING_REDIS_PORT}/CACHING_REDIS_DATABASE}'
else:
raise ImproperlyConfigured(
"Unknown PROTO for REDIS 'caching' subsection in configuration.py"
)
CACHING_REDIS_LOCATION = REDIS['caching'].get('LOCATION', CACHING_REDIS_LOCATION_FROM_KEYS)
CACHING_REDIS_OPTIONS = {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PASSWORD': CACHING_REDIS_PASSWORD,
}
CACHES = { CACHES = {
'default': { 'default': {
'BACKEND': 'django_redis.cache.RedisCache', 'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': f'{CACHING_REDIS_PROTO}://{CACHING_REDIS_USERNAME_HOST}:{CACHING_REDIS_PORT}/{CACHING_REDIS_DATABASE}', 'LOCATION': CACHING_REDIS_LOCATION,
'OPTIONS': { 'OPTIONS': CACHING_REDIS_OPTIONS,
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PASSWORD': CACHING_REDIS_PASSWORD,
}
} }
} }
@ -687,6 +702,10 @@ if TASKS_REDIS_USING_SENTINEL:
'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT 'socket_connect_timeout': TASKS_REDIS_SENTINEL_TIMEOUT
}, },
} }
elif TASKS_REDIS_LOCATION:
RQ_PARAMS = {
'URL': TASKS_REDIS_LOCATION,
}
else: else:
RQ_PARAMS = { RQ_PARAMS = {
'HOST': TASKS_REDIS_HOST, 'HOST': TASKS_REDIS_HOST,