Root cause: apps/*/ugok extended ../base via kustomize patches, but base is vault-native (Vault Agent Injector annotations + serviceAccount + command/args wrapper sourcing /vault/secrets/*). The Vault Agent Injector webhook IS deployed cluster-wide in ugok (infrastructure/vault/ugok), so it actually intercepted these pods — but no per-app Vault roles/secrets were ever provisioned there, so every pod hung in Init. Fix, mirrored from apps/*/wb (which never extends base for these apps): rebuild every affected app as a standalone HelmRelease per service, with no serviceAccount/podAnnotations override and no vault-sourcing wrapper in command/args (dropped entirely, or replaced with the real functional command where base's wrapper did double duty — e.g. celery invocations, pm's `python manage.py migrate`, pdf-markings-amqp's `start-amqp-worker`). Also recreates ConfigMaps that were referenced by name in volumes but never actually captured into the repo (eav, subscriptions, pm, issues, django) — copied verbatim from the cluster dump and verified byte-for-byte against it. Incidental bugs found and fixed along the way: - message-hub was still extending base (missed in an earlier pass). - system-log's patches targeted services.api/services.worker while base uses services.backend for both — would have produced duplicate Deployments per release, one of them permanently vault-broken. - contracts' real container port is 8080, not base's default 8000. - drawings' Service.targetPort (8000) didn't match the real containerPort (8080), breaking routing. - inspections/ugok was missing entirely from this pass. apps/documentations: intentionally left without a redis Deployment even though VALKEY_ADDR now points at one — the cluster dump has no redis in that namespace, so provisioning one is a scope decision, not a bug fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
157 lines
4.1 KiB
YAML
157 lines
4.1 KiB
YAML
---
|
|
# Скопировано из живого ConfigMap кластера ugok (namespace eav) —
|
|
# монтируется backend'ом в /server/config/settings/production.py.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: django-configmap
|
|
namespace: eav
|
|
data:
|
|
production.py: |
|
|
# production.py
|
|
|
|
from .base import *
|
|
from datetime import timedelta
|
|
import os
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
INSTALLED_APPS.append("corsheaders")
|
|
MIDDLEWARE = ["corsheaders.middleware.CorsMiddleware"] + MIDDLEWARE
|
|
|
|
# DEBUG SETTINGS START
|
|
# ---
|
|
|
|
DEBUG = True
|
|
ALLOWED_HOSTS = ['*']
|
|
# ---
|
|
|
|
# DEBUG SETTINGS END
|
|
|
|
# DATABASE SETTINGS START
|
|
# ---
|
|
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.postgresql",
|
|
"NAME": os.getenv("DJANGO_POSTGRES_DATABASE"),
|
|
"USER": os.getenv("DJANGO_POSTGRES_USER"),
|
|
"PASSWORD": os.getenv("DJANGO_POSTGRES_PASSWORD"),
|
|
"HOST": os.getenv("DJANGO_POSTGRES_HOST"),
|
|
"PORT": "5432",
|
|
}
|
|
}
|
|
# ---
|
|
|
|
# DATABASE SETTINGS END
|
|
|
|
# RESPONSE HEADERS START
|
|
# ---
|
|
|
|
CORS_ORIGIN_ALLOW_ALL = True
|
|
|
|
CORS_ALLOWED_ORIGINS = [
|
|
"http://sarex.ugok.lan","https://sarex.ugok.lan"
|
|
]
|
|
|
|
CORS_TRUSTED_ORIGINS = [
|
|
"http://sarex.ugok.lan","https://sarex.ugok.lan"
|
|
]
|
|
|
|
CSRF_TRUSTED_ORIGINS = [
|
|
"http://sarex.ugok.lan","https://sarex.ugok.lan"
|
|
]
|
|
|
|
CORS_ALLOW_METHODS = (
|
|
'DELETE',
|
|
'GET',
|
|
'OPTIONS',
|
|
'PATCH',
|
|
'POST',
|
|
'PUT',
|
|
)
|
|
|
|
CORS_ALLOW_HEADERS = (
|
|
'accept',
|
|
'accept-encoding',
|
|
'authorization',
|
|
'content-type',
|
|
'user-agent',
|
|
'x-csrftoken',
|
|
'x-requested-with',
|
|
'x-token',
|
|
'Bearer'
|
|
)
|
|
# ---
|
|
|
|
# RESPONSE HEADERS END
|
|
|
|
REST_FRAMEWORK = {
|
|
"DEFAULT_PAGINATION_CLASS": (
|
|
"rest_framework.pagination.LimitOffsetPagination"
|
|
),
|
|
"DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema",
|
|
"PAGE_SIZE": 10000,
|
|
"DEFAULT_FILTER_BACKENDS": [
|
|
"django_filters.rest_framework.DjangoFilterBackend"
|
|
],
|
|
"DEFAULT_AUTHENTICATION_CLASSES": [
|
|
# "rest_framework_simplejwt.authentication.JWTAuthentication",
|
|
"rest_framework.authentication.SessionAuthentication",
|
|
"rest_framework.authentication.BasicAuthentication",
|
|
],
|
|
"DEFAULT_PERMISSION_CLASSES": [
|
|
"rest_framework.permissions.AllowAny",
|
|
]
|
|
}
|
|
|
|
# JWT SETTINGS START
|
|
# ---
|
|
|
|
def get_env_variable(var_name, default=None):
|
|
try:
|
|
return os.getenv(var_name, default)
|
|
except KeyError:
|
|
error_msg = f"Set the {var_name} environment variable"
|
|
if default:
|
|
return default
|
|
raise ImproperlyConfigured(error_msg)
|
|
|
|
SIMPLE_JWT_ISSUER = get_env_variable("SIMPLE_JWT_ISSUER", default="django")
|
|
|
|
SIMPLE_JWT = {
|
|
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
|
|
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
|
|
"ROTATE_REFRESH_TOKENS": False,
|
|
"UPDATE_LAST_LOGIN": False,
|
|
|
|
"ALGORITHM": "RS512",
|
|
"SIGNING_KEY": get_env_variable("JWT_PRIVATE_KEY").replace("\\\n", "\n"),
|
|
"VERIFYING_KEY": get_env_variable("JWT_PUBLIC_KEY").replace("\\\n", "\n"),
|
|
"AUDIENCE": None,
|
|
"ISSUER": SIMPLE_JWT_ISSUER,
|
|
|
|
"AUTH_HEADER_TYPES": ("Bearer",),
|
|
"AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
|
|
"USER_ID_FIELD": "id",
|
|
"USER_ID_CLAIM": "user_id",
|
|
|
|
"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
|
|
"TOKEN_TYPE_CLAIM": "token_type",
|
|
|
|
"JTI_CLAIM": "jti",
|
|
|
|
"SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
|
|
"SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
|
|
"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
|
|
}
|
|
# ---
|
|
|
|
# JWT SETTINGS END
|
|
|
|
STATIC_ROOT = '/static/'
|
|
STATIC_URL = '/static/'
|
|
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
|
|
|
|
SESSION_COOKIE_NAME = 'eav-sessionid'
|
|
CSRF_COOKIE_NAME = 'eav-csrftoken'
|