Some checks failed
Docker Build / build-and-push-image (push) Has been cancelled
Adds the async dispatch infrastructure : - Postgres pool + embedded migration (CREATE TABLE/INDEX IF NOT EXISTS gateway_jobs). Auto-applied at boot. lib/pq driver (matches webapp convention). - queue.go : Enqueue (idempotent on UNIQUE(bot_slug, update_id) — handles Telegram redelivery), Pop with FOR UPDATE SKIP LOCKED, MarkDone, MarkFailed with exponential backoff (30s → 2m → 10m → 1h → dead at 5). - worker.go : goroutine that drains the queue, dispatches via the same Handler interface as sync, schedules retries on failure, notifies the user once when a job goes to dead. - BotConfig gains `async: bool`. Registry refuses bots with async=true if DATABASE_URL is unset (queue=nil). - Server : when bot.Async, the webhook ack is immediate ; the update payload is enqueued for the worker. When DATABASE_URL is unset (current default), queue/worker stay disabled and only sync handlers (echo, http, auth) work — no breaking change to the running cluster. Refs ~/.claude/plans/pour-les-notifications-on-inherited-seal.md § Phase 2.
135 lines
3.7 KiB
YAML
135 lines
3.7 KiB
YAML
replicaCount: 1
|
|
|
|
image:
|
|
repository: gitea.arcodange.lab/arcodange/telegram-gateway
|
|
pullPolicy: Always
|
|
# Le registry ne produit que :latest et la branch ref (:main) via le
|
|
# workflow Gitea Actions ; appVersion (0.1.0) n'existe pas comme tag.
|
|
# Image Updater écrira ensuite le digest réel dans le manifest in-cluster.
|
|
tag: "latest"
|
|
|
|
imagePullSecrets: []
|
|
nameOverride: ""
|
|
fullnameOverride: ""
|
|
|
|
serviceAccount:
|
|
create: true
|
|
automount: true
|
|
annotations: {}
|
|
name: ""
|
|
|
|
podAnnotations: {}
|
|
podLabels: {}
|
|
|
|
podSecurityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65532
|
|
runAsGroup: 65532
|
|
fsGroup: 65532
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
|
|
securityContext:
|
|
readOnlyRootFilesystem: true
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
|
|
service:
|
|
type: ClusterIP
|
|
port: 8080
|
|
|
|
# Public exposure via Traefik. Cloudflare routes *.arcodange.fr to the home lab
|
|
# already, so we just declare the hostname here. CF terminates TLS, Traefik
|
|
# receives plain HTTP on entrypoint `web`.
|
|
ingress:
|
|
enabled: true
|
|
className: ""
|
|
annotations:
|
|
traefik.ingress.kubernetes.io/router.entrypoints: web
|
|
traefik.ingress.kubernetes.io/router.middlewares: kube-system-crowdsec@kubernetescrd
|
|
hosts:
|
|
- host: tg.arcodange.fr
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
tls: []
|
|
|
|
resources:
|
|
limits:
|
|
cpu: 200m
|
|
memory: 256Mi
|
|
requests:
|
|
cpu: 50m
|
|
memory: 64Mi
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: http
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /readyz
|
|
port: http
|
|
|
|
autoscaling:
|
|
enabled: false
|
|
minReplicas: 1
|
|
maxReplicas: 3
|
|
targetCPUUtilizationPercentage: 80
|
|
|
|
# Bot routing config — non-secret, becomes the bots.yaml ConfigMap entry.
|
|
# Tokens & secret_token values live in a k8s Secret named `secret.name`.
|
|
#
|
|
# Auth gate (Phase 1.5, ADR factory/doc/adr/20260509-telegram-gateway-auth.md):
|
|
# - `requireAuth` defaults to **true** (secure by default). Add
|
|
# `requireAuth: false` only for bots you want to expose publicly.
|
|
# - For `handler: auth`, requireAuth is auto-forced to false (the auth bot
|
|
# can't gate itself or no one could ever authenticate).
|
|
bots:
|
|
factory:
|
|
handler: auth # principal bot — gère /auth, /whoami, /logout
|
|
# Exemple d'un bot gated (défaut) :
|
|
# pingbot:
|
|
# handler: echo
|
|
#
|
|
# Exemple d'un bot public (opt-out explicite) :
|
|
# statusbot:
|
|
# handler: echo
|
|
# requireAuth: false
|
|
|
|
# Auth layer (Phase 1.5). REDIS_URL est passé en env clair (non secret).
|
|
# AUTH_SECRET et ALLOWED_USERS doivent vivre dans le Secret k8s `secret.name`.
|
|
auth:
|
|
redisURL: "redis://redis.tools.svc.cluster.local:6379/0"
|
|
sessionTTL: "24h"
|
|
|
|
# Async queue (Phase 2b). Quand DATABASE_URL est dans le Secret cluster,
|
|
# la queue Postgres + worker s'activent ; sinon tout reste sync (les bots
|
|
# avec `async: true` font fail au boot — secure by default).
|
|
# Format DSN attendu : postgres://USER:PASSWORD@pgbouncer.tools:6432/DBNAME?sslmode=disable
|
|
# L'utilisateur doit avoir CREATE TABLE / CREATE INDEX sur la base cible
|
|
# (le pod auto-applique les migrations idempotentes au démarrage).
|
|
|
|
# k8s Secret consumed by `envFrom`. Phase 1: create it manually with kubectl.
|
|
# kubectl -n telegram-gateway create secret generic telegram-gateway-bots \
|
|
# --from-literal=BOT_FACTORY_TOKEN=… --from-literal=BOT_FACTORY_SECRET=…
|
|
secret:
|
|
name: telegram-gateway-bots
|
|
|
|
# Vault Secrets Operator integration (Phase 2+). When enabled, VSO writes the
|
|
# secret named `secret.name` automatically from `kvv2/telegram-gateway/config`.
|
|
vault:
|
|
enabled: false
|
|
role: telegram-gateway
|
|
mount: kvv2
|
|
path: telegram-gateway/config
|
|
refreshAfter: 30s
|
|
|
|
nodeSelector:
|
|
kubernetes.io/hostname: pi1
|
|
|
|
tolerations: []
|
|
affinity: {}
|