From 2e8cabcd630a98c35b35513fbfd31e8ad30811ef Mon Sep 17 00:00:00 2001 From: Andrew Stoltz <1578013+astoltz@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:30:24 -0500 Subject: [PATCH] platform: keep GX10 shared VIP traffic policy aligned --- gx10/platform/README.md | 1 + gx10/platform/gitea-ssh-service.yaml | 18 ++++++++++++++++++ gx10/platform/traefik-helmchart.yaml | 1 + .../FleetManifestLintTests.cs | 18 +++++++++++++----- 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 gx10/platform/gitea-ssh-service.yaml diff --git a/gx10/platform/README.md b/gx10/platform/README.md index 13f6615..947324f 100644 --- a/gx10/platform/README.md +++ b/gx10/platform/README.md @@ -9,6 +9,7 @@ ApplicationSet (`apps-gx10/*`) will own these. - `step-ca-acme.yaml` — cert-manager ClusterIssuer (ACME → noc1 step-ca, in-spec caBundle). APPLIED + Ready. - `traefik-helmchart.yaml` — Traefik v3.6.10 (chart 39.0.5) via the RKE2 HelmChart CRD, LoadBalancer VIP 10.0.57.202 (prod-pool; temp parallel-run VIP — canonical .200 reclaimed at cutover), with `externalTrafficPolicy: Local` so tenant IP allowlists see client source IP instead of the GX10 node hop. APPLIED. +- `gitea-ssh-service.yaml` — Gitea SSH LoadBalancer service sharing the Traefik VIP on port 22 with matching `externalTrafficPolicy: Local`; MetalLB requires the shared-IP services to use the same traffic policy. APPLIED. cert-manager v1.17.2 was installed separately (upstream static manifest). See `docs/ai-agents/gx10-migration-continuation-2026-06-14.md` + memory diff --git a/gx10/platform/gitea-ssh-service.yaml b/gx10/platform/gitea-ssh-service.yaml new file mode 100644 index 0000000..2dea9e1 --- /dev/null +++ b/gx10/platform/gitea-ssh-service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: gitea-ssh + namespace: gitea + annotations: + metallb.io/allow-shared-ip: gitea-traefik-202 + metallb.universe.tf/loadBalancerIPs: 10.0.57.202 +spec: + type: LoadBalancer + externalTrafficPolicy: Local + selector: + app: gitea + ports: + - name: ssh + port: 22 + protocol: TCP + targetPort: 2222 diff --git a/gx10/platform/traefik-helmchart.yaml b/gx10/platform/traefik-helmchart.yaml index a26f34a..1562453 100644 --- a/gx10/platform/traefik-helmchart.yaml +++ b/gx10/platform/traefik-helmchart.yaml @@ -15,6 +15,7 @@ spec: spec: externalTrafficPolicy: Local annotations: + metallb.io/allow-shared-ip: gitea-traefik-202 metallb.universe.tf/address-pool: prod-pool metallb.universe.tf/loadBalancerIPs: 10.0.57.202 ingressClass: diff --git a/tests/bluejay-infra-lint/FleetManifestLintTests.cs b/tests/bluejay-infra-lint/FleetManifestLintTests.cs index 81ab175..0e8aa8a 100644 --- a/tests/bluejay-infra-lint/FleetManifestLintTests.cs +++ b/tests/bluejay-infra-lint/FleetManifestLintTests.cs @@ -250,13 +250,21 @@ public sealed class FleetManifestLintTests } [Fact] - public void Gx10TraefikLoadBalancer_MustPreserveClientSourceIp() + public void Gx10SharedVipLoadBalancers_MustPreserveClientSourceIp() { - var path = Path.Combine(Inventory.BluejayRoot, "gx10", "platform", "traefik-helmchart.yaml"); - var manifest = File.ReadAllText(path); + var traefikPath = Path.Combine(Inventory.BluejayRoot, "gx10", "platform", "traefik-helmchart.yaml"); + var traefik = File.ReadAllText(traefikPath); - manifest.Should().Contain("metallb.universe.tf/loadBalancerIPs: 10.0.57.202"); - manifest.Should().Contain("spec:\n externalTrafficPolicy: Local"); + traefik.Should().Contain("metallb.io/allow-shared-ip: gitea-traefik-202"); + traefik.Should().Contain("metallb.universe.tf/loadBalancerIPs: 10.0.57.202"); + traefik.Should().Contain("spec:\n externalTrafficPolicy: Local"); + + var giteaPath = Path.Combine(Inventory.BluejayRoot, "gx10", "platform", "gitea-ssh-service.yaml"); + var gitea = File.ReadAllText(giteaPath); + + gitea.Should().Contain("metallb.io/allow-shared-ip: gitea-traefik-202"); + gitea.Should().Contain("metallb.universe.tf/loadBalancerIPs: 10.0.57.202"); + gitea.Should().Contain("externalTrafficPolicy: Local"); } [Fact]