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>
16 lines
5.3 KiB
YAML
16 lines
5.3 KiB
YAML
---
|
|
# Скопировано из живого ConfigMap кластера ugok (namespace issues) — монтируется
|
|
# backend'ом и celery как /src/config/settings/production.py.
|
|
#
|
|
# ВНИМАНИЕ: в файле буквально зашиты секреты (SECRET_KEY, DJANGO_TOKEN,
|
|
# KAFKA_PASSWORD) и чужой домен brusnika-stage-kafka-bootstrap — копирую
|
|
# как есть, как и договаривались, но это стоит знать: значения не
|
|
# заворачиваются в env/Secret на уровне HelmRelease, они прямо в коде.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: production-configmap
|
|
namespace: issues
|
|
data:
|
|
production.py: "from datetime import timedelta\nimport os\nfrom .base import *\n\n# DEBUG SETTINGS START\n# -----------------------------------------------------------------------------\nDEBUG = True\n# -----------------------------------------------------------------------------\n\nTEST_MODE = False\n\n# SECRETS SETTINGS START\n# -----------------------------------------------------------------------------\n\nAWS_S3_VERIFY=False\nENABLE_MAILGUN=False\nSECRET_KEY = \"FromToMuchLoveOfLiving\" # Delete after Test\n# -----------------------------------------------------------------------------\n\n# ALLOWED HOSTS START\n# -----------------------------------------------------------------------------\nALLOWED_HOSTS = [\"*\"]\n# -----------------------------------------------------------------------------\n\n# APPS SETTINGS START\n# -----------------------------------------------------------------------------\n# INSTALLED_APPS += [\n# \"django_extensions\",\n# ]\n# -----------------------------------------------------------------------------\n\nDJANGO_TOKEN=\"aGFnZW4wMTM6emVhbG90MDk2\"\n\n# DEBUG SETTINGS START\n# -----------------------------------------------------------------------------\nDEBUG = True\n# -----------------------------------------------------------------------------\n\nREVIEW_HOST='http://backend-service.flows.svc.cluster.local:8000'\n# -----------------------------------------------------------------------------\n# EXTERNAL SERVICES END\n\nWORKFLOWS_HOST = \"http://workflows-api-service.workflow.svc.cluster.local:8000\"\nWORKFLOWS_URL = \"http://workflows-api-service.workflow.svc.cluster.local:8000\"\nDOCUMENTATIONS_URL = \"http://documentations-api.documentations.svc.cluster.local:8080\"\nRESOURCES_API_HOST = os.getenv(\"RESOURCES_API_HOST\", default=\"http://resources-service.resources.svc.cluster:8000\")\nKAFKA_HOST = \"brusnika-stage-kafka-bootstrap.kafka.svc.cluster.local:9093\" \nKAFKA_USERNAME = \"sarex\" \nKAFKA_PASSWORD = \"nK36sasvSfoItJnXQ4qxav2OUWIPX5ZC\"\nKAFKA_SSL_CAFILE = os.getenv(\"KAFKA_SSL_CAFILE\", \"/usr/local/share/ca-certificates/kafka.crt\")\nKAFKA_EAV_ASSETS_TOPIC = os.getenv(\"KAFKA_EAV_ASSETS_TOPIC\", \"sarex\")\nKAFKA_ISSUES_TOPIC = os.getenv(\"KAFKA_ISSUES_TOPIC\", \"sarex-issues\")\nSMTP_HOST = 'mail.uchgok.ru'\nSMTP_PORT = 25\nEMAIL_FROM = 'sarex@uchgok.ru'\n\n\nUSE_ASYNC_FUNCTIONS = False\nUSE_NOTIFICATIONS = True\n\n# JWT SETTINGS START\n# ---------------------------------------------------------------------------------------------------------------------\nSIMPLE_JWT_ISSUER = os.getenv(\"SIMPLE_JWT_ISSUER\", default=\"default_issuer\")\n\nSIMPLE_JWT = {\n \"ACCESS_TOKEN_LIFETIME\": timedelta(minutes=5),\n \"REFRESH_TOKEN_LIFETIME\": timedelta(days=1),\n \"ROTATE_REFRESH_TOKENS\": False,\n \"UPDATE_LAST_LOGIN\": False,\n\n \"ALGORITHM\": \"RS512\",\n \"SIGNING_KEY\": os.getenv(\"JWT_PRIVATE_KEY\", default=\"\").replace(\"\\\\n\", \"\\n\"),\n \"VERIFYING_KEY\": os.getenv(\"JWT_PUBLIC_KEY\").replace(\"\\\\n\", \"\\n\"),\n \"AUDIENCE\": None,\n \"ISSUER\": SIMPLE_JWT_ISSUER,\n\n \"AUTH_HEADER_TYPES\": (\"Bearer\",),\n \"AUTH_HEADER_NAME\": \"HTTP_AUTHORIZATION\",\n \"USER_ID_FIELD\": \"id\",\n \"USER_ID_CLAIM\": \"user_id\",\n\n \"AUTH_TOKEN_CLASSES\": (\"rest_framework_simplejwt.tokens.AccessToken\",),\n \"TOKEN_TYPE_CLAIM\": \"token_type\",\n\n \"JTI_CLAIM\": \"jti\",\n\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# ---------------------------------------------------------------------------------------------------------------------\n\nCORS_ALLOWED_ORIGINS = [\n \"https://ugok-sarex.uralmine.com\",\n]\n\nCORS_TRUSTED_ORIGINS = [\n \"https://ugok-sarex.uralmine.com\",\n]\n\nCSRF_TRUSTED_ORIGINS = [\n \"https://ugok-sarex.uralmine.com\",\n]\n\nCORS_ALLOW_ALL_ORIGINS = True\n\nCORS_ALLOW_METHODS = [\n \"DELETE\",\n \"GET\",\n \"OPTIONS\",\n \"PATCH\",\n \"POST\",\n \"PUT\",\n]\n\nSAREX_API = \"http://backend.django.svc.cluster.local:8000\"\n\nAERO_PUBLIC_HOST = os.getenv(\"AERO_PUBLIC_HOST\", default=SAREX_API)\n\nBASE_AERO_URL = \"http://backend.django.svc.cluster.local:8000\"\n\nENVIRONMENT = \"production\"\n\nSESSION_COOKIE_NAME = \"issues-sessionid\"\nCSRF_COOKIE_NAME = \"issues-csrftoken\"\nSTATIC_URL = \"/static/\"\nSTORAGES = {\n 'default': {\n 'BACKEND': \"storages.backends.s3boto3.S3Boto3Storage\",\n },\n 'staticfiles': {\n # Leave whatever setting you already have here, e.g.:\n 'BACKEND': \"storages.backends.s3boto3.S3Boto3Storage\",\n }\n}\n"
|