gloo
gloo copied to clipboard
Support RouteTable delegation where the RT path is more general than the parent VS Route path
Is your feature request related to a problem? Please describe.
I would like to have 1 RouteTable owned by each application team. This RT would be delegated from multiple VirtualServices where each VS would map to a single domain. The paths for the RT will vary depending on the domain. The RT paths may be more general than the VS route delegateAction path. For example:
VS1 domain: foo.com path: / name: slash
VS2 domains: bar.com path /bar name: bar
Shared RT: path: / name: slash
path:/bar name: bar
However, this results in invalid route: route table matchers must begin with the prefix of their parent route's matcher
Describe the solution you'd like
Allow RTs to have more general paths than the parent VS
Describe alternatives you've considered
Multiple RTs or use VSs only
┆Issue is synchronized with this Asana task by Unito
Firming up the desired design ...
The relaxed validation would require that the route(s) in the VS(s) and RT(s) 1) would be named and 2) that the parent and child names and paths would need to match to be valid. This would not require any changes to the CRDs.
With the attached sample config envoy would be configured with 2 routes: foo.com/user/inbox bar.com/
@bdecoste can we either here or in slack write up some user stories around this. While the ask is not crazy before we tackle the relaxation there might be some other implementation details that really wont be done correctly if we dont understand the different ways that we are intending to interact with this.
route tables can select other route tables. how would this design prevent cycles?
perhaps we can allow child route tables to have many matches, and if any work then we generate the appropriate route. this way there can be several parents with different parent routes, and still only one route defined on one route table.
The key to the suggested config change is only match the VS parent routes with the RT child routes that have the same name. Then you never get a more general child matcher
I have another customer that could be interested in this (legacy purpose).
They would like to be able to handle /api/v1
and /v1
by the same RT (and strip the /api
at the same time when it exists).
Using regex
or multiple prefix
is not working with delegated RT as expressed here.
Their workaround for now is to have a vanilla envoy in front of GE gateway to be able to strip the /api
before getting to the gateway so the routing can be done by an unique route (on /v1
).
The only workaround without 3rd part would be to avoid the use of RT but with very large routing configuration this solution is not confortable.
Here is an example of what could answer their problematic (alternative to multiple prefix
could be regex
matchers on ^(/api)?/v1/.*
and ^(/api)?/v2/.*
, but the customer is used to prefix
, more generally regex
would be more flexible but less efficient) :
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: vs-ssl
namespace: gloo-system
spec:
virtualHost:
domains:
- '*'
routes:
- matchers:
- prefix: /api/v1
- prefix: /v1
options:
regexRewrite:
pattern:
regex: ^/api
substitution: ""
delegateAction:
ref:
name: 'v1-routes'
namespace: 'gloo-system'
- matchers:
- prefix: /api/v2
- prefix: /v2
options:
regexRewrite:
pattern:
regex: ^/api
substitution: ""
delegateAction:
ref:
name: 'v2-routes'
namespace: 'gloo-system'
sslConfig:
secretRef:
name: upstream-tls
namespace: gloo-system
And delegated RT :
apiVersion: gateway.solo.io/v1
kind: RouteTable
metadata:
name: 'v1-routes'
namespace: 'gloo-system'
spec:
routes:
- matchers:
- prefix: '/v1'
routeAction:
single:
upstream:
name: httpbin-httpbin-8000
namespace: gloo-system
apiVersion: gateway.solo.io/v1
kind: RouteTable
metadata:
name: 'v2-routes'
namespace: 'gloo-system'
spec:
routes:
- matchers:
- prefix: '/v2'
routeAction:
single:
upstream:
name: httpbin-httpbin-8000
namespace: gloo-system
@sam-heilbron to look at this issue for scope/estimation.
One thing we should make sure is that we don't allow child-routes to expose apps/services on paths that are not defined in the parent route. I.e, when we expose the following on the VS:
domain: api.example.com
- matchers:
- prefix: /foo
And the following on the child:
- matchers:
- prefix: /foo
......
- prefix: /bar
.......
we should only create a route for /foo
on the given VS for api.example.com
. If we would also create a route for /bar
, we would give teams owning the child rt to expose routes on the GW that team that owns the parent is not aware of.
Repository with an example how this can be implement with Gloo Gateway 1.17 and the K8S Gateway API: https://github.com/DuncanDoyle/gg-8134
So this requirement can already be implemented with the relative/inheritable path matchers in the K8S Gateway API. The "classic" Gloo Edge API does not (yet) support this.