From 9c2dd3f8db2a7f393b9a19fb7e254769d00c3876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Tailland?= Date: Sun, 23 Aug 2026 14:42:26 +0200 Subject: [PATCH] first commit --- .gitignore | 4 ++ README.md | 47 ++++++++++++++++++--- dev/api-gateway/dataplane.yaml | 5 --- dev/api-gateway/externalsecret.yaml | 27 ++++++++++++ dev/api-gateway/gateway-kustomization.yaml | 37 ++++++++++++++++ dev/api-gateway/konnectextension.yaml | 6 --- dev/api-gateway/kustomization.yaml | 5 --- dev/api-gateway/policies-kustomization.yaml | 42 ++++++++++++++++++ 8 files changed, 151 insertions(+), 22 deletions(-) create mode 100644 .gitignore delete mode 100644 dev/api-gateway/dataplane.yaml create mode 100644 dev/api-gateway/externalsecret.yaml create mode 100644 dev/api-gateway/gateway-kustomization.yaml delete mode 100644 dev/api-gateway/konnectextension.yaml delete mode 100644 dev/api-gateway/kustomization.yaml create mode 100644 dev/api-gateway/policies-kustomization.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..266bf00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +*.swp + +**/secret.yaml diff --git a/README.md b/README.md index 2229fd9..06bc490 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,45 @@ # dataplane-customers Layer 2 (Gateway infrastructure) for the **customers** bounded context -(domain team: customers). `DataPlane`, `KonnectExtension`, certs (cert-manager), -secrets (External Secrets Operator) — one Control Plane per environment, -referenced by ID (created by `../konnect-platform`, never recreated here). +(domain team: customers) — one Control Plane per environment, referenced by +ID (created manually in Konnect for now, never recreated here). -Content is generated and PR'd automatically when the matching Control -Plane is created via the self-service flow in `../konnect-platform` — -never hand-edited directly. +**This repo does NOT hold `KonnectAPIAuthConfiguration`/`GatewayConfiguration`/ +`Gateway`/`Certificate` YAML directly.** The actual resource template (one +copy, covering every domain/environment) lives in +`../k8s-platform/dataplane-template/`, `${VAR}`-parameterized. This repo +only holds what's specific to one `//` — same +`gateway-kustomization.yaml` / `externalsecret.yaml` / `policies-kustomization.yaml` +three-file pattern as `dataplane-catalog` (see that repo's README for the +full explanation of each file's role — identical here, not repeated). + +**IdP**: the `openid-connect` policy's `OIDC_ISSUER` (in +`dev/api-gateway/policies-kustomization.yaml`) points at the **local +in-cluster Keycloak** (`ns keycloak`, `https://keycloak.sttlab.local/realms/classic-models`, +deployed 2026-08-23 — config-as-code source in the separate `infra-keycloak` +repo). Not a `customers`-specific choice: `catalog`/`classic-models-api`/ +`librechat` were migrated to the same local Keycloak the same day (see +`../STATUS.md` section 15) — the old VPS Keycloak (`keycloak.sttlab.eu`) is +being phased out platform-wide, `customers` was just built against the +local one from the start rather than migrated later. The +`dataplane-template-defaults` ConfigMap's cluster-wide `OIDC_ISSUER` default +still hasn't been updated to match (still the stale VPS value) — every +domain currently overrides past it individually; see `../STATUS.md` +section 16 for that gap. + +**Only `dev/` is real.** `staging/api-gateway/` and `prod/api-gateway/` +still hold the original TODO placeholder files (`dataplane.yaml`, +`konnectextension.yaml`) from before this pattern existed — not converted, +not deployed, no Control Plane created for them yet. + +**This is Layer 2 (Gateway infrastructure) only — no API is actually +reachable through it yet.** The Layer 3 repo (`../customers-api`, the +`KongService`/`KongRoute`/plugin definitions that would route real traffic +to the backend, same role as `../catalog-api` plays for `catalog`) is +still just two `# TODO` placeholder files, not deployed — `kubectl get +kongservice,kongroute -n customers` returns nothing. A request to +`customers-dev.sttlab.local` would 404, not route anywhere. + +**Self-service pipeline (`../konnect-platform` generating this content +automatically) does not exist yet** — still a stub per `../STATUS.md`. +Everything here is hand-maintained, same as `dataplane-catalog`. diff --git a/dev/api-gateway/dataplane.yaml b/dev/api-gateway/dataplane.yaml deleted file mode 100644 index 3bd6558..0000000 --- a/dev/api-gateway/dataplane.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# TODO: DataPlane CRD for customers/dev/api-gateway -apiVersion: gateway-operator.konghq.com/v1beta1 -kind: DataPlane -metadata: - name: customers-dev diff --git a/dev/api-gateway/externalsecret.yaml b/dev/api-gateway/externalsecret.yaml new file mode 100644 index 0000000..805ed36 --- /dev/null +++ b/dev/api-gateway/externalsecret.yaml @@ -0,0 +1,27 @@ +# Real PAT lives only in Vault (secrets/kong-v2/customers/dev/konnect-pat), +# never in git, never manually kubectl-applied. refreshInterval controls how +# often ESO re-checks Vault and re-syncs the K8s Secret if the value +# changed there — rotation becomes "update Vault", nothing to touch in the +# cluster. +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: customers-dev-konnect-auth + namespace: customers +spec: + refreshInterval: 1h + secretStoreRef: + kind: ClusterSecretStore + name: vault-kong-v2 + target: + name: customers-dev-konnect-auth + template: + metadata: + labels: + konghq.com/credential: konnect + konghq.com/secret: "true" + data: + - secretKey: token + remoteRef: + key: kong-v2/customers/dev/konnect-pat + property: token diff --git a/dev/api-gateway/gateway-kustomization.yaml b/dev/api-gateway/gateway-kustomization.yaml new file mode 100644 index 0000000..bf18750 --- /dev/null +++ b/dev/api-gateway/gateway-kustomization.yaml @@ -0,0 +1,37 @@ +# sourceRef points at the GitRepository "k8s-platform" (created once, +# flux-system, see ../../../k8s-platform/flux/gitrepository.yaml) — any +# domain's Kustomization can reference this same object, no monorepo: +# k8s-platform and dataplane-customers stay two separate repos, `path` below +# is relative to the root of whichever repo `sourceRef` names. +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: customers-dev-api-gateway + namespace: flux-system +spec: + interval: 10m + sourceRef: + kind: GitRepository + name: k8s-platform + path: ./dataplane-template + prune: true + postBuild: + # Domain-specific non-sensitive values inline — no separate ConfigMap to + # forget to re-apply after an edit (bit us twice already). Inline + # substitute always wins over substituteFrom regardless of order, so + # this still overrides dataplane-template-defaults where needed. + substitute: + NAME: customers-dev + NAMESPACE: customers + CONTROL_PLANE_ID: "4d791a4c-177d-45dd-9ba5-3d28926458cd" + HOSTNAME: customers-dev.sttlab.local + # Cluster-wide defaults only — the Konnect PAT is NOT handled via + # substitute/substituteFrom at all: that mechanism requires the source + # Secret to sit in flux-system (same namespace as this Kustomization), + # which put a live copy of the real PAT in a shared, broadly-readable + # namespace. Rejected. The real konnect-auth Secret is materialized + # directly into the customers namespace instead (externalsecret.yaml, via + # External Secrets Operator + Vault) — never passes through flux-system. + substituteFrom: + - kind: ConfigMap + name: dataplane-template-defaults diff --git a/dev/api-gateway/konnectextension.yaml b/dev/api-gateway/konnectextension.yaml deleted file mode 100644 index 3026412..0000000 --- a/dev/api-gateway/konnectextension.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# TODO: KonnectExtension referencing the Control Plane created by -# konnect-platform/domains/customers/dev/ (by ID, not created here) -apiVersion: konnect.konghq.com/v1alpha1 -kind: KonnectExtension -metadata: - name: customers-dev diff --git a/dev/api-gateway/kustomization.yaml b/dev/api-gateway/kustomization.yaml deleted file mode 100644 index 44ec993..0000000 --- a/dev/api-gateway/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - dataplane.yaml - - konnectextension.yaml diff --git a/dev/api-gateway/policies-kustomization.yaml b/dev/api-gateway/policies-kustomization.yaml new file mode 100644 index 0000000..aa772dc --- /dev/null +++ b/dev/api-gateway/policies-kustomization.yaml @@ -0,0 +1,42 @@ +# Split from gateway-kustomization.yaml on purpose: different change +# cadence (policies get tuned far more often than the Gateway itself gets +# recreated) and different blast radius (a bad policy build/prune can't +# touch the Gateway/DataPlane, and vice versa). Same GitRepository, same +# domain namespace, different path. +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: customers-dev-api-gateway-policies + namespace: flux-system +spec: + interval: 10m + sourceRef: + kind: GitRepository + name: k8s-platform + path: ./dataplane-globalpolicy-template + prune: true + postBuild: + substitute: + NAME: customers-dev + NAMESPACE: customers + # Looked up manually after gateway-kustomization.yaml's + # Gateway/GatewayConfiguration first reconciled — the operator + # auto-names the mirrored KonnectGatewayControlPlane with a random + # suffix, not derivable from NAME. See + # dataplane-globalpolicy-template/global-policies-pluginbindings.yaml's + # comment. Automate this lookup once the self-service pipeline exists. + CONTROL_PLANE_REF_NAME: customers-dev-tw8tn + # Every audience valid anywhere in the customers domain — grows as the + # domain gains APIs. + JWT_AUDIENCE_WHITELIST: '["customers-api"]' + # Deliberate override of dataplane-template-defaults' OIDC_ISSUER (VPS + # Keycloak) — the customers-api client lives only in the local + # in-cluster Keycloak (ns keycloak, keycloak.sttlab.local/realms/ + # classic-models, deployed 2026-08-23), a separate IdP instance from + # the VPS one the other domains (catalog, librechat) authenticate + # against. Confirmed reachable in-cluster (OIDC discovery, 200) before + # wiring this in. + OIDC_ISSUER: https://keycloak.sttlab.local/realms/classic-models + substituteFrom: + - kind: ConfigMap + name: dataplane-template-defaults