# Один раз (и после каждой правки скрипта/списка событий) настраивает Target и Execution'ы в Zitadel. # Spec Job'а неизменяем: Flux пересоздаёт его (force). После ttlSecondsAfterFinished Job удаляется, # и Flux создаёт его заново при следующей сверке — скрипт идемпотентен, повторный запуск ничего не меняет. apiVersion: batch/v1 kind: Job metadata: name: idp-actions-bootstrap annotations: kustomize.toolkit.fluxcd.io/force: enabled spec: backoffLimit: 3 ttlSecondsAfterFinished: 86400 template: metadata: labels: security-audit/job: idp-actions-bootstrap # В mesh: запросы к Zitadel идут с mTLS (п.30). istio-proxy завершает сам скрипт (quitquitquit). sidecar.istio.io/inject: "true" annotations: sidecar.istio.io/inject: "true" proxy.istio.io/config: '{"holdApplicationUntilProxyStarts": true}' spec: serviceAccountName: idp-actions-bootstrap restartPolicy: Never imagePullSecrets: - name: regcred securityContext: runAsNonRoot: true runAsUser: 1001 runAsGroup: 1001 seccompProfile: {type: RuntimeDefault} initContainers: # В registry контура нет образа с curl и jq вместе: jq (1.6, Debian 12) берётся из образа kubectl, # который уже использует setup-Job Zitadel, curl — из образа kafka (тоже Debian 12). # TODO(verify): заменить на один toolbox-образ (generic/base-image), когда он появится. - name: tools image: cr.yandex/crp3ccidau046kdj8g9q/contour/zitadel/kubectl:1.33.4 command: - sh - -c - cp -L /usr/bin/jq /lib/x86_64-linux-gnu/libjq.so.1 /lib/x86_64-linux-gnu/libonig.so.5 /tools/ securityContext: &container-security runAsNonRoot: true readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: [ALL] resources: &resources requests: {cpu: 10m, memory: 32Mi} limits: {cpu: 200m, memory: 128Mi} volumeMounts: - {name: tools, mountPath: /tools} containers: - name: bootstrap image: cr.yandex/crp3ccidau046kdj8g9q/contour/kafka-nn/kafka:4.0.0-debian-12-r10 command: ["sh", "/scripts/idp-actions-bootstrap.sh"] env: # ZITADEL_API и ZITADEL_HOST задаёт оверлей контура. - {name: PATH, value: "/tools:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"} - {name: LD_LIBRARY_PATH, value: /tools} - {name: EVENTS_FILE, value: /config/events.txt} - {name: PAT_FILE, value: /vault/secrets/zitadel-pat} - {name: ISTIO_QUIT_ON_EXIT, value: "true"} - {name: TMPDIR, value: /tmp} securityContext: *container-security resources: *resources volumeMounts: - {name: tools, mountPath: /tools, readOnly: true} - {name: script, mountPath: /scripts, readOnly: true} - {name: events, mountPath: /config, readOnly: true} - {name: tmp, mountPath: /tmp} - {name: zitadel-pat, mountPath: /vault/secrets, readOnly: true} volumes: - {name: tools, emptyDir: {sizeLimit: 16Mi}} - {name: tmp, emptyDir: {medium: Memory, sizeLimit: 16Mi}} # заголовки с PAT — только в памяти - name: script configMap: {name: idp-actions-bootstrap-script} - name: events configMap: {name: idp-actions-bootstrap-events} # PAT machine user'а security-audit-bootstrap — статический Secret (роли в Vault нет). # TODO(verify): имя Secret'а и ключа сверить с созданным в контуре; скрипт читает PAT_FILE=/vault/secrets/zitadel-pat. - name: zitadel-pat secret: secretName: security-audit-kafka items: - {key: zitadel_pat, path: zitadel-pat}