Skip to content

Commit 5cfeef8

Browse files
authored
Merge pull request #4629 from zac-nixon/main
[Gateway API] Validate ListenerSet listeners
2 parents a48d356 + 244dd17 commit 5cfeef8

File tree

9 files changed

+655
-309
lines changed

9 files changed

+655
-309
lines changed

controllers/gateway/gateway_controller.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,16 @@ func (r *gatewayReconciler) reconcileHelper(ctx context.Context, req reconcile.R
231231

232232
loaderResults, err := r.gatewayLoader.LoadRoutesForGateway(ctx, *gw, r.routeFilter, r.controllerName, resolvedDefaultTGC)
233233

234-
if err != nil || loaderResults.ValidationResults.HasErrors {
234+
validationHasErrors := false
235+
if loaderResults != nil {
236+
validationHasErrors = loaderResults.ValidationResults.HasErrors()
237+
}
238+
if err != nil || validationHasErrors {
235239
var loaderErr routeutils.LoaderError
236-
if errors.As(err, &loaderErr) || loaderResults.ValidationResults.HasErrors {
240+
if errors.As(err, &loaderErr) || validationHasErrors {
237241
var gatewayReason gwv1.GatewayConditionReason
238242
var gatewayMessage string
239-
if loaderErr == nil && loaderResults.ValidationResults.HasErrors {
243+
if loaderErr == nil && validationHasErrors {
240244
gatewayReason = gwv1.GatewayReasonAccepted
241245
gatewayMessage = gateway_constants.GatewayAcceptedFalseMessage
242246
} else {

controllers/gateway/listener_status_utils.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import (
1111
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
1212
)
1313

14-
func buildListenerStatus(gateway gwv1.Gateway, listeners []gwv1.Listener, attachedRoutesMap map[gwv1.SectionName]int32, validateListenerResults routeutils.ListenerValidationResults, isProgrammed bool) []gwv1.ListenerStatus {
14+
func buildListenerStatus(gateway gwv1.Gateway, listeners []gwv1.Listener, attachedRoutesMap map[gwv1.SectionName]int32, validatedListeners routeutils.ValidatedGatewayListeners, isProgrammed bool) []gwv1.ListenerStatus {
1515
var listenerStatuses []gwv1.ListenerStatus
16+
validateListenerResults := validatedListeners.GatewayListenerValidation
1617

1718
for _, listener := range listeners {
1819
listenerValidationResult := validateListenerResults.Results[listener.Name]

controllers/gateway/listener_status_utils_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func Test_buildListenerStatus(t *testing.T) {
1616
name string
1717
gateway gwv1.Gateway
1818
attachedRoutesMap map[gwv1.SectionName]int32
19-
validateListenerResults routeutils.ListenerValidationResults
19+
validateListenerResults routeutils.ValidatedGatewayListeners
2020
supportedKinds []gwv1.RouteGroupKind
2121
isProgrammed bool
2222
expectedListenerCount int
@@ -37,11 +37,13 @@ func Test_buildListenerStatus(t *testing.T) {
3737
},
3838
},
3939
attachedRoutesMap: map[gwv1.SectionName]int32{"listener1": 1},
40-
validateListenerResults: routeutils.ListenerValidationResults{
41-
Results: map[gwv1.SectionName]routeutils.ListenerValidationResult{
42-
"listener1": {Reason: gwv1.ListenerReasonAccepted, Message: "accepted", SupportedKinds: []gwv1.RouteGroupKind{{
43-
Kind: "HTTPRoute",
44-
}}},
40+
validateListenerResults: routeutils.ValidatedGatewayListeners{
41+
GatewayListenerValidation: routeutils.ListenerValidationResults{
42+
Results: map[gwv1.SectionName]routeutils.ListenerValidationResult{
43+
"listener1": {Reason: gwv1.ListenerReasonAccepted, Message: "accepted", SupportedKinds: []gwv1.RouteGroupKind{{
44+
Kind: "HTTPRoute",
45+
}}},
46+
},
4547
},
4648
},
4749
supportedKinds: []gwv1.RouteGroupKind{{
@@ -59,7 +61,7 @@ func Test_buildListenerStatus(t *testing.T) {
5961
},
6062
},
6163
attachedRoutesMap: map[gwv1.SectionName]int32{},
62-
validateListenerResults: routeutils.ListenerValidationResults{},
64+
validateListenerResults: routeutils.ValidatedGatewayListeners{},
6365
isProgrammed: true,
6466
expectedListenerCount: 0,
6567
},

pkg/gateway/routeutils/listener_set.go

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55

66
"github.com/go-logr/logr"
77
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
"k8s.io/apimachinery/pkg/types"
9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
810
"sigs.k8s.io/controller-runtime/pkg/client"
911
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
1012
)
@@ -21,7 +23,7 @@ const (
2123
)
2224

2325
type listenerSetLoader interface {
24-
retrieveListenersFromListenerSets(ctx context.Context, gateway gwv1.Gateway) ([]gwv1.Listener, error)
26+
retrieveListenersFromListenerSets(ctx context.Context, gateway gwv1.Gateway) (listenerSetLoadResult, []*gwv1.ListenerSet, error)
2527
}
2628

2729
type listenerSetLoaderImpl struct {
@@ -34,37 +36,55 @@ func newListenerSetLoader(k8sClient client.Client, logger logr.Logger) listenerS
3436
return &listenerSetLoaderImpl{
3537
k8sClient: k8sClient,
3638
namespaceSelector: newNamespaceSelector(k8sClient),
37-
logger: logger.WithName("listener-set-loader"),
39+
logger: logger,
3840
}
3941
}
4042

41-
func (l *listenerSetLoaderImpl) retrieveListenersFromListenerSets(ctx context.Context, gateway gwv1.Gateway) ([]gwv1.Listener, error) {
42-
return []gwv1.Listener{}, nil
43-
43+
type listenerSetLoadResult struct {
44+
listenersPerListenerSet map[types.NamespacedName][]listenerSetListenerSource
45+
acceptedListenerSets []*gwv1.ListenerSet
4446
}
4547

46-
func (l *listenerSetLoaderImpl) getListenerSets(ctx context.Context, gateway gwv1.Gateway) ([]gwv1.Listener, error) {
48+
func (l *listenerSetLoaderImpl) retrieveListenersFromListenerSets(ctx context.Context, gateway gwv1.Gateway) (listenerSetLoadResult, []*gwv1.ListenerSet, error) {
4749
listenerSets := &gwv1.ListenerSetList{}
4850
err := l.k8sClient.List(ctx, listenerSets)
4951
if err != nil {
50-
return nil, err
52+
return listenerSetLoadResult{}, nil, err
5153
}
5254

53-
var result []gwv1.Listener
54-
for _, item := range listenerSets.Items {
55+
rejectedListenerSets := make([]*gwv1.ListenerSet, 0)
56+
57+
listenersPerListenerSet := make(map[types.NamespacedName][]listenerSetListenerSource)
58+
acceptedListenerSets := make([]*gwv1.ListenerSet, 0)
59+
for i, item := range listenerSets.Items {
5560
handshake, err := l.listenerSetGatewayHandshake(ctx, item, gateway)
5661
if err != nil {
57-
return nil, err
62+
return listenerSetLoadResult{}, nil, err
5863
}
59-
if handshake == acceptedHandshakeState {
64+
switch handshake {
65+
case acceptedHandshakeState:
66+
var convertedListeners []listenerSetListenerSource
6067
for _, listener := range item.Spec.Listeners {
61-
result = append(result, l.convertListenerSetListenerToGatewayListener(listener))
68+
convertedListeners = append(convertedListeners, l.convertListenerSetListenerToGatewayListener(item, listener))
6269
}
70+
itemPtr := &listenerSets.Items[i]
71+
listenersPerListenerSet[k8s.NamespacedName(itemPtr)] = convertedListeners
72+
acceptedListenerSets = append(acceptedListenerSets, itemPtr)
73+
break
74+
case gatewayRejectedHandshakeState:
75+
rejectedListenerSets = append(rejectedListenerSets, &listenerSets.Items[i])
76+
break
77+
case irrelevantResourceHandshakeState:
78+
// Nothing to do here, the listener set and gateway have no relation.
79+
break
6380
}
6481

6582
}
6683

67-
return result, nil
84+
return listenerSetLoadResult{
85+
listenersPerListenerSet: listenersPerListenerSet,
86+
acceptedListenerSets: acceptedListenerSets,
87+
}, rejectedListenerSets, nil
6888
}
6989

7090
func (l *listenerSetLoaderImpl) listenerSetGatewayHandshake(ctx context.Context, listenerSet gwv1.ListenerSet, gw gwv1.Gateway) (handshakeState, error) {
@@ -105,15 +125,19 @@ func (l *listenerSetLoaderImpl) convertListenerSetParentRef(ref gwv1.ParentGatew
105125
}
106126
}
107127

108-
func (l *listenerSetLoaderImpl) convertListenerSetListenerToGatewayListener(entry gwv1.ListenerEntry) gwv1.Listener {
109-
return gwv1.Listener{
128+
func (l *listenerSetLoaderImpl) convertListenerSetListenerToGatewayListener(listenerSet gwv1.ListenerSet, entry gwv1.ListenerEntry) listenerSetListenerSource {
129+
v := gwv1.Listener{
110130
Name: entry.Name,
111131
Hostname: entry.Hostname,
112132
Port: entry.Port,
113133
Protocol: entry.Protocol,
114134
TLS: entry.TLS,
115135
AllowedRoutes: entry.AllowedRoutes,
116136
}
137+
return listenerSetListenerSource{
138+
parentRef: listenerSet,
139+
listener: v,
140+
}
117141
}
118142

119143
var _ listenerSetLoader = &listenerSetLoaderImpl{}

0 commit comments

Comments
 (0)