Skip to content

Commit

Permalink
Fix Gateway-Route attachment rules relating to "Kind"
Browse files Browse the repository at this point in the history
We had the sense backward so we were rejecting valid routes.
  • Loading branch information
caboteria committed Jun 24, 2024
1 parent ecbb4cc commit ea5490e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
2 changes: 1 addition & 1 deletion controllers/gateway/tcproute_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (r *TCPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
}

// Make sure that the Gateway will allow this Route to attach
if err := gateway.GatewayAllowsTCPRoute(gw, route); err != nil {
if !gateway.GatewayAllowsTCPRoute(gw, route) {
// Update the Route's status
if err := markRouteRejected(ctx, r.Client, l, client.ObjectKey{Namespace: route.GetNamespace(), Name: route.GetName()}); err != nil {
return controllers.Done, err
Expand Down
42 changes: 22 additions & 20 deletions internal/gateway/gateway.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package gateway

import (
"fmt"

"k8s.io/apimachinery/pkg/labels"

meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -33,7 +31,7 @@ func GatewayEPICUID(gw gatewayapi.Gateway) string {
// route. If error is nil then route is allowed, but if it's non-nil
// then gw has rejected route.
func GatewayAllowsHTTPRoute(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute, fetcher dag.Fetcher) *meta_v1.Condition {
if err := GatewayAllowsKind(gw, (*gatewayapi.Kind)(&route.Kind)); err != nil {
if !GatewayAllowsKind(gw, (*gatewayapi.Kind)(&route.Kind)) {
return &meta_v1.Condition{
Type: string(gatewayapi.RouteConditionAccepted),
Reason: string(gatewayapi.RouteReasonInvalidKind),
Expand All @@ -42,12 +40,12 @@ func GatewayAllowsHTTPRoute(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute, f
}
}

if err := GatewayAllowsHostnames(gw, route); err != nil {
if !GatewayAllowsHostnames(gw, route) {
return &meta_v1.Condition{
Type: string(gatewayapi.RouteConditionAccepted),
Reason: string(gatewayapi.RouteReasonNoMatchingListenerHostname),
Status: meta_v1.ConditionFalse,
Message: "Reference not allowed by parent",
Message: "Reference Hostname not allowed by parent",
}
}

Expand All @@ -62,7 +60,7 @@ func GatewayAllowsHTTPRoute(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute, f
Type: string(gatewayapi.RouteConditionAccepted),
Reason: string(gatewayapi.RouteReasonNotAllowedByListeners),
Status: meta_v1.ConditionFalse,
Message: "Reference not allowed by parent",
Message: "Reference Listener not allowed by parent",
}
}

Expand All @@ -72,51 +70,55 @@ func GatewayAllowsHTTPRoute(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute, f
// GatewayAllowsHTTPRoute determines whether or not gw allows
// route. If error is nil then route is allowed, but if it's non-nil
// then gw has rejected route.
func GatewayAllowsTCPRoute(gw gatewayapi.Gateway, route gatewayapi_v1alpha2.TCPRoute) error {
func GatewayAllowsTCPRoute(gw gatewayapi.Gateway, route gatewayapi_v1alpha2.TCPRoute) bool {
return GatewayAllowsKind(gw, (*gatewayapi.Kind)(&route.Kind))
}

// GatewayAllowsHTTPRoute determines whether or not gw allows route's
// hostnames. If error is nil then route's hostnames are allowed, but
// if it's non-nil then there's no intersection between gw's hostnames
// and route's hostnames.
func GatewayAllowsHostnames(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute) error {
func GatewayAllowsHostnames(gw gatewayapi.Gateway, route gatewayapi.HTTPRoute) bool {
for _, listener := range gw.Spec.Listeners {
hosts, errs := dag.ComputeHosts(route.Spec.Hostnames, listener.Hostname)

// If any of the Route's hostnames are invalid then the Route
// can't be used
if errs != nil {
return errs[0]
return false
}

// If there's an intersection between the Route's hostnames and
// the Listener's hostnames then we can use the Route
if len(hosts) != 0 {
return nil
return true
}
}

return fmt.Errorf("No intersecting hostnames between gateway %s and route %s", gw.Name, route.Name)
return false
}

// GatewayAllowsKind checks whether gw allows attachment by
// routeKind. If error is nil then attachment is allowed but if not
// then it isn't.
func GatewayAllowsKind(gw gatewayapi.Gateway, routeKind *gatewayapi.Kind) error {
func GatewayAllowsKind(gw gatewayapi.Gateway, routeKind *gatewayapi.Kind) bool {
for _, listener := range gw.Spec.Listeners {
if err := allowsKind(listener.AllowedRoutes, routeKind); err != nil {
return err
if kindsIntersect(listener.AllowedRoutes, routeKind) {
return true
}
}
return nil
return false
}

func allowsKind(allow *gatewayapi.AllowedRoutes, routeKind *gatewayapi.Kind) error {
for _, gk := range allow.Kinds {
if &gk.Kind != routeKind {
return fmt.Errorf("Kind mismatch: %s vs %s", gk.Kind, *routeKind)
func kindsIntersect(allowedKinds *gatewayapi.AllowedRoutes, routeKind *gatewayapi.Kind) bool {
allowed := allowedKinds.Kinds
if len(allowedKinds.Kinds) == 0 {
allowed = []gatewayapi.RouteGroupKind{{Kind: "HTTPRoute"}}
}
for _, gk := range allowed {
if gk.Kind == *routeKind {
return true
}
}
return nil
return false
}

0 comments on commit ea5490e

Please sign in to comment.