Skip to content

custom-routing-with-envoy: read routes from the routeserver HTTP API on 7778 - #75

Draft
scott-cotton wants to merge 1 commit into
mainfrom
scott/envoy-example-routeserver-7778
Draft

custom-routing-with-envoy: read routes from the routeserver HTTP API on 7778#75
scott-cotton wants to merge 1 commit into
mainfrom
scott/envoy-example-routeserver-7778

Conversation

@scott-cotton

Copy link
Copy Markdown
Member

Why

The lua filter in experimental/custom-routing-with-envoy fetches routes from the Route Server's legacy API on port 8080:

GET routeserver.signadot.svc.cluster.local:8080/apis/apps/v1/namespaces/httpbin/deployments/httpbin/routes

That API predates the current Route Server. In the next operator release it stops serving by default — port 8080 answers 410 Gone unless routeServer.legacyRoutesAPI.enabled is set to true — and it is removed in the release after that. So this example breaks out of the box on upgrade unless it moves.

It is the last consumer of the legacy API in this repo; every other routeserver example (pub-sub, rabbitmq, temporal, SQS) already uses :7778 with /api/v1/workloads/routing-rules.

What changed

The signadot_router cluster now points at port 7778, and the filter calls the current HTTP API, passing the baseline workload and the routing key as query parameters:

GET /api/v1/workloads/routing-rules?baselineKind=Deployment&baselineNamespace=httpbin&baselineName=httpbin&routingKey=<key>

The response walk changes shape accordingly — routingRules[] → mappings[] → destinations[], reading host/port instead of the legacy [1].routes[] → targetIP/targetPort.

Two behaviors improve rather than just move:

A request with an unmatched routing key no longer 500s. The legacy endpoint returned an array that the operator omitted entirely when the baseline had no routes, and the filter indexed parsed[1].routes into it unguarded. A routing key matching no sandbox therefore raised attempt to index a nil value in the filter — a 500 — instead of falling through to baseline. Reproduced against the current filter with the bundled JSON.lua:

LUA ERROR: attempt to index a nil value (field 'integer index')

The right port gets selected. The legacy response flattened every port mapping into a single list, so the filter took whichever destination came first regardless of which port it belonged to. This pod has two container ports — httpbin on 80 and the envoy sidecar on 8080 — so that choice was ordering-dependent. The current API keeps destinations grouped under workloadPort, and the filter now selects 80, the same port its own baseline branch forwards to (127.0.0.1:80).

Draft: needs a cluster run

The filter logic is checked, but end-to-end behavior against a live sandbox is not. What has been verified:

  • The ConfigMap and the embedded envoy.yaml parse; the signadot_router cluster resolves to port 7778
  • The filter source is valid Lua under both lua and luajit
  • The filter, driven against recorded API response shapes with a stubbed request_handle and the bundled JSON.lua: routes to the port-80 destination when a rule matches (choosing it over a port-8080 mapping listed first); falls through to baseline with no routing key, with {"routingRules":[]}, with {}, with a rule for a different key, and with a rule carrying no port-80 mapping
  • Deployed against a cluster with the operator and a real httpbin-test-sandbox — that the port-80 mapping is the one carrying the fork's reachable destination is read off the API's shape, not observed
  • baseline.png / forked.png still reflect what the walkthrough produces

Marking draft until someone can run the walkthrough in the README.

…on 7778

The lua filter fetched routes from the routeserver's legacy API on port 8080,
/apis/apps/v1/namespaces/httpbin/deployments/httpbin/routes. That API is off by
default in the next operator release and removed in the one after, so the
filter now calls GET /api/v1/workloads/routing-rules on port 7778, passing the
baseline workload and the routing key as query parameters.

Two things get better in the move. The legacy response was an array that the
operator omitted entirely when the baseline had no routes, and the filter
indexed [1] into it unguarded -- a request carrying a routing key that matched
no sandbox raised a lua error and returned 500 instead of falling through to
baseline. And the legacy shape flattened every port mapping into one list, so
the filter took whichever destination came first regardless of which port it
belonged to; this pod has two container ports (httpbin 80, envoy 8080). The
current API keeps the destinations grouped under workloadPort, so the filter
selects port 80 -- the same port its baseline branch forwards to.

Co-Authored-By: Claude Opus 5 (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