57 lines
2.3 KiB
Python
57 lines
2.3 KiB
Python
"""
|
|
Custom PostgreSQL database backend that dynamically reloads credentials from Vault.
|
|
|
|
This wrapper ensures that Django picks up rotated database credentials from Vault
|
|
without requiring a container restart. Credentials are re-read from the Vault agent's
|
|
rendered secret files before each new connection is established.
|
|
"""
|
|
import os
|
|
from django.db.backends.postgresql import base
|
|
|
|
|
|
class DatabaseWrapper(base.DatabaseWrapper):
|
|
"""PostgreSQL wrapper that reloads credentials from Vault secret files."""
|
|
|
|
def get_connection_params(self):
|
|
"""
|
|
Reload credentials from Vault files before connecting.
|
|
|
|
This method is called each time Django establishes a new database connection.
|
|
It reads the latest credentials from /vault/secrets/app.env (maintained by
|
|
Vault agent) and updates the connection parameters.
|
|
|
|
Falls back to environment variables if the Vault secret file is unavailable
|
|
(e.g., in local development).
|
|
"""
|
|
params = super().get_connection_params()
|
|
|
|
# Determine which alias this is (default or admin)
|
|
alias = getattr(self, 'alias', 'default')
|
|
|
|
if alias == 'admin':
|
|
secret_file = '/vault/secrets/admin.env'
|
|
user_var = 'DB_ADMIN_USER'
|
|
password_var = 'DB_ADMIN_PASSWORD'
|
|
else:
|
|
secret_file = '/vault/secrets/app.env'
|
|
user_var = 'DB_USER'
|
|
password_var = 'DB_PASSWORD'
|
|
|
|
# Try to read fresh credentials from Vault agent's rendered file
|
|
try:
|
|
if os.path.exists(secret_file):
|
|
with open(secret_file, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if line.startswith(f'export {user_var}='):
|
|
username = line.split('=', 1)[1].strip().strip('"').strip("'")
|
|
params['user'] = username
|
|
elif line.startswith(f'export {password_var}='):
|
|
password = line.split('=', 1)[1].strip().strip('"').strip("'")
|
|
params['password'] = password
|
|
except (FileNotFoundError, PermissionError, IOError):
|
|
# Fallback to environment variables (local development or error case)
|
|
pass
|
|
|
|
return params
|