Skip to content

Commit fdbed99

Browse files
ronethingAlinsRan
andauthored
fix: record attachedRoutes and supportedkinds for gateway status (#2670) (#380)
Co-authored-by: AlinsRan <alinsran@apache.org>
1 parent 5ddd55a commit fdbed99

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{},
@@ -304,19 +317,11 @@ func (r *GatewayReconciler) listGatewaysForGatewayProxy(ctx context.Context, obj
304317
return recs
305318
}
306319

307-
func (r *GatewayReconciler) listGatewaysForHTTPRoute(ctx context.Context, obj client.Object) []reconcile.Request {
308-
httpRoute, ok := obj.(*gatewayv1.HTTPRoute)
309-
if !ok {
310-
r.Log.Error(
311-
fmt.Errorf("unexpected object type"),
312-
"HTTPRoute watch predicate received unexpected object type",
313-
"expected", "*gatewayapi.HTTPRoute", "found", reflect.TypeOf(obj),
314-
)
315-
return nil
316-
}
317-
recs := []reconcile.Request{}
318-
for _, routeParentStatus := range httpRoute.Status.Parents {
319-
gatewayNamespace := httpRoute.GetNamespace()
320+
func (r *GatewayReconciler) listGatewaysForStatusParentRefs(ctx context.Context, obj client.Object) []reconcile.Request {
321+
route := internaltypes.NewRouteAdapter(obj)
322+
reqs := []reconcile.Request{}
323+
for _, routeParentStatus := range route.GetParentStatuses() {
324+
gatewayNamespace := route.GetNamespace()
320325
parentRef := routeParentStatus.ParentRef
321326
if parentRef.Group != nil && *parentRef.Group != gatewayv1.GroupName {
322327
continue
@@ -340,14 +345,14 @@ func (r *GatewayReconciler) listGatewaysForHTTPRoute(ctx context.Context, obj cl
340345
continue
341346
}
342347

343-
recs = append(recs, reconcile.Request{
348+
reqs = append(reqs, reconcile.Request{
344349
NamespacedName: client.ObjectKey{
345350
Namespace: gatewayNamespace,
346351
Name: string(parentRef.Name),
347352
},
348353
})
349354
}
350-
return recs
355+
return reqs
351356
}
352357

353358
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
@@ -386,7 +386,7 @@ func ParseRouteParentRefs(
386386
}
387387
}
388388

389-
if !routeMatchesListenerType(route, listener) {
389+
if ok, _ := routeMatchesListenerType(route, listener); !ok {
390390
continue
391391
}
392392

@@ -485,8 +485,8 @@ func checkRouteAcceptedByListener(
485485
return false, gatewayv1.RouteReasonNoMatchingParent, nil
486486
}
487487
}
488-
if !routeMatchesListenerType(route, listener) {
489-
return false, gatewayv1.RouteReasonNoMatchingParent, nil
488+
if ok, err := routeMatchesListenerType(route, listener); !ok {
489+
return false, gatewayv1.RouteReasonNoMatchingParent, err
490490
}
491491
if !routeHostnamesIntersectsWithListenerHostname(route, listener) {
492492
return false, gatewayv1.RouteReasonNoMatchingListenerHostname, nil
@@ -659,71 +659,95 @@ func isRouteNamespaceAllowed(
659659
}
660660
}
661661

662-
func routeMatchesListenerType(route client.Object, listener gatewayv1.Listener) bool {
662+
func routeMatchesListenerType(route client.Object, listener gatewayv1.Listener) (bool, error) {
663663
switch route.(type) {
664664
case *gatewayv1.HTTPRoute, *gatewayv1.GRPCRoute:
665665
if listener.Protocol != gatewayv1.HTTPProtocolType && listener.Protocol != gatewayv1.HTTPSProtocolType {
666-
return false
666+
return false, nil
667667
}
668668

669669
if listener.Protocol == gatewayv1.HTTPSProtocolType {
670670
if listener.TLS == nil {
671-
return false
671+
return false, nil
672672
}
673673

674674
if listener.TLS.Mode != nil && *listener.TLS.Mode != gatewayv1.TLSModeTerminate {
675-
return false
675+
return false, nil
676676
}
677677
}
678678
case *gatewayv1alpha2.TCPRoute:
679679
if listener.Protocol != gatewayv1.TCPProtocolType {
680-
return false
680+
return false, nil
681681
}
682682
case *gatewayv1alpha2.UDPRoute:
683683
if listener.Protocol != gatewayv1.UDPProtocolType {
684-
return false
684+
return false, nil
685685
}
686686
case *gatewayv1alpha2.TLSRoute:
687687
if listener.Protocol != gatewayv1.TLSProtocolType {
688-
return false
688+
return false, nil
689689
}
690690
default:
691-
return false
691+
return false, fmt.Errorf("unsupported route type %T", route)
692692
}
693-
return true
693+
return true, nil
694694
}
695695

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

722-
for _, parentRef := range route.Spec.ParentRefs {
741+
var attachedRoutes int32
742+
for _, route := range routes {
743+
if !checkStatusParent(route.GetParentStatuses(), route.GetNamespace(), gateway) {
744+
continue
745+
}
746+
for _, parentRef := range route.GetParentRefs() {
723747
ok, _, err := checkRouteAcceptedByListener(
724748
ctx,
725749
mgrc,
726-
&route,
750+
route.GetObject(),
727751
gateway,
728752
listener,
729753
parentRef,
@@ -739,13 +763,29 @@ func getAttachedRoutesForListener(ctx context.Context, mgrc client.Client, gatew
739763
return attachedRoutes, nil
740764
}
741765

766+
func checkStatusParent(parents []gatewayv1.RouteParentStatus, routeNamespace string, gateway gatewayv1.Gateway) bool {
767+
return lo.ContainsBy(parents, func(parentStatus gatewayv1.RouteParentStatus) bool {
768+
parentRef := parentStatus.ParentRef
769+
if parentRef.Group != nil && *parentRef.Group != gatewayv1.GroupName {
770+
return false
771+
}
772+
if parentRef.Kind != nil && *parentRef.Kind != KindGateway {
773+
return false
774+
}
775+
gatewayNamespace := routeNamespace
776+
if parentRef.Namespace != nil {
777+
gatewayNamespace = string(*parentRef.Namespace)
778+
}
779+
return gateway.Namespace == gatewayNamespace && gateway.Name == string(parentRef.Name)
780+
})
781+
}
782+
742783
func getListenerStatus(
743784
ctx context.Context,
744785
mrgc client.Client,
745786
gateway *gatewayv1.Gateway,
746787
) ([]gatewayv1.ListenerStatus, error) {
747-
statuses := make(map[gatewayv1.SectionName]gatewayv1.ListenerStatus, len(gateway.Spec.Listeners))
748-
788+
statusArray := make([]gatewayv1.ListenerStatus, 0, len(gateway.Spec.Listeners))
749789
for i, listener := range gateway.Spec.Listeners {
750790
attachedRoutes, err := getAttachedRoutesForListener(ctx, mrgc, *gateway, listener)
751791
if err != nil {
@@ -786,10 +826,35 @@ func getListenerStatus(
786826
)
787827

788828
if listener.AllowedRoutes == nil || listener.AllowedRoutes.Kinds == nil {
789-
supportedKinds = []gatewayv1.RouteGroupKind{
790-
{
791-
Kind: KindHTTPRoute,
792-
},
829+
group := gatewayv1.Group(gatewayv1.GroupName)
830+
supportedKinds = []gatewayv1.RouteGroupKind{}
831+
switch listener.Protocol {
832+
case gatewayv1.TLSProtocolType:
833+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
834+
Group: &group,
835+
Kind: types.KindTLSRoute,
836+
})
837+
case gatewayv1.TCPProtocolType:
838+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
839+
Group: &group,
840+
Kind: types.KindTCPRoute,
841+
})
842+
case gatewayv1.UDPProtocolType:
843+
supportedKinds = append(supportedKinds, gatewayv1.RouteGroupKind{
844+
Group: &group,
845+
Kind: types.KindUDPRoute,
846+
})
847+
case gatewayv1.HTTPProtocolType, gatewayv1.HTTPSProtocolType:
848+
supportedKinds = append(supportedKinds, []gatewayv1.RouteGroupKind{
849+
{
850+
Group: &group,
851+
Kind: types.KindGRPCRoute,
852+
},
853+
{
854+
Group: &group,
855+
Kind: types.KindHTTPRoute,
856+
},
857+
}...)
793858
}
794859
} else {
795860
for _, kind := range listener.AllowedRoutes.Kinds {
@@ -799,7 +864,7 @@ func getListenerStatus(
799864
continue
800865
}
801866
switch kind.Kind {
802-
case KindHTTPRoute:
867+
case KindHTTPRoute, types.KindGRPCRoute, types.KindTLSRoute, types.KindTCPRoute, types.KindUDPRoute:
803868
supportedKinds = append(supportedKinds, kind)
804869
default:
805870
conditionResolvedRefs.Status = metav1.ConditionFalse
@@ -902,17 +967,9 @@ func getListenerStatus(
902967
changed = true
903968
}
904969

905-
if changed {
906-
statuses[listener.Name] = status
907-
} else {
908-
statuses[listener.Name] = gateway.Status.Listeners[i]
970+
if !changed {
971+
status = gateway.Status.Listeners[i]
909972
}
910-
}
911-
912-
// check for conflicts
913-
914-
statusArray := []gatewayv1.ListenerStatus{}
915-
for _, status := range statuses {
916973
statusArray = append(statusArray, status)
917974
}
918975

0 commit comments

Comments
 (0)