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>
11 lines
9.1 KiB
YAML
11 lines
9.1 KiB
YAML
---
|
|
# Скопировано из живого ConfigMap кластера ugok (namespace django) —
|
|
# монтируется backend/celery в /opt/sarex/config/settings/production.py.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: django-configmap
|
|
namespace: django
|
|
data:
|
|
production.py: "\nimport os\nfrom .base import *\nfrom logging.handlers import SysLogHandler\nfrom datetime import timedelta\n\nALLOWED_HOSTS = [\"*\"]\nFILE_UPLOAD_PERMISSIONS = 0o644\nDEBUG = False\nCSRF_COOKIE_SECURE = False\nCSRF_TRUSTED_ORIGINS = [\"https://sarex.ugok.lan\",\"http://sarex.ugok.la\", \"*\"]\nSESSION_COOKIE_SECURE = False\nSECURE_SSL_REDIRECT = False\n\nSECRET_KEY = 't2=9+($2f%7ptsdy4!rby$)mcfl1l%o2e@vs^d(g&(wwi&%k1v'\n\nCORS_ORIGIN_ALLOW_ALL = True\nSERVERSETTINGS.cache_enabled = True\nINSTALLED_APPS = list(INSTALLED_APPS) + ['corsheaders']\n\nCORS_ALLOW_METHODS = (\n 'DELETE',\n 'GET',\n 'OPTIONS',\n 'PATCH',\n 'POST',\n 'PUT',\n)\nBASIC_USER_ID = 2\n\nCORS_ALLOW_HEADERS = (\n 'accept',\n 'accept-encoding',\n 'authorization',\n 'content-type',\n 'user-agent',\n 'x-csrftoken',\n 'x-requested-with',\n 'x-token',\n 'Bearer',\n)\n\nHOST = \"https://sarex.ugok.lan\"\n\nPOSTGRES_DATABASE = os.environ.get('DJANGO_POSTGRES_DATABASE')\nPOSTGRES_USER = os.environ.get('DJANGO_POSTGRES_USER')\nPOSTGRES_PASSWORD = os.environ.get('DJANGO_POSTGRES_PASSWORD')\nPOSTGRES_HOST = os.environ.get('DJANGO_POSTGRES_HOST')\nPOSTGRES_PORTS = os.environ.get('DJANGO_POSTGRES_PORTS', \"5432\")\n\nDATABASES = {\n 'default': {\n 'ENGINE': 'django_prometheus.db.backends.postgresql',\n 'NAME': POSTGRES_DATABASE,\n 'USER': POSTGRES_USER,\n 'PASSWORD': POSTGRES_PASSWORD,\n 'HOST': POSTGRES_HOST,\n 'PORT': POSTGRES_PORTS,\n }\n}\n\nLOGGING = {\n 'version': 1,\n 'disable_existing_loggers': False,\n 'filters': {\n 'require_debug_false': {\n '()': 'django.utils.log.RequireDebugFalse',\n }\n },\n 'formatters': {\n 'verbose': {\n 'format': '[contactor] %(levelname)s %(asctime)s %(message)s',\n },\n },\n 'handlers': {\n 'console': {\n 'level': 'DEBUG',\n 'class': 'logging.StreamHandler',\n },\n 'sentry': {\n 'level': 'ERROR',\n 'filters': ['require_debug_false'],\n 'class': 'logging.StreamHandler',\n },\n },\n 'loggers': {\n '': {\n 'handlers': ['console', 'sentry'],\n 'level': 'INFO',\n 'propagate': False,\n },\n }\n}\n\nCOMPARATOR_JWT = os.environ.get(\"COMPARATOR_JWT\", \"default_jwt\")\nCOMPARATOR_URL = os.environ.get(\"COMPARATOR_URL\", \"https://wb.sarex.io/comparator\")\nCOMPARATOR_SECTION = os.environ.get(\"COMPARATOR_SECTION\", \"sarex-production-storage\")\n\nSIMPLE_JWT = {\n 'ACCESS_TOKEN_LIFETIME': timedelta(hours=1),\n 'REFRESH_TOKEN_LIFETIME': timedelta(days=1),\n 'ROTATE_REFRESH_TOKENS': False,\n 'BLACKLIST_AFTER_ROTATION': True,\n 'UPDATE_LAST_LOGIN': False,\n 'ALGORITHM': 'RS512',\n 'SIGNING_KEY': os.environ.get(\"JWT_PRIVATE_KEY\").replace(\"\\\\n\", \"\\n\"),\n 'VERIFYING_KEY': os.environ.get(\"JWT_PUBLIC_KEY\").replace(\"\\\\n\", \"\\n\"),\n 'AUDIENCE': None,\n 'ISSUER': os.environ.get('SIMPLE_JWT_ISSUER', 'default_issuer'),\n 'AUTH_HEADER_TYPES': ('Bearer',),\n 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',\n 'USER_ID_FIELD': 'id',\n 'USER_ID_CLAIM': 'user_id',\n 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),\n 'TOKEN_TYPE_CLAIM': 'token_type',\n 'JTI_CLAIM': 'jti',\n 'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',\n 'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),\n 'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),\n}\n\nos.environ[\"DJANGO_ALLOW_ASYNC_UNSAFE\"] = \"true\"\nDEFAULT_FILE_STORAGE = 'sarex.core.storages.CustomS3Boto3Storage'\nDATA_UPLOAD_MAX_MEMORY_SIZE = 268435456\n\nif not os.environ.get('ISOLATED', False):\n import sentry_sdk\n from sentry_sdk.integrations.django import DjangoIntegration\n\n sentry_sdk.init(\n dsn=\"https://3df2f4b8d3d14595a06c92e9d7c562cb@sentry.io/1501541\",\n integrations=[DjangoIntegration()],\n environment=os.environ.get('SENTRY_ENVIRONMENT', 'production'),\n send_default_pii=True,\n )\n\nCOMPARISON_API_URL = f\"{os.environ.get('WORKFLOWSSETTINGS_HOST')}/comparisons\"\nDOCUMENTATION_API_URL = f\"{os.environ.get('WORKFLOWSSETTINGS_HOST')}/documentations\"\nPDM_FILES_API_URL = f\"{os.environ.get('WORKFLOWSSETTINGS_HOST')}/files\"\n\nWORKFLOWS_TASKS = {\n \"update_orthomosaic_data\": {\n \"image\": f\"{os.environ.get('WORKFLOWSSETTINGS_REGISTRY')}/update-orthomosaic-data:dev\",\n \"service_requests\": [\"django-auth\"],\n \"backoff_limit\": 3,\n },\n}\n\nREST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': (\n 'rest_framework.pagination.LimitOffsetPagination' ),\n 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',\n 'PAGE_SIZE': 1000, 'DEFAULT_FILTER_BACKENDS': [\n 'django_filters.rest_framework.DjangoFilterBackend' ],\n 'DEFAULT_AUTHENTICATION_CLASSES': [\n 'sarex.authentication.backends.ZitadelJWTAuthentication',\n 'rest_framework.authentication.RemoteUserAuthentication',\n 'rest_framework_simplejwt.authentication.JWTAuthentication',\n 'rest_framework.authentication.BasicAuthentication',\n 'rest_framework.authentication.SessionAuthentication',\n 'sarex.authentication.backends.JWTAuthentication' ],\n 'DEFAULT_PERMISSION_CLASSES': [\n 'rest_framework.permissions.IsAuthenticated', ] }\n\nAUTHENTICATION_BACKENDS = [\n 'sarex.authentication.backends.CustomRemoteUserBackend',\n 'django.contrib.auth.backends.ModelBackend',\n 'guardian.backends.ObjectPermissionBackend',\n]\n\nMIDDLEWARE = [\n 'django_prometheus.middleware.PrometheusBeforeMiddleware',\n 'django.middleware.security.SecurityMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'django.middleware.common.CommonMiddleware',\n #'django.middleware.csrf.CsrfViewMiddleware',\n #'django_keycloak.middlewares.AuthorizationHeaderMiddleware',\n #'django_keycloak.middlewares.KeycloakSessionMiddleware',\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n #'django.contrib.auth.middleware.RemoteUserMiddleware',\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n 'django_user_agents.middleware.UserAgentMiddleware',\n 'simple_history.middleware.HistoryRequestMiddleware',\n 'django_prometheus.middleware.PrometheusAfterMiddleware', ]\n\n\nclass KeyCloakSettings(BaseSettings):\n client_id: str = \"client_id\"\n client_secret: str = \"client_secret\"\n discovery_url: str = \"https://login.wb.sarex.io/realms/sarex/.well-known/openid-configuration\"\n staff: Optional[str] = \"Sarex staff\"\n superuser: Optional[str] = \"Sarex superusers\"\n sync_with_django: bool = True\n sync_admin: bool = False\n group_prefix: str = 'Sarex-Role'\n company_prefix: str = 'Sarex-Company'\n department_prefix: str = 'Sarex-Department'\n position_prefix: str = 'Sarex-Position'\n separator: str = '__'\n sync_user_groups: bool = False\n sync_user_positions: bool = False\n sync_user_departments: bool = False\n sync_user_companies: bool = False\n use_redirect_logout: bool = False\n logout_redirect_uri: str = \"/\"\n default_group_name: Optional[str] = 'Тест'\n default_company_name: Optional[str] = 'Брусника'\n trusted_uri: List[str] = ['/api/core/orthophotos/', '/api/token', '/api/token/me']\n trusted_uri: List[str] = []\n\n class Config:\n env_prefix = \"KC_\"\n\n\nKEYCLOAKSETTINGS = KeyCloakSettings()\n\nREMOTE_USER_DEFAULT_COMPANY_ID = 1\nSAREX_MODULES = [\n {\n \"name\": \"Замечания\",\n \"uri\": \"/remarks\"\n },\n {\n \"name\": \"Управление проектами\",\n \"uri\": \"/management/projects\",\n },\n {\n \"name\": \"Замечания V2\",\n \"uri\": \"/issues\"\n },\n {\n \"name\": \"Документация\",\n \"uri\": \"/documentations\",\n },\n {\n \"name\": \"Согласование документов\",\n \"uri\": \"/reviews\"\n },\n {\n \"name\": \"Рабочие процессы\",\n \"uri\": \"/processes\"\n },\n {\n \"name\": \"Запросы\",\n \"uri\": \"/rfi\"\n },\n {\n \"name\": \"Обзор\",\n \"uri\": \"/projects\"\n },\n {\n \"name\": \"Передача документации\", \n \"uri\": \"/transmittal\"\n },\n]\nAUTH_SETTINGS = {\n \"refresh_token\": False,\n \"refresh_token_uri\": \"/api/token/me\",\n \"refresh_oauth_token\": True,\n \"refresh_oauth_token_uri\": \"/oauth/token\",\n \"refresh_time\": 240,\n}\n\n\nDEBUG=False\nWEB_APP_AUTH_MODE='jwt-session-based'\n\n\nSAREX_MODULES_SETTINGS = {\n \"aero\": {\n \"enable_new_media\": True\n },\n \"sso_logout_redirect\": True\n}\n"
|