--- apiVersion: v1 kind: ConfigMap metadata: name: memelord-settings namespace: memelord-raiko data: settings.py: | """ Django settings for myproject project. """ from pathlib import Path from dotenv import load_dotenv import os import pytz import secrets from django.utils.html import escape from django.utils.translation import gettext_lazy as _ from csp.constants import NONE, SELF, UNSAFE_INLINE, UNSAFE_EVAL load_dotenv() BASE_DIR = Path(__file__).resolve().parent.parent DEBUG = os.environ.get('DEBUG', 'False').lower() in ['true'] VERSION = escape(os.environ.get("VERSION", '')) ENABLE_PUBLIC_FEED = os.environ.get('ENABLE_PUBLIC_FEED', 'False').lower() in ['true', '1', 'yes'] SECRET_KEY = os.environ.get("SECRET_KEY", secrets.token_urlsafe(32)) DOMAIN = "" ALLOWED_HOSTS = ["127.0.0.1", "localhost", "10.*", "172.*", "192.168.*"] CSRF_TRUSTED_ORIGINS = [] DOMAIN = str(os.environ.get("DOMAIN", "localhost")) TRUSTED_PORT = str(os.environ.get("PORT", "8000")) if DOMAIN: domains = DOMAIN.split(',') for domain in domains: domain = domain.strip().rstrip('/').replace('http://', '').replace('https://', '') if domain: ALLOWED_HOSTS.append(domain) CSRF_TRUSTED_ORIGINS.append(f"https://{domain}") if TRUSTED_PORT not in ["80", "443", "8000"]: CSRF_TRUSTED_ORIGINS.append(f"https://{domain}:{TRUSTED_PORT}") CSRF_COOKIE_HTTPONLY = True SESSION_EXPIRE_AT_BROWSER_CLOSE = os.environ.get('SESSION_EXPIRE_AT_BROWSER_CLOSE', 'True').lower() in ['true'] SESSION_COOKIE_AGE = int(os.environ.get('SESSION_COOKIE_AGE', '30')) * 60 SESSION_COOKIE_NAME = 'Session' SESSION_COOKIE_SAMESITE = 'Lax' REDIS_HOST = os.environ.get("REDIS_HOST", "") REDIS_PORT = os.environ.get("REDIS_PORT", "6379") REDIS_DB = os.environ.get("REDIS_DB", "0") REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD", "") if REDIS_HOST: CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_DB}", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": REDIS_PASSWORD if REDIS_PASSWORD else None, "SOCKET_CONNECT_TIMEOUT": 5, "SOCKET_TIMEOUT": 5, "RETRY_ON_TIMEOUT": True, "CONNECTION_POOL_KWARGS": { "max_connections": 50, "retry_on_timeout": True, }, "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor", "IGNORE_EXCEPTIONS": True, }, "KEY_PREFIX": "memelord", "TIMEOUT": 300, } } SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default" else: SESSION_ENGINE = "django.contrib.sessions.backends.db" SECURE_COOKIES = os.environ.get('SECURE_COOKIES', 'False').lower() in ['true'] if SECURE_COOKIES: SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SECURE_HSTS_SECONDS = "31536000" SECURE_HSTS_PRELOAD = True SECURE_HSTS_INCLUDE_SUBDOMAINS = True else: SESSION_COOKIE_SECURE = False CSRF_COOKIE_SECURE = False SECURE_BROWSER_XSS_FILTER = True SECURE_CONTENT_TYPE_NOSNIFF = True X_FRAME_OPTIONS = 'DENY' REFERRER_POLICY = 'same-origin' raw_frame_ancestors = os.environ.get("CSP_FRAME_ANCESTORS", "'none'") FRAME_ANCESTORS = [item.strip() for item in raw_frame_ancestors.split(',') if item.strip()] STORAGE_BACKEND = os.environ.get('STORAGE_BACKEND', 'local').lower() IMG_SRC_LIST = ["'self'", "data:", "blob:", "https://img.logo.dev"] if STORAGE_BACKEND == 's3': AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME') AWS_S3_CUSTOM_DOMAIN = os.environ.get('AWS_S3_CUSTOM_DOMAIN') AWS_S3_REGION_NAME = os.environ.get('AWS_S3_REGION_NAME', 'us-east-1') AWS_S3_ENDPOINT_URL = os.environ.get('AWS_S3_ENDPOINT_URL') AWS_S3_USE_ACCELERATE_ENDPOINT = os.environ.get('AWS_S3_USE_ACCELERATE_ENDPOINT', 'False').lower() in ['true'] if AWS_S3_CUSTOM_DOMAIN: IMG_SRC_LIST.append(f"https://{AWS_S3_CUSTOM_DOMAIN}") if AWS_S3_ENDPOINT_URL: from urllib.parse import urlparse parsed_url = urlparse(AWS_S3_ENDPOINT_URL) endpoint_domain = parsed_url.netloc endpoint_scheme = parsed_url.scheme or 'https' IMG_SRC_LIST.append(f"{endpoint_scheme}://{endpoint_domain}") if endpoint_domain and AWS_STORAGE_BUCKET_NAME: IMG_SRC_LIST.append(f"{endpoint_scheme}://{AWS_STORAGE_BUCKET_NAME}.{endpoint_domain}") else: if AWS_STORAGE_BUCKET_NAME: IMG_SRC_LIST.append(f"https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com") IMG_SRC_LIST.append(f"https://{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com") CSP_IMG_SRC_EXTRA = os.environ.get('CSP_IMG_SRC_EXTRA', '') if CSP_IMG_SRC_EXTRA: extra_domains = [domain.strip() for domain in CSP_IMG_SRC_EXTRA.split(',') if domain.strip()] IMG_SRC_LIST.extend(extra_domains) CONTENT_SECURITY_POLICY = { "DIRECTIVES": { "default-src": ["'self'"], "style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com", "https://cdn.jsdelivr.net"], "script-src": ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://cdn.jsdelivr.net"], "font-src": ["'self'", "https://fonts.googleapis.com", "https://fonts.gstatic.com"], "img-src": IMG_SRC_LIST, "object-src": ["'none'"], "connect-src": ["'self'"], "frame-ancestors": FRAME_ANCESTORS, }, } INSTALLED_APPS = [ 'myapp', 'django_celery_beat', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'csp', 'storages', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django_http_referrer_policy.middleware.ReferrerPolicyMiddleware', 'csp.middleware.CSPMiddleware', ] ROOT_URLCONF = 'myproject.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'myapp/templates/registration')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] DB_ENGINE = os.environ.get("DB_ENGINE", "sqlite3") if DB_ENGINE == "sqlite3": DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'database', 'db.sqlite3'), } } elif DB_ENGINE == "postgres": DB_HOST = os.environ.get("POSTGRES_HOST", "db") DB_PORT = os.environ.get("POSTGRES_PORT", "5432") DB_USER = os.environ.get("POSTGRES_USER", "memelord") DB_PASSWORD = os.environ.get("POSTGRES_PASSWORD", "memelord") DB_NAME = os.environ.get("POSTGRES_DB", "memelord") DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': DB_NAME, 'HOST': DB_HOST, 'PORT': DB_PORT, 'USER': DB_USER, 'PASSWORD': DB_PASSWORD, } } AUTH_PASSWORD_VALIDATORS = [ {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, ] LANGUAGE_CODE = 'en-us' TIME_ZONE = os.environ.get('TZ', 'Europe/Berlin') USE_I18N = True USE_L10N = True USE_TZ = True LANGUAGES = [ ('en', _('English')), ('de', _('German')), ('fr', _('French')), ('it', _('Italian')), ] LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')] LOGS_DIR = os.path.join(BASE_DIR, 'logs') LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '{levelname} {asctime} {module} {message}', 'style': '{', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'verbose', }, }, 'loggers': { 'django': { 'handlers': ['console'], 'level': os.environ.get('DJANGO_LOG_LEVEL', 'INFO'), 'propagate': False, }, 'myapp': { 'handlers': ['console'], 'level': os.environ.get('DJANGO_LOG_LEVEL', 'INFO'), 'propagate': False, }, 'storages': { 'handlers': ['console'], 'level': 'DEBUG' if DEBUG else 'INFO', 'propagate': False, }, 'boto3': { 'handlers': ['console'], 'level': 'DEBUG' if DEBUG else 'INFO', 'propagate': False, }, 'botocore': { 'handlers': ['console'], 'level': 'DEBUG' if DEBUG else 'INFO', 'propagate': False, }, }, 'root': { 'handlers': ['console'], 'level': 'INFO', }, } os.makedirs(LOGS_DIR, exist_ok=True) STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'myapp', 'static') DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' LOGIN_URL = '/accounts/login/' LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = '/post-logout/' ALLOW_LOGOUT_GET_METHOD = True WSGI_APPLICATION = 'myproject.wsgi.application' OIDC_ENABLED = os.environ.get('OIDC_ENABLED', 'False').lower() in ['true'] OIDC_AUTOLOGIN = os.environ.get('OIDC_AUTOLOGIN', 'False').lower() in ['true'] MAX_UPLOAD_SIZE_MB = int(os.environ.get('MAX_UPLOAD_SIZE_MB', '10')) * 1024 * 1024 STORAGE_BACKEND = os.environ.get('STORAGE_BACKEND', 'local').lower() if STORAGE_BACKEND == 's3': AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID') AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY') AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME') AWS_S3_REGION_NAME = os.environ.get('AWS_S3_REGION_NAME', 'us-east-1') AWS_S3_CUSTOM_DOMAIN = os.environ.get('AWS_S3_CUSTOM_DOMAIN') AWS_S3_ENDPOINT_URL = os.environ.get('AWS_S3_ENDPOINT_URL') AWS_DEFAULT_ACL = os.environ.get('AWS_DEFAULT_ACL', 'private') AWS_S3_OBJECT_PARAMETERS = {'CacheControl': 'max-age=86400'} AWS_QUERYSTRING_AUTH = os.environ.get('AWS_QUERYSTRING_AUTH', 'True').lower() in ['true'] AWS_S3_FILE_OVERWRITE = os.environ.get('AWS_S3_FILE_OVERWRITE', 'False').lower() in ['true'] AWS_LOCATION = os.environ.get('AWS_LOCATION', 'media') AWS_S3_SIGNATURE_VERSION = 's3v4' AWS_S3_ADDRESSING_STYLE = 'path' STORAGES = { "default": { "BACKEND": "storages.backends.s3boto3.S3Boto3Storage", }, "staticfiles": { "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", }, } DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' if AWS_S3_CUSTOM_DOMAIN: MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/{AWS_LOCATION}/' elif AWS_STORAGE_BUCKET_NAME: if AWS_S3_REGION_NAME == 'us-east-1': MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com/{AWS_LOCATION}/' else: MEDIA_URL = f'https://{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com/{AWS_LOCATION}/' else: MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" else: STORAGES = { "default": { "BACKEND": "django.core.files.storage.FileSystemStorage", }, "staticfiles": { "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage", }, } DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" if OIDC_ENABLED: OIDC_CREATE_USER = os.environ.get('OIDC_CREATE_USER', 'True').lower() in ['true'] OIDC_RP_SIGN_ALGO = os.environ.get('OIDC_RP_SIGN_ALGO', 'HS256') OIDC_OP_JWKS_ENDPOINT = os.environ.get('OIDC_OP_JWKS_ENDPOINT') OIDC_RP_IDP_SIGN_KEY = os.environ.get('OIDC_RP_IDP_SIGN_KEY') OIDC_RP_CLIENT_ID = os.environ.get('OIDC_RP_CLIENT_ID') OIDC_RP_CLIENT_SECRET = os.environ.get('OIDC_RP_CLIENT_SECRET') OIDC_OP_AUTHORIZATION_ENDPOINT = os.environ.get('OIDC_OP_AUTHORIZATION_ENDPOINT') OIDC_OP_TOKEN_ENDPOINT = os.environ.get('OIDC_OP_TOKEN_ENDPOINT') OIDC_OP_USER_ENDPOINT = os.environ.get('OIDC_OP_USER_ENDPOINT') OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS = float(os.environ.get('OIDC_RENEW_ID_TOKEN_EXPIRY_SECONDS', 900)) OIDC_USERNAME_ALGO = 'myapp.utils.generate_username' INSTALLED_APPS.append('mozilla_django_oidc') AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', 'mozilla_django_oidc.auth.OIDCAuthenticationBackend', ) MIDDLEWARE.append('mozilla_django_oidc.middleware.SessionRefresh') SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") --- apiVersion: apps/v1 kind: Deployment metadata: name: memelord namespace: memelord-raiko spec: replicas: 1 selector: matchLabels: app: memelord template: metadata: labels: app: memelord spec: containers: - name: memelord image: ghcr.io/l4rm4nd/memelord:latest imagePullPolicy: Always ports: - name: http containerPort: 8000 protocol: TCP volumeMounts: - name: settings-override mountPath: /opt/app/myproject/settings.py subPath: settings.py env: - name: DOMAIN value: "memelord-raiko.ee-lte-1.codemowers.io" - name: DB_ENGINE value: "postgres" - name: POSTGRES_USER valueFrom: secretKeyRef: name: memelord-raiko-database key: username - name: POSTGRES_HOST value: "memelord-raiko-database-rw" - name: POSTGRES_PORT value: "5432" - name: POSTGRES_DB value: "memelord-raiko" - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: memelord-raiko-database key: password - name: REDIS_HOST value: "memelord-raiko-redis" - name: REDIS_PORT value: "6379" - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: memelord-raiko-redis key: redis-password - name: STORAGE_BACKEND value: "s3" - name: AWS_STORAGE_BUCKET_NAME value: "memelord-raiko" - name: AWS_S3_ENDPOINT_URL value: "https://minio.ee-lte-1.codemowers.io/" - name: AWS_S3_REGION_NAME value: "ee-lte-1" - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: memelord-raiko-bucket key: accessKey - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: memelord-raiko-bucket key: secretKey - name: OIDC_ENABLED value: "True" - name: OIDC_CREATE_USER value: "True" - name: OIDC_RP_CLIENT_ID valueFrom: secretKeyRef: name: oidc-client-memelord-raiko-owner-secrets key: OIDC_CLIENT_ID - name: OIDC_RP_CLIENT_SECRET valueFrom: secretKeyRef: name: oidc-client-memelord-raiko-owner-secrets key: OIDC_CLIENT_SECRET - name: OIDC_OP_AUTHORIZATION_ENDPOINT value: "https://auth.ee-lte-1.codemowers.io/auth" - name: OIDC_OP_TOKEN_ENDPOINT value: "http://passmower.passmower.svc.cluster.local/token" - name: OIDC_OP_USER_ENDPOINT value: "http://passmower.passmower.svc.cluster.local/me" - name: OIDC_OP_JWKS_ENDPOINT value: "http://passmower.passmower.svc.cluster.local/jwks" - name: OIDC_RP_SIGN_ALGO value: "RS256" - name: OIDC_AUTOLOGIN value: "False" - name: DEBUG value: "True" - name: SECURE_COOKIES value: "True" - name: ENABLE_PUBLIC_FEED value: "True" volumes: - name: settings-override configMap: name: memelord-settings defaultMode: 420