feat(tenants): cria tenant escolinha (silo completo, paridade com os demais)
- tenants/escolinha gerado a partir de acme (todos os servicos + backend + keycloak + postgres + backup + monitoring + garmin) - SealedSecrets db-credentials/keycloak-admin re-selados para escolinha-prod (senhas novas) - garmin-oauth criado em escolinha-prod (out-of-band) - host escolinha.athleticmap.influxdigital.com.br (DNS wildcard + TLS via cert-manager)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# Silo "demo" — isolamento do tenant (namespace + quota + limites + rede)
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: escolinha-prod
|
||||
labels:
|
||||
name: escolinha-prod
|
||||
tenant: escolinha
|
||||
athleticmap.io/tier: pilot
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: tenant-quota
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "4"
|
||||
requests.memory: 6Gi
|
||||
limits.cpu: "20"
|
||||
limits.memory: 16Gi
|
||||
pods: "30"
|
||||
persistentvolumeclaims: "4"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: LimitRange
|
||||
metadata:
|
||||
name: defaults
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
limits:
|
||||
- type: Container
|
||||
default:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
defaultRequest:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: deny-cross-tenant
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes: [Ingress, Egress]
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector: {}
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
egress:
|
||||
- to: # intra-namespace (pods) + ClusterIPs (VIP de service, pre-DNAT)
|
||||
- podSelector: {}
|
||||
- ipBlock: { cidr: 10.43.0.0/16 }
|
||||
- to: # DNS (CoreDNS em kube-system)
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: kube-system
|
||||
ports:
|
||||
- { protocol: UDP, port: 53 }
|
||||
- { protocol: TCP, port: 53 }
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
apiVersion: bitnami.com/v1alpha1
|
||||
kind: SealedSecret
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: db-credentials
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
encryptedData:
|
||||
password: AgB2QaOuIFLe3rxIFaZ/ppM9uV/6waytab4xqGJ81bKkoxDKZJ4ls4Wdw1nOoRemFC75uJMSfdC1S9on+kbN54mvEjpuvZY6jHEKT4LBWPGl+KiHnKZJyqNil90cSBrT7ZpaPJC6FvLkOuENJHipfnsvcyAnuX1Udqbbc6uIjm7Yb9DPg+RGRTjD4j2Wcid7JrA7AhK8cePUO3a5ZDDdCOwqVHS1Z3KYuSmZ5HW4F/NnAU86cgkYUrCRm7Uc+DzRfoBJErW6EIpg+lkDIW2yMVHP/zYhi69E7gDwYtiBN2tdi/9qjLK/oCQYEHCeqqClyUefmjcwu5K3olsRAMxf1TfH/1VRPM+Kk7BcNa7uf6UN/X6kcTN487HskHVMzVK0DFRlysODqoZIOGfstcEzga+FncyC6xXVMOaYczn8a4cQLHpnX5Dzq4tHeBUf0xxMeYDwZzr54Euzfz6t3Hp/zLz97PO5HF8rHKhFEjfr4AEyyvPW73+eG+PDg2P/hUpRXueBimntpXGBEEob1ZJCiDt44KUVLgVFDUV6YeBtN3kNJc58jv4hZmZdPdpRLhTmlFsTYOHU8HrMlegyJOiQstGWQF1AYeJAfe3WtwZ+LHBCb3rxCC4nyKh+nFgkxU2LmJaWmPCo8FCWKUzG1bBI4lzxwI2oKa/mlWbjhIdjcdcU114gcT0+h5MbqfKtZoJKxiwRYDEH679SZE2/tZe5cfi19TuzC4YUFDiBUXCj
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: db-credentials
|
||||
namespace: escolinha-prod
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
apiVersion: bitnami.com/v1alpha1
|
||||
kind: SealedSecret
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: keycloak-admin
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
encryptedData:
|
||||
password: AgCpLPi/GqPeAFKad4SOaYFbpPQwQdXYcwWlKcrOby5fyzXBiBwau0BOrIAcOjbThzNrrFUsg8FxnFPBfdvfosW+aRpwoQSWoiJQ4/qfLYINZD9NWzCWAzQDvcnK1wqyODw5RmD/ugQK3g7ZWhvKys7lrjfyQQGldowMK1+XIpoJuC5sAVLldyJ08kBxp7mtKH/Xfb5rWMalmqk4PwueCkZFI65FkCxI/gAlq8inrtYWVrtNYHe1nTGfmbZfRGmbllTa+wuctUjs6SMJ2zj7fislgh2uv+Ihl2e4TOAoqC8ZreCknRL/ym9H6Pqa5lOhQqpfT1GOFrRH7PEXiQql55nczz44jUq4iplXFY3EvVd6hK06itw3eLSlLGhXPeRrOJuUB0DJSFR6nYOqXguMMcMYB/lpuYpxRRocVCygE2snIadTK2DIWxQ0XJhKwxwBcvO2N8r2hVJxgABlVecnErzVodeS6D53JiosP921MefUHQOPZtrql86AFjihdc2gZJF6N54bNOXRt5bP11zyHDLGBzIAWbdXvSVTRZ+i5tUHib2gnvdsLfD2gdgvorzbkcXtgI6IKdd4SaO/yxuS4sgtMJ5FxSkbvyNUw5k/NWmuHsifENMbsZG0laWnkHpqW3Vxzq+dJsdUm4wIyS0vdDxQSbyPy+ZF4CRyYqgE9+2cw6EF5WDA9iaMjfjJVND5Xr7cZG09GF96o+MgAVrDW1KFaEgAkAncHXuwULt4
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: keycloak-admin
|
||||
namespace: escolinha-prod
|
||||
@@ -0,0 +1,84 @@
|
||||
# PostgreSQL dedicado do tenant demo (banco da aplicação + banco do Keycloak)
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: pg-initdb
|
||||
namespace: escolinha-prod
|
||||
data:
|
||||
01-keycloak.sql: |
|
||||
CREATE DATABASE keycloak;
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: postgres-data
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: local-path
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:16
|
||||
args: ["-c", "max_connections=300"]
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: athleticmap
|
||||
- name: POSTGRES_USER
|
||||
value: atm
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: password
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
- name: initdb
|
||||
mountPath: /docker-entrypoint-initdb.d
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["pg_isready", "-U", "atm", "-d", "athleticmap"]
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-data
|
||||
- name: initdb
|
||||
configMap:
|
||||
name: pg-initdb
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
selector:
|
||||
app: postgres
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
@@ -0,0 +1,86 @@
|
||||
# Keycloak dedicado do tenant demo (IdP do silo) — modo dev, persistindo no Postgres
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: keycloak
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: keycloak
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: keycloak
|
||||
spec:
|
||||
containers:
|
||||
- name: keycloak
|
||||
image: quay.io/keycloak/keycloak:26.0
|
||||
args: ["start-dev", "--import-realm"]
|
||||
env:
|
||||
- name: KC_DB
|
||||
value: postgres
|
||||
- name: KC_DB_URL
|
||||
value: "jdbc:postgresql://postgres:5432/keycloak"
|
||||
- name: KC_DB_USERNAME
|
||||
value: atm
|
||||
- name: KC_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: password
|
||||
- name: KC_BOOTSTRAP_ADMIN_USERNAME
|
||||
value: admin
|
||||
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: keycloak-admin
|
||||
key: password
|
||||
- name: KC_HEALTH_ENABLED
|
||||
value: "true"
|
||||
- name: KC_HTTP_ENABLED
|
||||
value: "true"
|
||||
- name: KC_PROXY_HEADERS
|
||||
value: xforwarded
|
||||
- name: KC_HOSTNAME
|
||||
value: "auth-escolinha.athleticmap.influxdigital.com.br"
|
||||
- name: KC_HOSTNAME_STRICT
|
||||
value: "true"
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
- containerPort: 9000
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 1Gi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: 9000
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
failureThreshold: 40
|
||||
volumeMounts:
|
||||
- name: realm-import
|
||||
mountPath: /opt/keycloak/data/import
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: realm-import
|
||||
configMap:
|
||||
name: kc-realm-import
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: keycloak
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
selector:
|
||||
app: keycloak
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
@@ -0,0 +1,75 @@
|
||||
# Apps do tenant escolinha:
|
||||
# - backend: Spring Boot OAuth2 Resource Server (imagem athletic-map-backend:1.0, importada no k3s)
|
||||
# - frontend: SPA OIDC Authorization Code + PKCE (keycloak-js) chamando /api/me
|
||||
# - bff: stub (whoami) — sera substituido na evolucao
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: backend, namespace: escolinha-prod, labels: { app: backend } }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: backend } }
|
||||
template:
|
||||
metadata: { labels: { app: backend } }
|
||||
spec:
|
||||
containers:
|
||||
- name: backend
|
||||
image: docker.io/library/athletic-map-backend:1.3
|
||||
imagePullPolicy: Never
|
||||
env:
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
ports: [{ containerPort: 8083 }]
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/public/health, port: 8083 }
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 10
|
||||
failureThreshold: 24
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: backend, namespace: escolinha-prod, labels: { app: backend } }
|
||||
spec:
|
||||
selector: { app: backend }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: escolinha
|
||||
namespace: escolinha-prod
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
traefik.ingress.kubernetes.io/router.middlewares: escolinha-prod-redirect-https@kubernetescrd
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts:
|
||||
- escolinha.athleticmap.influxdigital.com.br
|
||||
- auth-escolinha.athleticmap.influxdigital.com.br
|
||||
secretName: escolinha-tls
|
||||
rules:
|
||||
- host: escolinha.athleticmap.influxdigital.com.br
|
||||
http:
|
||||
paths:
|
||||
- { path: /api/configuracao, pathType: Prefix, backend: { service: { name: servico-configuracao, port: { number: 80 } } } }
|
||||
- { path: /api/cadastro, pathType: Prefix, backend: { service: { name: servico-cadastro, port: { number: 80 } } } }
|
||||
- { path: /bff, pathType: Prefix, backend: { service: { name: servico-bff, port: { number: 80 } } } }
|
||||
- { path: /api/organizacao, pathType: Prefix, backend: { service: { name: servico-organizacao, port: { number: 80 } } } }
|
||||
- { path: /api/planejamento, pathType: Prefix, backend: { service: { name: servico-planejamento, port: { number: 80 } } } }
|
||||
- { path: /api/campeonato, pathType: Prefix, backend: { service: { name: servico-campeonato, port: { number: 80 } } } }
|
||||
- { path: /api/saude, pathType: Prefix, backend: { service: { name: servico-saude, port: { number: 80 } } } }
|
||||
- { path: /api/financeiro, pathType: Prefix, backend: { service: { name: servico-financeiro, port: { number: 80 } } } }
|
||||
- { path: /api/documentos, pathType: Prefix, backend: { service: { name: servico-documentos, port: { number: 80 } } } }
|
||||
- { path: /api/administrativo, pathType: Prefix, backend: { service: { name: servico-administrativo, port: { number: 80 } } } }
|
||||
- { path: /api/assistencia-social, pathType: Prefix, backend: { service: { name: servico-assistencia-social, port: { number: 80 } } } }
|
||||
- { path: /api/pedagogico, pathType: Prefix, backend: { service: { name: servico-pedagogico, port: { number: 80 } } } }
|
||||
- { path: /api/nutricao, pathType: Prefix, backend: { service: { name: servico-nutricao, port: { number: 80 } } } }
|
||||
- { path: /api/agenda, pathType: Prefix, backend: { service: { name: servico-agenda, port: { number: 80 } } } }
|
||||
- { path: /api, pathType: Prefix, backend: { service: { name: backend, port: { number: 80 } } } }
|
||||
- { path: /, pathType: Prefix, backend: { service: { name: frontend-spa, port: { number: 80 } } } }
|
||||
- host: auth-escolinha.athleticmap.influxdigital.com.br
|
||||
http:
|
||||
paths:
|
||||
- { path: /, pathType: Prefix, backend: { service: { name: keycloak, port: { number: 8080 } } } }
|
||||
@@ -0,0 +1,39 @@
|
||||
apiVersion: v1
|
||||
data:
|
||||
athleticmap-realm.json: |
|
||||
{
|
||||
"realm": "athleticmap",
|
||||
"enabled": true,
|
||||
"displayName": "Athletic Map",
|
||||
"loginWithEmailAllowed": true,
|
||||
"roles": {
|
||||
"realm": [
|
||||
{ "name": "admin" },
|
||||
{ "name": "atm_athlete" },
|
||||
{ "name": "atm_trainer" },
|
||||
{ "name": "atm_team_admin" },
|
||||
{ "name": "atm_fed_admin" }
|
||||
]
|
||||
},
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "spa",
|
||||
"name": "Athletic Map SPA",
|
||||
"publicClient": true,
|
||||
"protocol": "openid-connect",
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"redirectUris": ["https://escolinha.athleticmap.influxdigital.com.br/*"],
|
||||
"webOrigins": ["https://escolinha.athleticmap.influxdigital.com.br"],
|
||||
"attributes": {
|
||||
"pkce.code.challenge.method": "S256",
|
||||
"post.logout.redirect.uris": "https://escolinha.athleticmap.influxdigital.com.br/*"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: kc-realm-import
|
||||
namespace: escolinha-prod
|
||||
@@ -0,0 +1,10 @@
|
||||
# Redirect HTTP->HTTPS (Traefik). Aplicado por-ingress (nao afeta o desafio ACME do cert-manager).
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: redirect-https
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
@@ -0,0 +1,57 @@
|
||||
# Backup diario do Postgres do tenant demo (pg_dump -> PVC, retencao 7 dias)
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: pg-backups
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
storageClassName: local-path
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: pg-backup
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
schedule: "0 2 * * *"
|
||||
successfulJobsHistoryLimit: 3
|
||||
failedJobsHistoryLimit: 3
|
||||
concurrencyPolicy: Forbid
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: pg-backup
|
||||
image: postgres:16
|
||||
env:
|
||||
- name: PGPASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: password
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
set -eo pipefail
|
||||
echo "aguardando postgres ficar acessivel..."
|
||||
for i in $(seq 1 30); do pg_isready -h postgres -U atm -t 3 >/dev/null 2>&1 && break; sleep 2; done
|
||||
TS=$(date +%Y%m%d-%H%M%S)
|
||||
for DB in athleticmap keycloak; do
|
||||
echo "dump $DB ..."
|
||||
pg_dump -h postgres -U atm -d "$DB" | gzip > "/backups/${DB}-${TS}.sql.gz"
|
||||
done
|
||||
find /backups -name '*.sql.gz' -mtime +7 -delete
|
||||
echo "backups atuais:"; ls -lh /backups | tail -20
|
||||
volumeMounts:
|
||||
- name: backups
|
||||
mountPath: /backups
|
||||
volumes:
|
||||
- name: backups
|
||||
persistentVolumeClaim:
|
||||
claimName: pg-backups
|
||||
@@ -0,0 +1,19 @@
|
||||
# Permite o namespace 'monitoring' (Prometheus) raspar o backend (porta 8083). Additivo a deny-cross-tenant.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-monitoring
|
||||
namespace: escolinha-prod
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: backend
|
||||
policyTypes: [Ingress]
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: monitoring
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8083
|
||||
@@ -0,0 +1,60 @@
|
||||
# Bounded context "configuracao" como app proprio (ADR-0002): Deployment/pod
|
||||
# medivel = centro de custo. Schema proprio "configuracao" no Postgres do silo
|
||||
# (criado pelo Flyway). Roteado em /api/configuracao no ingress do tenant.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-configuracao
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-configuracao
|
||||
athleticmap.io/contexto: configuracao
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-configuracao } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-configuracao
|
||||
athleticmap.io/contexto: configuracao
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-configuracao
|
||||
image: docker.io/library/servico-configuracao:1.2
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/configuracao/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-configuracao
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-configuracao
|
||||
spec:
|
||||
selector: { app: servico-configuracao }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,59 @@
|
||||
# Bounded context "organizacao" como app proprio (ADR-0002): Elenco e Turma.
|
||||
# Schema proprio "organizacao" (Flyway). Roteado em /api/organizacao no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-organizacao
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-organizacao
|
||||
athleticmap.io/contexto: organizacao
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-organizacao } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-organizacao
|
||||
athleticmap.io/contexto: organizacao
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-organizacao
|
||||
image: docker.io/library/servico-organizacao:1.2
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/organizacao/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-organizacao
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-organizacao
|
||||
spec:
|
||||
selector: { app: servico-organizacao }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,59 @@
|
||||
# Bounded context "planejamento" como app proprio (ADR-0002): Treino e Plano de Aula.
|
||||
# Schema proprio "planejamento" (Flyway). Roteado em /api/planejamento no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-planejamento
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-planejamento
|
||||
athleticmap.io/contexto: planejamento
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-planejamento } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-planejamento
|
||||
athleticmap.io/contexto: planejamento
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-planejamento
|
||||
image: docker.io/library/servico-planejamento:1.3
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/planejamento/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-planejamento
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-planejamento
|
||||
spec:
|
||||
selector: { app: servico-planejamento }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,59 @@
|
||||
# Bounded context "campeonato" (2a onda): Campeonato (estrutura) + Jogo (sumula).
|
||||
# Schema proprio "campeonato" (Flyway). Roteado em /api/campeonato no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-campeonato
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-campeonato
|
||||
athleticmap.io/contexto: campeonato
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-campeonato } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-campeonato
|
||||
athleticmap.io/contexto: campeonato
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-campeonato
|
||||
image: docker.io/library/servico-campeonato:1.9
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/campeonato/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-campeonato
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-campeonato
|
||||
spec:
|
||||
selector: { app: servico-campeonato }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,69 @@
|
||||
# Bounded context "saude" (2a onda): RegistroSaude (registros por especialidade).
|
||||
# Schema proprio "saude" (Flyway). Roteado em /api/saude no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-saude
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-saude
|
||||
athleticmap.io/contexto: saude
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-saude } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-saude
|
||||
athleticmap.io/contexto: saude
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-saude
|
||||
image: docker.io/library/servico-saude:1.88-garmin
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
# Garmin: DNS devolve IPv6 primeiro e a rota IPv6 do cluster falha; forcar IPv4.
|
||||
- { name: JAVA_TOOL_OPTIONS, value: "-Djava.net.preferIPv4Stack=true" }
|
||||
- { name: GARMIN_REDIRECT_URI, value: "https://escolinha.athleticmap.influxdigital.com.br/api/public/integrations/garmin/callback" }
|
||||
- { name: GARMIN_FRONTEND_REDIRECT, value: "https://escolinha.athleticmap.influxdigital.com.br/integracoes/garmin" }
|
||||
- name: GARMIN_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef: { name: garmin-oauth, key: GARMIN_CLIENT_ID }
|
||||
- name: GARMIN_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef: { name: garmin-oauth, key: GARMIN_CLIENT_SECRET }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/saude/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-saude
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-saude
|
||||
spec:
|
||||
selector: { app: servico-saude }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,59 @@
|
||||
# Bounded context "financeiro" (2a onda): Cobranca + ApuracaoRateio (centros de custo).
|
||||
# Schema proprio "financeiro" (Flyway). Roteado em /api/financeiro no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-financeiro
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-financeiro
|
||||
athleticmap.io/contexto: financeiro
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-financeiro } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-financeiro
|
||||
athleticmap.io/contexto: financeiro
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-financeiro
|
||||
image: docker.io/library/servico-financeiro:1.4
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/financeiro/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-financeiro
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-financeiro
|
||||
spec:
|
||||
selector: { app: servico-financeiro }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,64 @@
|
||||
# Bounded context "cadastro" como app proprio (ADR-0002/0003): Deployment/pod
|
||||
# medivel = centro de custo. Schema proprio "cadastro" no Postgres do silo
|
||||
# (criado pelo Flyway). Roteado em /api/cadastro no ingress do tenant.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-cadastro
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-cadastro
|
||||
athleticmap.io/contexto: cadastro
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-cadastro } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-cadastro
|
||||
athleticmap.io/contexto: cadastro
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-cadastro
|
||||
image: docker.io/library/servico-cadastro:1.6
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
- { name: ATM_KC_ADMIN_ENABLED, value: "true" }
|
||||
- name: ATM_KC_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef: { name: kc-admin-secret, key: client-secret }
|
||||
resources:
|
||||
requests: { cpu: 150m, memory: 320Mi }
|
||||
limits: { cpu: "1", memory: 768Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/cadastro/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-cadastro
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-cadastro
|
||||
spec:
|
||||
selector: { app: servico-cadastro }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "documentos" (servico de anexos centralizado, ADR-0002 + decisao 2026-06-18).
|
||||
# Schema proprio "documentos"; roteado em /api/documentos no ingress do tenant.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-documentos
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-documentos, athleticmap.io/contexto: documentos }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-documentos } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-documentos, athleticmap.io/contexto: documentos }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-documentos
|
||||
image: docker.io/library/servico-documentos:1.0
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/documentos/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-documentos
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-documentos }
|
||||
spec:
|
||||
selector: { app: servico-documentos }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "administrativo" (contratos e gestao administrativa, ADR-0002).
|
||||
# Schema proprio "administrativo"; roteado em /api/administrativo no ingress do tenant.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-administrativo
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-administrativo, athleticmap.io/contexto: administrativo }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-administrativo } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-administrativo, athleticmap.io/contexto: administrativo }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-administrativo
|
||||
image: docker.io/library/servico-administrativo:1.6
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/administrativo/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-administrativo
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-administrativo }
|
||||
spec:
|
||||
selector: { app: servico-administrativo }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "assistencia-social" (servico social, ADR-0002).
|
||||
# Schema proprio "assistencia_social"; roteado em /api/assistencia-social no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-assistencia-social
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-assistencia-social, athleticmap.io/contexto: assistencia-social }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-assistencia-social } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-assistencia-social, athleticmap.io/contexto: assistencia-social }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-assistencia-social
|
||||
image: docker.io/library/servico-assistencia-social:1.0
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/assistencia-social/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-assistencia-social
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-assistencia-social }
|
||||
spec:
|
||||
selector: { app: servico-assistencia-social }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "pedagogico" (boletim / acompanhamento academico, ADR-0002).
|
||||
# Schema proprio "pedagogico"; roteado em /api/pedagogico no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-pedagogico
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-pedagogico, athleticmap.io/contexto: pedagogico }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-pedagogico } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-pedagogico, athleticmap.io/contexto: pedagogico }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-pedagogico
|
||||
image: docker.io/library/servico-pedagogico:1.0
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/pedagogico/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-pedagogico
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-pedagogico }
|
||||
spec:
|
||||
selector: { app: servico-pedagogico }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "nutricao" (planos alimentares + catalogo de alimentos, ADR-0002).
|
||||
# Schema proprio "nutricao"; roteado em /api/nutricao no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-nutricao
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-nutricao, athleticmap.io/contexto: nutricao }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-nutricao } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-nutricao, athleticmap.io/contexto: nutricao }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-nutricao
|
||||
image: docker.io/library/servico-nutricao:1.9
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/nutricao/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-nutricao
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-nutricao }
|
||||
spec:
|
||||
selector: { app: servico-nutricao }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Bounded context "agenda" (agendamento de compromissos: consulta/avaliacao/retorno/treino/reuniao, ADR-0002).
|
||||
# Schema proprio "agenda"; roteado em /api/agenda no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-agenda
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-agenda, athleticmap.io/contexto: agenda }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-agenda } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: servico-agenda, athleticmap.io/contexto: agenda }
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-agenda
|
||||
image: docker.io/library/servico-agenda:1.1
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: SPRING_DATASOURCE_URL, value: "jdbc:postgresql://postgres:5432/athleticmap" }
|
||||
- { name: SPRING_DATASOURCE_USERNAME, value: "atm" }
|
||||
- { name: SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE, value: "5" }
|
||||
- name: SPRING_DATASOURCE_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef: { name: db-credentials, key: password }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 300Mi }
|
||||
limits: { cpu: "1", memory: 640Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /api/agenda/health, port: 8083 }
|
||||
initialDelaySeconds: 25
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-agenda
|
||||
namespace: escolinha-prod
|
||||
labels: { app: servico-agenda }
|
||||
spec:
|
||||
selector: { app: servico-agenda }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,67 @@
|
||||
# BFF (Backend-for-Frontend) — ponto unico da SPA; agrega configuracao + cadastro
|
||||
# com token relay. Stateless (sem banco). Roteado em /bff no ingress do tenant.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: servico-bff
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-bff
|
||||
athleticmap.io/contexto: bff
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: servico-bff } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: servico-bff
|
||||
athleticmap.io/contexto: bff
|
||||
spec:
|
||||
containers:
|
||||
- name: servico-bff
|
||||
image: docker.io/library/servico-bff:1.87-garmin
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 8083 }]
|
||||
env:
|
||||
- { name: ATM_CONFIG_URL, value: "http://servico-configuracao" }
|
||||
- { name: ATM_CADASTRO_URL, value: "http://servico-cadastro" }
|
||||
- { name: ATM_ORGANIZACAO_URL, value: "http://servico-organizacao" }
|
||||
- { name: ATM_PLANEJAMENTO_URL, value: "http://servico-planejamento" }
|
||||
- { name: ATM_CAMPEONATO_URL, value: "http://servico-campeonato" }
|
||||
- { name: ATM_SAUDE_URL, value: "http://servico-saude" }
|
||||
- { name: ATM_FINANCEIRO_URL, value: "http://servico-financeiro" }
|
||||
- { name: ATM_DOCUMENTOS_URL, value: "http://servico-documentos" }
|
||||
- { name: ATM_ADMINISTRATIVO_URL, value: "http://servico-administrativo" }
|
||||
- { name: ATM_ASSISTENCIA_SOCIAL_URL, value: "http://servico-assistencia-social" }
|
||||
- { name: ATM_PEDAGOGICO_URL, value: "http://servico-pedagogico" }
|
||||
- { name: ATM_NUTRICAO_URL, value: "http://servico-nutricao" }
|
||||
- { name: ATM_AGENDA_URL, value: "http://servico-agenda" }
|
||||
- { name: ATM_JWK_SET_URI, value: "http://keycloak:8080/realms/athleticmap/protocol/openid-connect/certs" }
|
||||
- { name: ATM_ISSUER, value: "https://auth-escolinha.athleticmap.influxdigital.com.br/realms/athleticmap" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
- { name: GARMIN_FRONTEND_REDIRECT, value: "https://escolinha.athleticmap.influxdigital.com.br/integracoes/garmin" }
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 256Mi }
|
||||
limits: { cpu: 500m, memory: 512Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /bff/health, port: 8083 }
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
httpGet: { path: /actuator/health/liveness, port: 8083 }
|
||||
initialDelaySeconds: 50
|
||||
periodSeconds: 20
|
||||
failureThreshold: 6
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: servico-bff
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: servico-bff
|
||||
spec:
|
||||
selector: { app: servico-bff }
|
||||
ports: [{ name: http, port: 80, targetPort: 8083 }]
|
||||
@@ -0,0 +1,48 @@
|
||||
# SPA Angular (shell OIDC + admin de catalogos + cadastro de Atleta) consumindo
|
||||
# o BFF. Substitui o stub estatico nginx/configMap. Roteado em / no ingress.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: frontend-spa
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: frontend-spa
|
||||
athleticmap.io/contexto: frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: frontend-spa } }
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: frontend-spa
|
||||
athleticmap.io/contexto: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: frontend-spa
|
||||
image: docker.io/library/frontend-spa:1.90-garmin
|
||||
imagePullPolicy: Never
|
||||
ports: [{ containerPort: 80 }]
|
||||
env:
|
||||
- { name: ATM_KC_URL, value: "https://auth-escolinha.athleticmap.influxdigital.com.br" }
|
||||
- { name: ATM_REALM, value: "athleticmap" }
|
||||
- { name: ATM_CLIENT, value: "spa" }
|
||||
- { name: ATM_TENANT, value: "escolinha" }
|
||||
resources:
|
||||
requests: { cpu: 50m, memory: 64Mi }
|
||||
limits: { cpu: 200m, memory: 128Mi }
|
||||
readinessProbe:
|
||||
httpGet: { path: /, port: 80 }
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: frontend-spa
|
||||
namespace: escolinha-prod
|
||||
labels:
|
||||
app: frontend-spa
|
||||
spec:
|
||||
selector: { app: frontend-spa }
|
||||
ports: [{ name: http, port: 80, targetPort: 80 }]
|
||||
@@ -0,0 +1 @@
|
||||
# Patch manual: /api/public roteado ao BFF (Garmin OAuth callback)
|
||||
@@ -0,0 +1,25 @@
|
||||
# Rota publica Garmin OAuth callback (BFF)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: escolinha-garmin-public
|
||||
namespace: escolinha-prod
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
traefik.ingress.kubernetes.io/router.middlewares: escolinha-prod-redirect-https@kubernetescrd
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
tls:
|
||||
- hosts: [escolinha.athleticmap.influxdigital.com.br]
|
||||
secretName: escolinha-tls
|
||||
rules:
|
||||
- host: escolinha.athleticmap.influxdigital.com.br
|
||||
http:
|
||||
paths:
|
||||
- path: /api/public
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: servico-bff
|
||||
port:
|
||||
number: 80
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"realm": "athleticmap",
|
||||
"enabled": true,
|
||||
"displayName": "Athletic Map",
|
||||
"loginWithEmailAllowed": true,
|
||||
"roles": {
|
||||
"realm": [
|
||||
{
|
||||
"name": "admin"
|
||||
},
|
||||
{
|
||||
"name": "atm_athlete"
|
||||
},
|
||||
{
|
||||
"name": "atm_trainer"
|
||||
},
|
||||
{
|
||||
"name": "atm_team_admin"
|
||||
},
|
||||
{
|
||||
"name": "atm_fed_admin"
|
||||
},
|
||||
{
|
||||
"name": "atm_admin",
|
||||
"description": "Administrador do tenant (gestao geral)"
|
||||
},
|
||||
{
|
||||
"name": "atm_cadastro",
|
||||
"description": "Gestao de cadastros e catalogos"
|
||||
}
|
||||
]
|
||||
},
|
||||
"clients": [
|
||||
{
|
||||
"clientId": "spa",
|
||||
"name": "Athletic Map SPA",
|
||||
"publicClient": true,
|
||||
"protocol": "openid-connect",
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"redirectUris": [
|
||||
"https://escolinha.athleticmap.influxdigital.com.br/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"https://escolinha.athleticmap.influxdigital.com.br"
|
||||
],
|
||||
"attributes": {
|
||||
"pkce.code.challenge.method": "S256",
|
||||
"post.logout.redirect.uris": "https://escolinha.athleticmap.influxdigital.com.br/*"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user