4 Commits

Author SHA1 Message Date
Sten
375fbff4b6 fix(apps): drop duplicate keycloak-client secret (chart owns it)
The forteapp chart renders Secret/keycloak-client-forte-drop from
auth.registration values (verified: the live secret is tracked by
the forte-drop Application and carries the correct
drop.forteapps.net redirect). The overlay copy gives the secret two
owners — enterprise-apps and forte-drop self-heal against each
other in a sync loop (the Slack spam). Remove the overlay copy;
the chart is the single source.
2026-06-05 12:55:45 +02:00
275ec675da fix(apps): drop dangling namespace.yaml ref (enterprise-apps ComparisonError) (#19)
0a98674 deleted `namespace.yaml` but `apps/overlays/upc-dev/forte-drop/kustomization.yaml` still lists it → `kustomize build` fails → the **enterprise-apps** app-of-apps has a ComparisonError and the whole overlay stopped syncing. Visible symptom: `secret "forte-drop-secrets" not found` on all forte-drop pods (the SealedSecret no longer applies).

One-line fix: remove the dangling resource entry. The namespace itself is fine — the forte-drop Application has `CreateNamespace=true`.

@danijel.simeunovic — pairs with your cleanup; after this merges the secret re-applies and the pods only need the right image tag (helm-prod-values PR #4: `buildcache` → `v20260604-200105-1316f7a`, buildcache is the buildx cache manifest, not a runnable image).

Co-authored-by: Sten <sten@Sten-sin-MacBook-Pro.local>
Reviewed-on: #19
Reviewed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-06-05 08:44:56 +00:00
0a98674a27 not needed 2026-06-05 00:05:56 +02:00
b713ec853c feat(apps): forte-drop web + mcp argocd apps (prod) (#18)
## Summary

ArgoCD Applications + Keycloak clients + sealed secret for forte-drop **web + mcp** (PROD).

## What changed

- **forte-drop** + **forte-drop-mcp** ArgoCD Applications (two-source: forte-helm chart + helm-prod-values).
- **namespace.yaml** — explicit `forte-drop` Namespace at sync-wave -1, `Prune=false` (avoids first-sync race for namespaced resources; doesn't cascade-delete on base removal).
- **keycloak-client-forte-drop** + **keycloak-client-forte-drop-mcp** — labeled config Secrets; the registrar creates the OIDC clients in the `forte` realm within ~2 min.
- **forte-drop-secrets** SealedSecret — UpCloud S3 creds (existing drops bucket) + PG creds + PASSWORD_GATE_SECRET. Consumed by both deployments + the pg-backup CronJob.
- **forte-drop-web PDB** — minAvailable 1 (selector verified against the live forteapp chart's pod labels).
- Wired into `apps/overlays/upc-dev` (NOT base → stays out of upc-prod).

## Post-merge manual step (one-time)

`auth-oidc` SealedSecret for the web sidecar is still commented out — it needs the `client-secret` the Keycloak registrar writes to `forte-drop-oidc-credentials` after first sync:

```bash
CLIENT_SECRET=$(kubectl -n forte-drop get secret forte-drop-oidc-credentials -o jsonpath='{.data.client-secret}' | base64 -d)
kubectl create secret generic auth-oidc -n forte-drop \
  --from-literal=client-secret="$CLIENT_SECRET" \
  --from-literal=cookie-secret="$(openssl rand -hex 32)" \
  --dry-run=client -o yaml > private/auth-oidc.yaml
kubeseal --format=yaml --controller-name=sealed-secrets-controller --controller-namespace=kube-system \
  < private/auth-oidc.yaml > apps/base/forte-drop/auth-oidc-sealed.yaml
# uncomment in kustomization, commit, push
```

## Depends on

- launchpad PR #17 (postgres + namespace via CreateNamespace).
- helm-prod-values forte-drop PR (values).

## Review

- [x] codex: namespace first-sync race → fixed (explicit namespace, sync-wave -1).
- [x] Keycloak registrar unblocked (stale chibisafe/minio config secrets removed; registrar green).

🤖 Generated with Claude Code

Co-authored-by: Sten <sten@Sten-sin-MacBook-Pro.local>
Co-authored-by: Sten <sten@Mac.domain_not_set.invalid>
Co-authored-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
Reviewed-on: #18
Reviewed-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-06-04 18:47:08 +00:00
5 changed files with 4 additions and 61 deletions

View File

@@ -1,38 +0,0 @@
# Labeled config Secret read by the Keycloak Client Registrar. Kyverno clones it
# to the keycloak namespace; a CronJob registers the OIDC client in the forte
# realm and writes the credentials back as forte-drop-oidc-credentials in THIS
# namespace (~2 min). The forte-helm auth sidecar (auth.type: oidc) consumes that
# registrar-created Secret automatically — no manual SealedSecret step needed.
apiVersion: v1
kind: Secret
metadata:
name: keycloak-client-forte-drop
namespace: forte-drop
labels:
keycloak.forteapps.net/client-config: "true"
annotations:
keycloak.forteapps.net/source-namespace: "forte-drop"
stringData:
client.json: |
{
"clientId": "forte-drop",
"name": "Forte Drop (web)",
"enabled": true,
"protocol": "openid-connect",
"clientAuthenticatorType": "client-secret",
"standardFlowEnabled": true,
"directAccessGrantsEnabled": false,
"serviceAccountsEnabled": false,
"publicClient": false,
"redirectUris": ["https://drop-k8s.hackathon.forteapps.net/auth/callback"],
"webOrigins": ["https://drop-k8s.hackathon.forteapps.net"],
"defaultClientScopes": ["openid","email","profile"],
"secret": {
"namespace": "forte-drop",
"name": "forte-drop-oidc-credentials",
"keys": {
"clientId": "client-id",
"clientSecret": "client-secret"
}
}
}

View File

@@ -1,8 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- forte-drop.yaml
- keycloak-client-forte-drop.yaml
- forte-drop-pdb.yaml
- forte-drop-secrets-sealed.yaml

View File

@@ -1,17 +0,0 @@
# Owns the forte-drop namespace shared by the web + mcp deployments and the
# postgres StatefulSet (infra overlay). sync-wave -1 ensures the namespace exists
# before the namespaced Secrets/PDB in this base apply (avoids a first-sync
# "namespaces forte-drop not found" race when the business-apps parent syncs).
# Prune=false so removing this base never cascade-deletes the namespace (and with
# it postgres data + the mcp deployment) — matches the earlier decision to keep
# namespace ownership decoupled from any single workload.
apiVersion: v1
kind: Namespace
metadata:
name: forte-drop
annotations:
argocd.argoproj.io/sync-wave: "-1"
argocd.argoproj.io/sync-options: Prune=false
labels:
app.kubernetes.io/managed-by: argocd
app.kubernetes.io/part-of: apps

View File

@@ -8,6 +8,6 @@ resources:
# No patches needed — base apps already default to "upc-dev" value paths
# (upc-dev is the default/base cluster).
# forte-drop (postgres + web + mcp) and dbunk-demo are upc-dev-only apps — they
# have hackathon-domain hardcoded values and must not sync to upc-prod, so they
# live here in the overlay rather than in apps/base/.
# forte-drop (postgres + web + mcp) and dbunk-demo are upc-dev-only apps — their
# values hardcode upc-dev hosts (drop.forteapps.net etc.) and must not sync to
# upc-prod, so they live here in the overlay rather than in apps/base/.

View File

@@ -60,7 +60,7 @@ config:
description: Teknisk kompetanse fra offentlige anbud
icon: forte
- Forte Drop:
href: https://drop.hackathon.forteapps.net
href: https://drop.forteapps.net
description: Self-hosted HTML-drops + MCP for Claude
icon: forte
- Forte Feedback: