Skip to content

feat(api-server): aggregator + pod/service proxy fixes#45

Open
indyjonesnl wants to merge 2 commits into
calfonso:mainfrom
indyjonesnl:upstream/api-server-proxy
Open

feat(api-server): aggregator + pod/service proxy fixes#45
indyjonesnl wants to merge 2 commits into
calfonso:mainfrom
indyjonesnl:upstream/api-server-proxy

Conversation

@indyjonesnl
Copy link
Copy Markdown

Changes

Two proxy-layer features required by conformance.

`feat: pod/service proxy preserves trailing slash and named ports`

The `/api/v1/namespaces/{ns}/pods/{name}/proxy/{path...}` (and the service equivalent) had two K8s-conformance bugs:

  • Trailing slash: `.../proxy/foo/` was rewritten to `http://:/foo` (slash lost). Backends that rely on path semantics (autoindex, redirects) misbehaved. Now we preserve the trailing slash byte-for-byte.
  • Named ports: when the proxy URL specified a port by name (`...pods/web/proxy:http:/...`), we passed the literal string "http" as a port. Resolve named ports to the numeric value by looking up the matching `container.ports[].name` on the pod, falling back to the service `spec.ports[]` for service proxies.

`feat(api-server): aggregator forwards auth, body, query to APIService backends`

Aggregated APIService backends (e.g., metrics-server) received bare GETs with no Authorization header, no request body, and no query string. Now the aggregator copies:

  • The `Authorization` header (passing the caller's token through).
  • The request body (so POST/PUT/PATCH against an aggregated API work).
  • The full URL query string.
    plus sets X-Remote-* headers for the backend's auth chain.

Verification

`cargo build --workspace --locked` clean. Depends on #32 for green CI.

indyjonesnl and others added 2 commits May 14, 2026 18:20
Match upstream Kubernetes v1.35 semantics for `/proxy/{path}` subresources
so that conformance tests "Proxy through service + pod" pass:

- Use `OriginalUri` to read the request path verbatim, preserving any
  trailing slash so `/proxy/foo/` is forwarded to the backend as `/foo/`
  (and `/proxy/foo` as `/foo`). The previous code stripped the trailing
  slash via Axum's `*path` capture.
- Forward the raw query string instead of rebuilding it from a
  `HashMap`. The HashMap form lost ordering, duplicate keys, and exact
  encoding — all observable to backends.
- Map the HTTP method to the K8s authorization verb (GET→get, POST→
  create, PUT→update, PATCH→patch, DELETE→delete) for the
  `pods/proxy`, `services/proxy`, and `nodes/proxy` subresources, so
  RBAC rules can scope mutations separately from reads.
- Resolve `pod:portname` style URLs against named container ports
  across all containers in the pod, matching `pkg/registry/core/pod/
  strategy.go ResourceLocation`.

Adds 11 new unit tests covering verb mapping, trailing-slash
preservation, encoded characters, and named-port resolution; plus an
integration test confirming a pod's named container port survives a
storage round trip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… backends

Closes a slice of the v1.35 conformance gap for the
[Conformance].*Aggregator.*sample tests. The router's APIService proxy now
mirrors kube-aggregator semantics: it forwards the request body, query
string, and an impersonation header set (X-Remote-User, X-Remote-Group,
X-Remote-Extra-*) so the backend can authorise the original caller, while
dropping the inbound Authorization to prevent token leakage. TLS uses the
APIService caBundle when present and honours insecureSkipTLSVerify.

The /apis discovery list now merges in groups registered via APIService so
clients can discover aggregated APIs. create_apiservice no longer claims
Available=True for service-backed APIServices on creation — it now seeds
Available=Unknown/Pending and lets the APIServiceAvailabilityController
drive the truth.

Tests cover header construction (impersonation + allow-list + Authorization
drop), target resolution (ClusterIP / Endpoints / 503), discovery merge,
query-string forwarding, and the unreachable-backend 503 path against a
warp mock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant