Skip to content

Commit 2bab77a

Browse files
authored
fix: record attachedRoutes and supportedkinds for gateway status (#2670)
1 parent 466ea42 commit 2bab77a

File tree

6 files changed

+530
-75
lines changed

6 files changed

+530
-75
lines changed

internal/controller/gateway_controller.go

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"context"
2222
"errors"
2323
"fmt"
24-
"reflect"
2524

2625
"github.com/go-logr/logr"
2726
corev1 "k8s.io/api/core/v1"
@@ -35,6 +34,7 @@ import (
3534
"sigs.k8s.io/controller-runtime/pkg/predicate"
3635
"sigs.k8s.io/controller-runtime/pkg/reconcile"
3736
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
37+
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
3838
"sigs.k8s.io/gateway-api/apis/v1beta1"
3939

4040
"github.com/apache/apisix-ingress-controller/api/v1alpha1"
@@ -62,13 +62,10 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
6262
For(
6363
&gatewayv1.Gateway{},
6464
builder.WithPredicates(
65-
predicate.NewPredicateFuncs(r.checkGatewayClass),
66-
),
67-
).
68-
WithEventFilter(
69-
predicate.Or(
70-
predicate.GenerationChangedPredicate{},
71-
predicate.NewPredicateFuncs(TypePredicate[*corev1.Secret]()),
65+
predicate.And(
66+
predicate.NewPredicateFuncs(r.checkGatewayClass),
67+
predicate.GenerationChangedPredicate{},
68+
),
7269
),
7370
).
7471
Watches(
@@ -80,7 +77,23 @@ func (r *GatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
8077
).
8178
Watches(
8279
&gatewayv1.HTTPRoute{},
83-
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForHTTPRoute),
80+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
81+
).
82+
Watches(
83+
&gatewayv1.GRPCRoute{},
84+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
85+
).
86+
Watches(
87+
&gatewayv1alpha2.TCPRoute{},
88+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
89+
).
90+
Watches(
91+
&gatewayv1alpha2.TLSRoute{},
92+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
93+
).
94+
Watches(
95+
&gatewayv1alpha2.UDPRoute{},
96+
handler.EnqueueRequestsFromMapFunc(r.listGatewaysForStatusParentRefs),
8497
).
8598
Watches(
8699
&v1alpha1.GatewayProxy{},
@@ -300,19 +313,11 @@ func (r *GatewayReconciler) listGatewaysForGatewayProxy(ctx context.Context, obj
300313
return recs
301314
}
302315

303-
func (r *GatewayReconciler) listGatewaysForHTTPRoute(ctx context.Context, obj client.Object) []reconcile.Request {
304-
httpRoute, ok := obj.(*gatewayv1.HTTPRoute)
305-
if !ok {
306-
r.Log.Error(
307-
fmt.Errorf("unexpected object type"),
308-
"HTTPRoute watch predicate received unexpected object type",
309-
"expected", "*gatewayapi.HTTPRoute", "found", reflect.TypeOf(obj),
310-
)
311-
return nil
312-
}
313-
recs := []reconcile.Request{}
314-
for _, routeParentStatus := range httpRoute.Status.Parents {
315-
gatewayNamespace := httpRoute.GetNamespace()
316+
func (r *GatewayReconciler) listGatewaysForStatusParentRefs(ctx context.Context, obj client.Object) []reconcile.Request {
317+
route := internaltypes.NewRouteAdapter(obj)
318+
reqs := []reconcile.Request{}
319+
for _, routeParentStatus := range route.GetParentStatuses() {
320+
gatewayNamespace := route.GetNamespace()
316321
parentRef := routeParentStatus.ParentRef
317322
if parentRef.Group != nil && *parentRef.Group != gatewayv1.GroupName {
318323
continue
@@ -336,14 +341,14 @@ func (r *GatewayReconciler) listGatewaysForHTTPRoute(ctx context.Context, obj cl
336341
continue
337342
}
338343

339-
recs = append(recs, reconcile.Request{
344+
reqs = append(reqs, reconcile.Request{
340345
NamespacedName: client.ObjectKey{
341346
Namespace: gatewayNamespace,
342347
Name: string(parentRef.Name),
343348
},
344349
})
345350
}
346-
return recs
351+
return reqs
347352
}
348353

349354
func (r *GatewayReconciler) listGatewaysForSecret(ctx context.Context, obj client.Object) (requests []reconcile.Request) {

internal/controller/utils.go

Lines changed: 108 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ func ParseRouteParentRefs(
376376
}
377377
}
378378

379-
if !routeMatchesListenerType(route, listener) {
379+
if ok, _ := routeMatchesListenerType(route, listener); !ok {
380380
continue
381381
}
382382

@@ -475,8 +475,8 @@ func checkRouteAcceptedByListener(
475475
return false, gatewayv1.RouteReasonNoMatchingParent, nil
476476
}
477477
}
478-
if !routeMatchesListenerType(route, listener) {
479-
return false, gatewayv1.RouteReasonNoMatchingParent, nil
478+
if ok, err := routeMatchesListenerType(route, listener); !ok {
479+
return false, gatewayv1.RouteReasonNoMatchingParent, err
480480
}
481481
if !routeHostnamesIntersectsWithListenerHostname(route, listener) {
482482
return false, gatewayv1.RouteReasonNoMatchingListenerHostname, nil
@@ -649,71 +649,95 @@ func isRouteNamespaceAllowed(
649649
}
650650
}
651651

652-
func routeMatchesListenerType(route client.Object, listener gatewayv1.Listener) bool {
652+
func routeMatchesListenerType(route client.Object, listener gatewayv1.Listener) (bool, error) {
653653
switch route.(type) {
654654
case *gatewayv1.HTTPRoute, *gatewayv1.GRPCRoute:
655655
if listener.Protocol != gatewayv1.HTTPProtocolType && listener.Protocol != gatewayv1.HTTPSProtocolType {
656-
return false
656+
return false, nil
657657
}
658658

659659
if listener.Protocol == gatewayv1.HTTPSProtocolType {
660660
if listener.TLS == nil {
661-
return false
661+
return false, nil
662662
}
663663

664664
if listener.TLS.Mode != nil && *listener.TLS.Mode != gatewayv1.TLSModeTerminate {
665-
return false
665+
return false, nil
666666
}
667667
}
668668
case *gatewayv1alpha2.TCPRoute:
669669
if listener.Protocol != gatewayv1.TCPProtocolType {
670-
return false
670+
return false, nil
671671
}
672672
case *gatewayv1alpha2.UDPRoute:
673673
if listener.Protocol != gatewayv1.UDPProtocolType {
674-
return false
674+
return false, nil
675675
}
676676
case *gatewayv1alpha2.TLSRoute:
677677
if listener.Protocol != gatewayv1.TLSProtocolType {
678-
return false
678+
return false, nil
679679
}
680680
default:
681-
return false
681+
return false, fmt.Errorf("unsupported route type %T", route)
682682
}
683-
return true
683+
return true, nil
684684
}
685685

686686
func getAttachedRoutesForListener(ctx context.Context, mgrc client.Client, gateway gatewayv1.Gateway, listener gatewayv1.Listener) (int32, error) {
687-
httpRouteList := gatewayv1.HTTPRouteList{}
688-
if err := mgrc.List(ctx, &httpRouteList); err != nil {
689-
return 0, err
687+
routes := []types.RouteAdapter{}
688+
routeList := []client.ObjectList{}
689+
690+
listOption := client.MatchingFields{
691+
indexer.ParentRefs: indexer.GenIndexKey(gateway.Namespace, gateway.Name),
690692
}
691-
var attachedRoutes int32
692-
for _, route := range httpRouteList.Items {
693-
route := route
694-
acceptedByGateway := lo.ContainsBy(route.Status.Parents, func(parentStatus gatewayv1.RouteParentStatus) bool {
695-
parentRef := parentStatus.ParentRef
696-
if parentRef.Group != nil && *parentRef.Group != gatewayv1.GroupName {
697-
return false
698-
}
699-
if parentRef.Kind != nil && *parentRef.Kind != KindGateway {
700-
return false
693+
if listener.AllowedRoutes != nil && listener.AllowedRoutes.Kinds != nil {
694+
for _, rgk := range listener.AllowedRoutes.Kinds {
695+
if rgk.Group != nil && *rgk.Group != gatewayv1.GroupName {
696+
continue
701697
}
702-
gatewayNamespace := route.Namespace
703-
if parentRef.Namespace != nil {
704-
gatewayNamespace = string(*parentRef.Namespace)
698+
switch rgk.Kind {
699+
case types.KindHTTPRoute:
700+
routeList = append(routeList, &gatewayv1.HTTPRouteList{})
701+
case types.KindGRPCRoute:
702+
routeList = append(routeList, &gatewayv1.GRPCRouteList{})
703+
case types.KindTCPRoute:
704+
routeList = append(routeList, &gatewayv1alpha2.TCPRouteList{})
705+
case types.KindUDPRoute:
706+
routeList = append(routeList, &gatewayv1alpha2.UDPRouteList{})
707+
case types.KindTLSRoute:
708+
routeList = append(routeList, &gatewayv1alpha2.TLSRouteList{})
705709
}
706-
return gateway.Namespace == gatewayNamespace && gateway.Name == string(parentRef.Name)
707-
})
708-
if !acceptedByGateway {
709-
continue
710710
}
711+
} else {
712+
switch listener.Protocol {
713+
case gatewayv1.HTTPProtocolType, gatewayv1.HTTPSProtocolType:
714+
routeList = append(routeList, &gatewayv1.HTTPRouteList{}, &gatewayv1.GRPCRouteList{})
715+
case gatewayv1.TCPProtocolType:
716+
routeList = append(routeList, &gatewayv1alpha2.TCPRouteList{})
717+
case gatewayv1.UDPProtocolType:
718+
routeList = append(routeList, &gatewayv1alpha2.UDPRouteList{})
719+
case gatewayv1.TLSProtocolType:
720+
routeList = append(routeList, &gatewayv1alpha2.TLSRouteList{})
721+
}
722+
}
723+
724+
for _, rl := range routeList {
725+
if err := mgrc.List(ctx, rl, listOption); err != nil {
726+
return 0, fmt.Errorf("failed to list %T: %w", rl, err)
727+
}
728+
routes = append(routes, types.NewRouteListAdapter(rl)...)
729+
}
711730

712-
for _, parentRef := range route.Spec.ParentRefs {
731+
var attachedRoutes int32
732+
for _, route := range routes {
733+
if !checkStatusParent(route.GetParentStatuses(), route.GetNamespace(), gateway) {
734+
continue
735+
}
736+
for _, parentRef := range route.GetParentRefs() {
713737
ok, _, err := checkRouteAcceptedByListener(
714738
ctx,
715739
mgrc,
716-
&route,
740+
route.GetObject(),
717741
gateway,
718742
listener,
719743
parentRef,
@@ -729,13 +753,29 @@ func getAttachedRoutesForListener(ctx context.Context, mgrc client.Client, gatew
729753
return attachedRoutes, nil
730754
}
731755

756+
func checkStatusParent(parents []gatewayv1.RouteParentStatus, routeNamespace string, gateway gatewayv1.Gateway) bool {
757+
return lo.ContainsBy(parents, func(parentStatus gatewayv1.RouteParentStatus) bool {
758+
parentRef := parentStatus.ParentRef
759+
if parentRef.Group != nil && *parentRef.Group != gatewayv1.GroupName {
760+
return false
761+
}
762+
if parentRef.Kind != nil && *parentRef.Kind != KindGateway {
763+
return false
764+
}
765+
gatewayNamespace := routeNamespace
766+
if parentRef.Namespace != nil {
767+
gatewayNamespace = string(*parentRef.Namespace)
768+
}
769+
return gateway.Namespace == gatewayNamespace && gateway.Name == string(parentRef.Name)
770+
})
771+
}
772+
732773
func getListenerStatus(
733774
ctx context.Context,
734775
mrgc client.Client,
735776
gateway *gatewayv1.Gateway,
736777
) ([]gatewayv1.ListenerStatus, error) {
737-
statuses := make(map[gatewayv1.SectionName]gatewayv1.ListenerStatus, len(gateway.Spec.Listeners))
738-
778+
statusArray := make([]gatewayv1.ListenerStatus, 0, len(gateway.Spec.Listeners))
739779
for i, listener := range gateway.Spec.Listeners {
740780
attachedRoutes, err := getAttachedRoutesForListener(ctx, mrgc, *gateway, listener)
741781
if err != nil {
@@ -776,10 +816,35 @@ func getListenerStatus(
776816
)
777817

778818
if listener.AllowedRoutes == nil || listener.AllowedRoutes.Kinds == nil {
779-
supportedKinds = []gatewayv1.RouteGroupKind{
780-
{
781-
Kind: KindHTTPRoute,
782-
},
819+
group := gatewayv1.Group(gatewayv1.GroupName)
820+
supportedKinds = []gatewayv1.RouteGroupKind{}
821+
switch listener.Protocol {
822+
case gatewayv1.TLSProtocolType:
823+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
824+
Group: &group,
825+
Kind: types.KindTLSRoute,
826+
})
827+
case gatewayv1.TCPProtocolType:
828+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
829+
Group: &group,
830+
Kind: types.KindTCPRoute,
831+
})
832+
case gatewayv1.UDPProtocolType:
833+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
834+
Group: &group,
835+
Kind: types.KindUDPRoute,
836+
})
837+
case gatewayv1.HTTPProtocolType, gatewayv1.HTTPSProtocolType:
838+
supportedKinds = append(supportedKinds, []gatewayv1.RouteGroupKind{
839+
{
840+
Group: &group,
841+
Kind: types.KindGRPCRoute,
842+
},
843+
{
844+
Group: &group,
845+
Kind: types.KindHTTPRoute,
846+
},
847+
}...)
783848
}
784849
} else {
785850
for _, kind := range listener.AllowedRoutes.Kinds {
@@ -789,7 +854,7 @@ func getListenerStatus(
789854
continue
790855
}
791856
switch kind.Kind {
792-
case KindHTTPRoute:
857+
case KindHTTPRoute, types.KindGRPCRoute, types.KindTLSRoute, types.KindTCPRoute, types.KindUDPRoute:
793858
supportedKinds = append(supportedKinds, kind)
794859
default:
795860
conditionResolvedRefs.Status = metav1.ConditionFalse
@@ -892,17 +957,9 @@ func getListenerStatus(
892957
changed = true
893958
}
894959

895-
if changed {
896-
statuses[listener.Name] = status
897-
} else {
898-
statuses[listener.Name] = gateway.Status.Listeners[i]
960+
if !changed {
961+
status = gateway.Status.Listeners[i]
899962
}
900-
}
901-
902-
// check for conflicts
903-
904-
statusArray := []gatewayv1.ListenerStatus{}
905-
for _, status := range statuses {
906963
statusArray = append(statusArray, status)
907964
}
908965

0 commit comments

Comments
 (0)