Skip to content

Commit d5ec72b

Browse files
author
Kate Osborn
committed
Reduce complexity of bindRouteToListeners
The gocyclo linter complained about the complexity of the bindRouteToListeners function. This commit refactors this function to reduce its complexity.
1 parent f051302 commit d5ec72b

File tree

2 files changed

+76
-39
lines changed

2 files changed

+76
-39
lines changed

internal/state/graph/httproute.go

+74-38
Original file line numberDiff line numberDiff line change
@@ -290,55 +290,91 @@ func bindRouteToListeners(r *Route, gw *Gateway) {
290290

291291
// Case 4 - winning Gateway
292292

293-
// Find a listener
293+
// Try to attach Route to all matching listeners
294+
cond, attached := tryToAttachRouteToListeners(routeRef, r, gw.Listeners)
295+
if !attached {
296+
attachment.FailedCondition = cond
297+
continue
298+
}
294299

295-
// FIXME(pleshakov)
296-
// For now, let's do simple matching.
297-
// However, we need to also support wildcard matching.
300+
attachment.Attached = true
301+
}
302+
}
298303

299-
bind := func(l *Listener) (valid bool) {
300-
if !l.Valid {
301-
return false
302-
}
304+
// tryToAttachRouteToListeners tries to attach the route to the listeners that match the parentRef and the hostnames.
305+
// If it succeeds in attaching at least one listener it will return true and the condition will be empty.
306+
// If it fails to attach the route, it will return false and the failure condition.
307+
// FIXME(pleshakov)
308+
// For now, let's do simple matching.
309+
// However, we need to also support wildcard matching.
310+
func tryToAttachRouteToListeners(
311+
ref v1beta1.ParentReference,
312+
route *Route,
313+
listeners map[string]*Listener,
314+
) (conditions.Condition, bool) {
315+
validListeners, listenerExists := findValidListeners(getSectionName(ref.SectionName), listeners)
303316

304-
hostnames := findAcceptedHostnames(l.Source.Hostname, r.Source.Spec.Hostnames)
305-
if len(hostnames) == 0 {
306-
return true // listener is valid, but return without attaching due to no matching hostnames
307-
}
317+
if !listenerExists {
318+
// FIXME(pleshakov): Add a proper condition once it is available in the Gateway API.
319+
// https://github.com/nginxinc/nginx-kubernetes-gateway/issues/306
320+
return conditions.NewTODO("listener is not found"), false
321+
}
308322

309-
attachment.Attached = true
310-
for _, h := range hostnames {
311-
l.AcceptedHostnames[h] = struct{}{}
312-
}
313-
l.Routes[client.ObjectKeyFromObject(r.Source)] = r
323+
if len(validListeners) == 0 {
324+
return conditions.NewRouteInvalidListener(), false
325+
}
314326

315-
return true
327+
bind := func(l *Listener) (attached bool) {
328+
hostnames := findAcceptedHostnames(l.Source.Hostname, route.Source.Spec.Hostnames)
329+
if len(hostnames) == 0 {
330+
return false
316331
}
317332

318-
var validListener bool
319-
if getSectionName(routeRef.SectionName) == "" {
320-
for _, l := range gw.Listeners {
321-
validListener = bind(l) || validListener
322-
}
323-
} else {
324-
l, exists := gw.Listeners[string(*routeRef.SectionName)]
325-
if !exists {
326-
// FIXME(pleshakov): Add a proper condition once it is available in the Gateway API.
327-
// https://github.com/nginxinc/nginx-kubernetes-gateway/issues/306
328-
attachment.FailedCondition = conditions.NewTODO("listener is not found")
329-
continue
330-
}
331-
332-
validListener = bind(l)
333+
for _, h := range hostnames {
334+
l.AcceptedHostnames[h] = struct{}{}
333335
}
334-
if !validListener {
335-
attachment.FailedCondition = conditions.NewRouteInvalidListener()
336-
continue
336+
l.Routes[client.ObjectKeyFromObject(route.Source)] = route
337+
338+
return true
339+
}
340+
341+
attached := false
342+
for _, l := range validListeners {
343+
attached = attached || bind(l)
344+
}
345+
346+
if !attached {
347+
return conditions.NewRouteNoMatchingListenerHostname(), false
348+
}
349+
350+
return conditions.Condition{}, true
351+
}
352+
353+
// findValidListeners returns a list of valid listeners and whether the listener exists for a non-empty sectionName.
354+
func findValidListeners(sectionName string, listeners map[string]*Listener) ([]*Listener, bool) {
355+
if sectionName != "" {
356+
l, exists := listeners[sectionName]
357+
if !exists {
358+
return nil, false
337359
}
338-
if !attachment.Attached {
339-
attachment.FailedCondition = conditions.NewRouteNoMatchingListenerHostname()
360+
361+
if l.Valid {
362+
return []*Listener{l}, true
340363
}
364+
365+
return nil, true
341366
}
367+
368+
validListeners := make([]*Listener, 0, len(listeners))
369+
for _, l := range listeners {
370+
if !l.Valid {
371+
continue
372+
}
373+
374+
validListeners = append(validListeners, l)
375+
}
376+
377+
return validListeners, true
342378
}
343379

344380
func findAcceptedHostnames(listenerHostname *v1beta1.Hostname, routeHostnames []v1beta1.Hostname) []string {

internal/status/gateway.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,6 @@ func prepareGatewayStatus(
5151
return v1beta1.GatewayStatus{
5252
Listeners: listenerStatuses,
5353
Addresses: []v1beta1.GatewayAddress{gwPodIP},
54-
Conditions: convertConditions(gatewayStatus.Conditions, gatewayStatus.ObservedGeneration, transitionTime)}
54+
Conditions: convertConditions(gatewayStatus.Conditions, gatewayStatus.ObservedGeneration, transitionTime),
55+
}
5556
}

0 commit comments

Comments
 (0)