diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f31b3e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +*.swp diff --git a/README.md b/README.md index ab412e6..c001489 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,68 @@ # k8s-platform -Platform-team owned, cluster-scoped only: Kong Gateway Operator install -(Helm chart or OLM Subscription on OpenShift). Rare changes, cautious sync -(not aggressive auto-sync). +Platform-team owned, cluster-scoped only. Rare changes, cautious sync (not +aggressive auto-sync). -Per-domain gateway infrastructure (DataPlane/KonnectExtension) does NOT -live here — see the dedicated `dataplane-` repos, to avoid write -contention across domains. +Per-domain gateway infrastructure (`Gateway`, `GatewayConfiguration`, +`KonnectAPIAuthConfiguration`) does NOT live here — see the dedicated +`dataplane-` repos, to avoid write contention across domains. + +## flux/ + +The Flux Operator (`flux-system` namespace) that everything else in this +GitOps setup depends on. Installed 2026-08-19 on the local cluster. + +The operator itself is installed manually via Helm — bootstrap problem, +Flux can't deploy the thing that deploys it: + +```bash +helm install flux-operator oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator \ + --namespace flux-system --create-namespace +``` + +`flux/fluxinstance.yaml` configures the actual Flux controllers +(source-controller, kustomize-controller, helm-controller, +notification-controller) — tracked in git, applied via +`kubectl apply -k flux/`. + +`flux/gitrepository.yaml` is what lets Flux clone this (`k8s-platform`) +repo so other repos' `Kustomization`s can reference paths inside it (e.g. +`dataplane-template/`). `url` is a `PLACEHOLDER` — this repo has no git +remote yet. Once it does, apply it manually once +(`kubectl apply -f flux/gitrepository.yaml`) — same bootstrap-chicken-egg +reasoning as the operator install above. + +## kong-platform/ + +Cluster-wide Kong foundations: +- `gatewayclass.yaml` — `GatewayClass` `kong-v2` (deliberately not named + `kong`, to avoid touching the pre-existing `kong` GatewayClass that backs + the unrelated `tasks`/`jira`/`openrouter` Gateway on this cluster). +- `operator/` — `HelmRepository` + `HelmRelease` for the Kong Gateway + Operator itself, matching the release already installed manually on this + cluster (`helm list -n kong`: chart `kong-operator-1.3.1`, `env.ENABLE_CONTROLLER_KONNECT: true`). + `helm-controller` can adopt an existing release under the same + `releaseName`/`targetNamespace` rather than reinstalling. + +## dataplane-template/ + +The shared `KonnectAPIAuthConfiguration` + `GatewayConfiguration` + `Gateway` ++ `Secret` template (one copy, `${VAR}`-parameterized) that every domain's +Flux `Kustomization` builds via `postBuild.substitute` — see +`dataplane-catalog/README.md` for the full mechanism and the values/secret +side of it. + +## Applying today (no git remote yet) + +Nothing here reconciles from git automatically yet — `flux/gitrepository.yaml` +has no real URL. Apply directly: + +```bash +kubectl apply -k flux/ # fluxinstance.yaml + gitrepository.yaml (the + # latter will just sit inert, PLACEHOLDER url) +kubectl apply -f kong-platform/gatewayclass.yaml +``` + +`dataplane-template/` is never applied on its own — it only makes sense +built + substituted by a domain's `flux-kustomization.yaml`, which itself +can't reconcile yet (needs the real `GitRepository`, see above). diff --git a/dataplane-template/gateway.yaml b/dataplane-template/gateway.yaml new file mode 100644 index 0000000..afea424 --- /dev/null +++ b/dataplane-template/gateway.yaml @@ -0,0 +1,24 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + gatewayClassName: kong-v2 + infrastructure: + parametersRef: + group: gateway-operator.konghq.com + kind: GatewayConfiguration + name: ${NAME} + listeners: + - name: http + protocol: HTTP + port: 80 + - name: https + protocol: HTTPS + port: 443 + hostname: ${HOSTNAME} + tls: + certificateRefs: + - kind: Secret + name: ${TLS_SECRET_NAME} diff --git a/dataplane-template/gatewayconfiguration.yaml b/dataplane-template/gatewayconfiguration.yaml new file mode 100644 index 0000000..b247cce --- /dev/null +++ b/dataplane-template/gatewayconfiguration.yaml @@ -0,0 +1,21 @@ +apiVersion: gateway-operator.konghq.com/v2beta1 +kind: GatewayConfiguration +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + dataPlaneOptions: + deployment: + replicas: ${REPLICAS} + podTemplateSpec: + spec: + containers: + - name: proxy + image: ${GATEWAY_IMAGE} + konnect: + authRef: + name: ${NAME} + source: Mirror + mirror: + konnect: + id: ${CONTROL_PLANE_ID} diff --git a/dataplane-template/konnectapiauthconfiguration.yaml b/dataplane-template/konnectapiauthconfiguration.yaml new file mode 100644 index 0000000..8271f6f --- /dev/null +++ b/dataplane-template/konnectapiauthconfiguration.yaml @@ -0,0 +1,10 @@ +apiVersion: konnect.konghq.com/v1alpha1 +kind: KonnectAPIAuthConfiguration +metadata: + name: ${NAME} + namespace: ${NAMESPACE} +spec: + type: secretRef + secretRef: + name: ${KONNECT_AUTH_SECRET_NAME} + serverURL: ${KONNECT_SERVER_URL} diff --git a/dataplane-template/kustomization.yaml b/dataplane-template/kustomization.yaml new file mode 100644 index 0000000..b848c54 --- /dev/null +++ b/dataplane-template/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - konnectapiauthconfiguration.yaml + - gatewayconfiguration.yaml + - gateway.yaml + - secret.yaml diff --git a/dataplane-template/secret.yaml b/dataplane-template/secret.yaml new file mode 100644 index 0000000..e47149f --- /dev/null +++ b/dataplane-template/secret.yaml @@ -0,0 +1,15 @@ +# konghq.com/secret: "true" is required — the Kong Operator's secret +# watch/cache is scoped to that label; without it, references from +# KonnectAPIAuthConfiguration.secretRef resolve to "does not exist" even +# though the Secret is present (see ~/dev/kong/kube/gateway/apigw/secret.yaml). +apiVersion: v1 +kind: Secret +metadata: + name: ${KONNECT_AUTH_SECRET_NAME} + namespace: ${NAMESPACE} + labels: + konghq.com/credential: konnect + konghq.com/secret: "true" +type: Opaque +stringData: + token: ${KONNECT_PAT_TOKEN} diff --git a/flux/fluxinstance.yaml b/flux/fluxinstance.yaml new file mode 100644 index 0000000..5749f14 --- /dev/null +++ b/flux/fluxinstance.yaml @@ -0,0 +1,24 @@ +# The Flux Operator itself (flux-system ns) is installed manually via Helm, +# not by Flux — bootstrap problem, Flux can't deploy the thing that deploys +# it. Standard/expected: see README.md for the one-time install command. +# +# This FluxInstance is what the operator reconciles into the actual Flux +# controllers (source-controller, kustomize-controller, ...). No `sync` +# block yet: that would wire Flux to a GitRepository/OCIRepository source to +# reconcile automatically, and none of the kong-v2 repos have a remote yet +# (all local-only, see ../../STATUS.md) — until that's decided, apply +# Kustomizations manually per repo (e.g. `kubectl apply -k dataplane-catalog/dev/api-gateway/`). +apiVersion: fluxcd.controlplane.io/v1 +kind: FluxInstance +metadata: + name: flux + namespace: flux-system +spec: + distribution: + registry: ghcr.io/fluxcd + version: "2.x" + components: + - source-controller + - kustomize-controller + - helm-controller + - notification-controller diff --git a/flux/gitrepository.yaml b/flux/gitrepository.yaml new file mode 100644 index 0000000..42dec6b --- /dev/null +++ b/flux/gitrepository.yaml @@ -0,0 +1,27 @@ +# Not applied yet: url is a PLACEHOLDER, this repo has no git remote (see +# ../../STATUS.md). Once it does, this object is what makes source-controller +# actually clone it — nothing else does. +# +# Bootstrap step, same category as installing the Flux Operator itself +# (see ../README.md): this file must be applied manually once +# (`kubectl apply -f gitrepository.yaml`), because nothing can apply it +# automatically before it exists — Flux can't fetch the object that tells it +# where to fetch from. After that one-time apply, since this file lives +# inside the k8s-platform repo that the GitRepository itself now points at, +# a root Kustomization reconciling k8s-platform's own `flux/` directory +# would keep it (and everything else here) self-managing going forward — +# not scaffolded yet, out of scope for this file. +# +# Any other repo's Kustomization (e.g. dataplane-catalog's +# flux-kustomization.yaml) can reference this SAME GitRepository by name — +# one GitRepository per source repo, not per consumer. +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: k8s-platform + namespace: flux-system +spec: + interval: 5m + url: PLACEHOLDER # e.g. https://github.com//k8s-platform + ref: + branch: main diff --git a/flux/kustomization.yaml b/flux/kustomization.yaml new file mode 100644 index 0000000..1b19eac --- /dev/null +++ b/flux/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - fluxinstance.yaml + - gitrepository.yaml diff --git a/kong-platform/gatewayclass.yaml b/kong-platform/gatewayclass.yaml new file mode 100644 index 0000000..cc832ca --- /dev/null +++ b/kong-platform/gatewayclass.yaml @@ -0,0 +1,14 @@ +# Named "kong-v2", not "kong" — the "kong" GatewayClass already exists on +# this cluster (backs the unrelated tasks/jira/openrouter Gateway) and its +# default parametersRef is load-bearing for that Gateway, which has no +# per-instance override unlike ours. Reusing that name would edit a shared +# cluster-scoped object something else depends on. No parametersRef here: +# every domain's own Gateway sets spec.infrastructure.parametersRef itself +# (see dataplane-template/gateway.yaml), so there's no meaningful default to +# set at the class level. +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: kong-v2 +spec: + controllerName: konghq.com/gateway-operator diff --git a/kong-platform/kustomization.yaml b/kong-platform/kustomization.yaml new file mode 100644 index 0000000..f9792da --- /dev/null +++ b/kong-platform/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - gatewayclass.yaml diff --git a/kong-platform/operator/helmrelease.yaml b/kong-platform/operator/helmrelease.yaml new file mode 100644 index 0000000..1c7dd8c --- /dev/null +++ b/kong-platform/operator/helmrelease.yaml @@ -0,0 +1,25 @@ +# Matches the release already installed manually on this cluster +# (`helm list -n kong`: chart kong-operator-1.3.1, values env.ENABLE_CONTROLLER_KONNECT: true). +# helm-controller can adopt an existing release under the same +# releaseName/targetNamespace — this doesn't reinstall from scratch, it +# starts managing what's already there. +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: kong-operator + namespace: flux-system +spec: + interval: 1h + releaseName: kong-operator + targetNamespace: kong + chart: + spec: + chart: kong-operator + version: "1.3.1" + sourceRef: + kind: HelmRepository + name: kong + namespace: flux-system + values: + env: + ENABLE_CONTROLLER_KONNECT: true diff --git a/kong-platform/operator/helmrepository.yaml b/kong-platform/operator/helmrepository.yaml new file mode 100644 index 0000000..5a14c88 --- /dev/null +++ b/kong-platform/operator/helmrepository.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: kong + namespace: flux-system +spec: + interval: 1h + url: https://charts.konghq.com diff --git a/operator/kustomization.yaml b/operator/kustomization.yaml deleted file mode 100644 index 6e28a72..0000000 --- a/operator/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# TODO: Kong Gateway Operator install (Helm chart via HelmRelease, or an -# OLM Subscription + OperatorGroup on OpenShift). -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: []