Skip to content

Commit 373bdc8

Browse files
authored
fix listener config generation when port is duplicated (#4419)
1 parent 431fc62 commit 373bdc8

File tree

2 files changed

+89
-13
lines changed

2 files changed

+89
-13
lines changed

pkg/gateway/model/model_build_listener.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func (l listenerBuilderImpl) buildListeners(ctx context.Context, stack core.Stac
5858
portsWithRoutes := sets.Int32KeySet(routes)
5959
// Materialise the listener only if listener has associated routes
6060
if len(gwLsPorts.Intersection(portsWithRoutes).List()) != 0 {
61-
lbLsCfgs := mapLoadBalancerListenerConfigsByPort(lbCfg)
61+
lbLsCfgs := mapLoadBalancerListenerConfigsByPort(lbCfg, gw.Spec.Listeners)
6262
for _, port := range gwLsPorts.Intersection(portsWithRoutes).List() {
6363
ls, err := l.buildListener(ctx, stack, lb, gw, port, routes[port], lbCfg, gwLsCfgs[port], lbLsCfgs[port])
6464
if err != nil {
@@ -327,7 +327,7 @@ func (l listenerBuilderImpl) buildCertificates(ctx context.Context, gw *gwv1.Gat
327327
}
328328
discoveredCerts, err := l.buildInferredTLSCertARNs(ctx, gwLsCfg.hostnames.UnsortedList())
329329
if err != nil {
330-
l.logger.Error(err, "Unable to discover certs for listener on gateway %s with protocol:port %s:%v\", k8s.NamespacedName(gw), gwLsCfg.protocol, port")
330+
l.logger.Error(err, fmt.Sprintf("Unable to discover certs for listener on gateway %s with protocol:port %s:%v", k8s.NamespacedName(gw), gwLsCfg.protocol, port))
331331
return []elbv2model.Certificate{}, err
332332
}
333333
for _, cert := range discoveredCerts {
@@ -521,18 +521,32 @@ func mapGatewayListenerConfigsByPort(gw *gwv1.Gateway, routes map[int32][]routeu
521521

522522
// mapLoadBalancerListenerConfigsByPort creates a mapping of ports to their corresponding
523523
// listener configurations from the LoadBalancer configuration.
524-
func mapLoadBalancerListenerConfigsByPort(lbCfg elbv2gw.LoadBalancerConfiguration) map[int32]*elbv2gw.ListenerConfiguration {
524+
func mapLoadBalancerListenerConfigsByPort(lbCfg elbv2gw.LoadBalancerConfiguration, gatewayListeners []gwv1.Listener) map[int32]*elbv2gw.ListenerConfiguration {
525+
configuredListeners := sets.NewString()
526+
527+
for _, configuredListener := range gatewayListeners {
528+
configuredListeners.Insert(generateListenerPortKey(configuredListener))
529+
}
530+
525531
lbLsCfgs := make(map[int32]*elbv2gw.ListenerConfiguration)
526532
if lbCfg.Spec.ListenerConfigurations == nil {
527533
return lbLsCfgs
528534
}
529535
for _, lsCfg := range *lbCfg.Spec.ListenerConfigurations {
530-
port, _ := strconv.ParseInt(strings.Split(string(lsCfg.ProtocolPort), ":")[1], 10, 64)
531-
lbLsCfgs[int32(port)] = &lsCfg
536+
lowerValue := strings.ToLower(string(lsCfg.ProtocolPort))
537+
if configuredListeners.Has(lowerValue) {
538+
port, _ := strconv.ParseInt(strings.Split(string(lsCfg.ProtocolPort), ":")[1], 10, 64)
539+
lbLsCfgs[int32(port)] = &lsCfg
540+
}
541+
532542
}
533543
return lbLsCfgs
534544
}
535545

546+
func generateListenerPortKey(listener gwv1.Listener) string {
547+
return fmt.Sprintf("%s:%d", strings.ToLower(string(listener.Protocol)), listener.Port)
548+
}
549+
536550
func newListenerBuilder(loadBalancerType elbv2model.LoadBalancerType, tgBuilder targetGroupBuilder, tagHelper tagHelper, clusterName string, defaultSSLPolicy string, elbv2Client services.ELBV2, acmClient services.ACM, k8sClient client.Client, allowedCAARNs []string, secretsManager k8s.SecretsManager, logger logr.Logger) listenerBuilder {
537551
certDiscovery := certs.NewACMCertDiscovery(acmClient, allowedCAARNs, logger)
538552
return &listenerBuilderImpl{

pkg/gateway/model/model_build_listener_test.go

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -471,16 +471,19 @@ func Test_mapLoadBalancerListenerConfigsByPort(t *testing.T) {
471471

472472
// Test cases
473473
tests := []struct {
474-
name string
475-
lbCfg elbv2gw.LoadBalancerConfiguration
476-
want map[int32]*elbv2gw.ListenerConfiguration
474+
name string
475+
lbCfg elbv2gw.LoadBalancerConfiguration
476+
listeners []gwv1.Listener
477+
want map[int32]*elbv2gw.ListenerConfiguration
477478
}{
478479
{
479-
name: "nil configuration",
480-
want: map[int32]*elbv2gw.ListenerConfiguration{},
480+
name: "nil configuration",
481+
listeners: []gwv1.Listener{},
482+
want: map[int32]*elbv2gw.ListenerConfiguration{},
481483
},
482484
{
483-
name: "nil listener configurations",
485+
name: "nil listener configurations",
486+
listeners: []gwv1.Listener{},
484487
lbCfg: elbv2gw.LoadBalancerConfiguration{
485488
Spec: elbv2gw.LoadBalancerConfigurationSpec{
486489
ListenerConfigurations: nil,
@@ -489,7 +492,8 @@ func Test_mapLoadBalancerListenerConfigsByPort(t *testing.T) {
489492
want: map[int32]*elbv2gw.ListenerConfiguration{},
490493
},
491494
{
492-
name: "empty listener configurations",
495+
name: "empty listener configurations",
496+
listeners: []gwv1.Listener{},
493497
lbCfg: elbv2gw.LoadBalancerConfiguration{
494498
Spec: elbv2gw.LoadBalancerConfigurationSpec{
495499
ListenerConfigurations: createListenerConfigs(),
@@ -499,6 +503,12 @@ func Test_mapLoadBalancerListenerConfigsByPort(t *testing.T) {
499503
},
500504
{
501505
name: "single HTTP listener",
506+
listeners: []gwv1.Listener{
507+
{
508+
Protocol: gwv1.HTTPProtocolType,
509+
Port: 80,
510+
},
511+
},
502512
lbCfg: elbv2gw.LoadBalancerConfiguration{
503513
Spec: elbv2gw.LoadBalancerConfigurationSpec{
504514
ListenerConfigurations: createListenerConfigs("HTTP:80"),
@@ -512,10 +522,62 @@ func Test_mapLoadBalancerListenerConfigsByPort(t *testing.T) {
512522
},
513523
{
514524
name: "multiple valid listeners",
525+
listeners: []gwv1.Listener{
526+
{
527+
Protocol: gwv1.HTTPProtocolType,
528+
Port: 80,
529+
},
530+
{
531+
Protocol: gwv1.HTTPSProtocolType,
532+
Port: 443,
533+
},
534+
{
535+
Protocol: gwv1.HTTPProtocolType,
536+
Port: 8080,
537+
},
538+
},
539+
lbCfg: elbv2gw.LoadBalancerConfiguration{
540+
Spec: elbv2gw.LoadBalancerConfigurationSpec{
541+
ListenerConfigurations: createListenerConfigs(
542+
"HTTP:80",
543+
"HTTPS:443",
544+
"HTTP:8080",
545+
),
546+
},
547+
},
548+
want: map[int32]*elbv2gw.ListenerConfiguration{
549+
80: {
550+
ProtocolPort: "HTTP:80",
551+
},
552+
443: {
553+
ProtocolPort: "HTTPS:443",
554+
},
555+
8080: {
556+
ProtocolPort: "HTTP:8080",
557+
},
558+
},
559+
},
560+
{
561+
name: "conflicting listener protocols",
562+
listeners: []gwv1.Listener{
563+
{
564+
Protocol: gwv1.HTTPProtocolType,
565+
Port: 80,
566+
},
567+
{
568+
Protocol: gwv1.HTTPSProtocolType,
569+
Port: 443,
570+
},
571+
{
572+
Protocol: gwv1.HTTPProtocolType,
573+
Port: 8080,
574+
},
575+
},
515576
lbCfg: elbv2gw.LoadBalancerConfiguration{
516577
Spec: elbv2gw.LoadBalancerConfigurationSpec{
517578
ListenerConfigurations: createListenerConfigs(
518579
"HTTP:80",
580+
"TCP:80",
519581
"HTTPS:443",
520582
"HTTP:8080",
521583
),
@@ -537,7 +599,7 @@ func Test_mapLoadBalancerListenerConfigsByPort(t *testing.T) {
537599

538600
for _, tt := range tests {
539601
t.Run(tt.name, func(t *testing.T) {
540-
got := mapLoadBalancerListenerConfigsByPort(tt.lbCfg)
602+
got := mapLoadBalancerListenerConfigsByPort(tt.lbCfg, tt.listeners)
541603

542604
assert.Equal(t, tt.want, got)
543605
})

0 commit comments

Comments
 (0)