Vale para TODO tenant provisionado: eles nao tem Keycloak proprio, usam este,
um realm cada. O tema vem por ConfigMap e nao por imagem porque o login.ftl traz
as imagens em data URI — o ConfigMap e montado read-only sobre o diretorio e nao
sobra resources/ para o Keycloak servir.
Sem ele o Keycloak monta os links e o iss com o KC_HOSTNAME global
(auth-plataforma), e os runtimes do tenant validam contra ATM_ISSUER, que o
molde define como auth.athleticmap.com. Os dois tem de bater.
Nao da para resolver so no KC_HOSTNAME porque ele e um so e a plataforma
depende do valor antigo. Dai o frontendUrl por realm, que e para isto.
O molde do tenant ja apontava para ca — a SPA em ATM_KC_URL e os tres runtimes
em ATM_ISSUER — e o host nao existia. O navegador batia em
ERR_CERT_AUTHORITY_INVALID e, passando por cima, em 404 do Traefik.
Nao e auth-plataforma para o cliente: o endereco aparece na barra dele durante
o login, e o nome do nosso tenant interno nao tem o que fazer ali.
A etapa BANCO_CRIADO reinicia o PgBouncer e espera ele voltar. Com 5, o backoff
da 155s — menos do que o pod novo levou nas tres medicoes de hoje, e os dois
clientes pagos precisaram de retomada a mao. Com 8 da 515s, dentro da janela.
So o hostname faz o Keycloak resolver esquema e porta a partir da requisicao.
O provisionamento chama a Admin API por dentro (http://keycloak:8080), e o link
do convite saiu http://auth-plataforma.athleticmap.com:8080 — o cliente clicava
e dava ERR_CONNECTION_TIMED_OUT.
O deny-cross-tenant libera 443 para a internet e nada mais. O Keycloak batia em
Network is unreachable na 587, e o erro que chegava ao provisionamento era
Failed to send execute actions email — que manda procurar no SMTP, nao na rede.
db-credentials (a senha do papel) e <tenant>-tls (so a existencia, que e como a
etapa DNS_PUBLICADO sabe que o cert-manager terminou). Por tenant porque o nome
do TLS depende dele e resourceNames nao aceita curinga — e dar get em qualquer
Secret do namespace deixaria o provisionamento ler a chave Asaas DO CLIENTE.
RBAC amarrado por resourceNames (db-credentials nos tenants, pgbouncer-userlist
so aqui), netpol do PgBouncer por ROTULO em vez de por nome, e a credencial de
administracao do Postgres compartilhado para o servico-captacao.
Cliente: Escolinha de Teste
Assinatura: sub_h2dtdvlbt83iq2lg
Plano: (nao informado)
Realm: athleticmap-6
Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
O dominio athleticmap.com tem MX na Hostinger e SPF que so autoriza a
Hostinger. A credencial foi medida: aceita em smtp.hostinger.com:587,
recusada com 535 no Gmail e no Titan.
O molde do realm nunca tinha sido empurrado — PROVISIONAMENTO_REALM_TEMPLATE
estava vazio, e a etapa REALM_CRIADO teria parado nele logo depois do SMTP.
Cliente: (sem nome no pedido)
Assinatura: sub_60id65hukv48tshu
Plano: (nao informado)
Realm: athleticmap-7
Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
Cliente: Escolinha de Teste
Assinatura: sub_h2dtdvlbt83iq2lg
Plano: (nao informado)
Realm: athleticmap-6
Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
Temporario e marcado no proprio arquivo. A venda de teste exercita link,
pagamento, webhook e provisionamento, e nao faz sentido gastar R$ 170 nisso.
Sobreposicao por ambiente: tirar e remover o bloco, sem tocar no codigo.
O publicar_servico_captacao.py escreve o manifesto a partir da copia LOCAL do
athletic-map-deploy, e essa copia esta defasada. Ao subir a tag 1.6 ele levou
junto tudo o que foi ligado hoje no servidor: ASAAS_API_KEY, CAPTACAO_ORIGEM no
dominio novo e as QUATRO credenciais do provisionamento — 56 linhas.
O pod chegou a subir sem elas. E exatamente a divergencia de espelho registrada
hoje de manha, agora com consequencia medida.
Restaurado a partir do commit anterior, com a tag nova aplicada por cima.