Gateway API: handle Route conflicts with HTTPRoute.Matches
Please describe the problem you have It's possible that multiple HTTPRoutes will define the same Match conditions. In this case the following logic should be applied to resolve the conflict:
- The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of “2020-09-08 01:02:03” is given precedence over a Route with a creation timestamp of “2020-09-08 01:02:04”.
- The Route appearing first in alphabetical order (namespace/name) for example, foo/bar is given precedence over foo/baz.
//ref: https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRouteRule
Neither of these rules feels truly ideal IMHO, conflict resolution can’t be just time based can it? @youngnick Has gw api upstream discussed other approaches?
It's kind of intended that there not be matching rules, so this is really an escape valve for when that happens in error. If you want multiple targets for traffic, using the same set of match criteria, then you really should be using a single HTTPRoute for it, with multiple targets inside that.
I think that this is probably a good use case to clarify route inclusion with upstream.
I'll take a crack at this now that we've updated to v1alpha2.
This will probably become a conformance issue at some point, but for now, removing from the 1.22 milestone, still open to a contributor picking this up though!
I can work on it
/assign
After reading the previous PR, https://github.com/projectcontour/contour/pull/3636, I think the biggest argument is around where to implement this check. Whether to add a different layer to do the comparison, or directly filter out duplicate route when adding the route to vhost inside dag.go.
The first one would make the layer more clear, but the code is kind of duplicate since inside here https://github.com/projectcontour/contour/blob/73864b85309cd4cdb7c98abecc47996ecc0c8e58/internal/dag/dag.go#L485-L498 we already have conditionsToString that generating the same key that we tries to filter with. So option 2 would be cleaner code.
directly filter out duplicate route when adding the route to vhost inside dag.go.
Yeah in thinking about this before for fixing up some existing possible conflicts with HTTPProxy includes, I think this is where I wanted to take things
We would need to pre-sort the routes based on name/age (conflict resolution logic listed above) so processing order is consistent, otherwise we could get into a state where iterating through the map of routes in different orders generates different resulting DAGs
MM just come to my mind, we should compare HTTPProxy'match vs HTTPRoute's match as well? So basically just compare HTTPProxy, then compare HTTPRoute on their own.
Their path/header/query could also match though
As discussed previously with @sunjayBhatia , we will compare one type of CRD at a time. Now we will only hanndle HTTPRoute.
We can add other types in follow up PR.
~~Just to confirm, a packet is matched to a route if path matched && one of query params matched && one of header matched~~
// Headers specifies HTTP request header matchers. Multiple match values are // ANDed together, meaning, a request must match all the specified headers // to select the route. // QueryParams specifies HTTP query parameter matchers. Multiple match // values are ANDed together, meaning, a request must match all the // specified query parameters to select the route.