first commit

This commit is contained in:
Stéphane Tailland
2026-08-23 14:42:26 +02:00
parent 7b7257379f
commit 9c2dd3f8db
8 changed files with 151 additions and 22 deletions
+4
View File
@@ -0,0 +1,4 @@
.DS_Store
*.swp
**/secret.yaml
+41 -6
View File
@@ -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 `<env>/<gateway-type>/` — 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`.
-5
View File
@@ -1,5 +0,0 @@
# TODO: DataPlane CRD for customers/dev/api-gateway
apiVersion: gateway-operator.konghq.com/v1beta1
kind: DataPlane
metadata:
name: customers-dev
+27
View File
@@ -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
@@ -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
-6
View File
@@ -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
-5
View File
@@ -1,5 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- dataplane.yaml
- konnectextension.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