Skip to content

feat: Rewrite Host per backend when origins differ - #508

Open
mattdjenkinson wants to merge 3 commits into
mainfrom
feat/per-backend-host-rewrite
Open

mattdjenkinson wants to merge 3 commits into
mainfrom
feat/per-backend-host-rewrite

Conversation

@mattdjenkinson

Copy link
Copy Markdown
Contributor

Summary

A load balancer splitting weighted traffic between two origins on different hostnames could not be programmed: the Host rewrite each origin needs lived on the rule, so the controller refused the pair and the proxy kept serving its old configuration while reporting Pending. Envoy Gateway already supports a separate Host rewrite per backend on the version the edge runs, and the only thing in the way was our own HTTPRoute webhook. This puts the rewrite on each backend when a rule's backends disagree, keeps today's single rule-level rewrite when they agree so no existing load balancer changes, and lets the webhook admit a hostname-only rewrite on a backend. It also corrects the merged enhancement doc, which blamed the Gateway API webhook and proposed an upstream change we don't need.

Notes for reviewers

Rules whose origins differ now get a cluster per backend rather than one merged cluster. On Envoy Gateway v1.7.4 that means a consistent-hash load balancer keeps a client on one endpoint within an origin but not on the same origin; v1.8.4 and later pin it automatically. HTTPProxy users still cannot set their own rewrite on a backend, and a rule-level Host override still takes precedence over a backend's, since reversing that would change traffic for existing proxies that set both.

Test plan

  • Unit and envtest suite passes, with new cases for origins on different hostnames, a Host override on one backend, and both webhooks
  • Lint is clean
  • Translating a 95/5 split across two origins with Envoy Gateway v1.7.4 gives each weighted cluster its own Host rewrite
  • A 95/5 split across two hosted origins on staging serves each origin's own site

Related to #473 and #481, and datum-cloud/enhancements#744.

A rule whose weighted backends need different Host rewrites could not be
programmed: the rewrite lived on the rule, so the controller refused the
pair and the proxy kept serving its previous configuration while
reporting Pending. Envoy Gateway has accepted a hostname URLRewrite on an
individual backendRef since v1.7.0, and gives each weighted cluster its
own host_rewrite_literal; the only thing stopping the controller was
this repository's HTTPRoute webhook.

Key changes:
- Put the Host rewrite on each backendRef when a rule's backends
  disagree, and drop any rule-level hostname rewrite so both never apply
- Keep the single rule-scoped rewrite when backends agree, so existing
  routes are unchanged
- Admit hostname-only URLRewrite on HTTPRoute backendRefs; HTTPProxy
  backend filters are unchanged
The proposal rested on Gateway API's webhook refusing URLRewrite on a
backendRef. Gateway API v1.5 ships no such webhook; the refusal was this
repository's own, and Envoy Gateway already supports the per-backend
rewrite on the version the edge runs.

Key changes:
- Replace the upstream modifier proposal with per-backend rewrites
- Explain why the Backend hostname modifier covers only part of the case
- Record the session affinity caveat on Envoy Gateway v1.7.4
- Drop open questions that only applied to the upstream route
@mattdjenkinson
mattdjenkinson requested a review from a team as a code owner September 26, 2026 11:54
@mattdjenkinson mattdjenkinson self-assigned this Sep 26, 2026
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.

2 participants