@@ -35,6 +35,7 @@ import (
35
35
kerrors "k8s.io/apimachinery/pkg/util/errors"
36
36
"k8s.io/apimachinery/pkg/util/sets"
37
37
"k8s.io/apiserver/pkg/storage/names"
38
+ "k8s.io/utils/ptr"
38
39
39
40
infrav1 "sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
40
41
"sigs.k8s.io/cluster-api-provider-aws/v2/pkg/cloud/awserrors"
@@ -55,6 +56,14 @@ const elbResourceType = "elasticloadbalancing:loadbalancer"
55
56
// see: https://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DescribeTags.html
56
57
const maxELBsDescribeTagsRequest = 20
57
58
59
+ // apiServerTargetGroupPrefix is the target group name prefix used when creating a target group for the API server
60
+ // listener.
61
+ const apiServerTargetGroupPrefix = "apiserver-target-"
62
+
63
+ // additionalTargetGroupPrefix is the target group name prefix used when creating target groups for additional
64
+ // listeners.
65
+ const additionalTargetGroupPrefix = "additional-listener-"
66
+
58
67
// ReconcileLoadbalancers reconciles the load balancers for the given cluster.
59
68
func (s * Service ) ReconcileLoadbalancers () error {
60
69
s .scope .Debug ("Reconciling load balancers" )
@@ -271,7 +280,7 @@ func (s *Service) getAPIServerLBSpec(elbName string, lbSpec *infrav1.AWSLoadBala
271
280
Protocol : infrav1 .ELBProtocolTCP ,
272
281
Port : infrav1 .DefaultAPIServerPort ,
273
282
TargetGroup : infrav1.TargetGroupSpec {
274
- Name : names .SimpleNameGenerator .GenerateName ("apiserver-target-" ),
283
+ Name : names .SimpleNameGenerator .GenerateName (apiServerTargetGroupPrefix ),
275
284
Port : infrav1 .DefaultAPIServerPort ,
276
285
Protocol : infrav1 .ELBProtocolTCP ,
277
286
VpcID : s .scope .VPC ().ID ,
@@ -296,7 +305,7 @@ func (s *Service) getAPIServerLBSpec(elbName string, lbSpec *infrav1.AWSLoadBala
296
305
Protocol : listener .Protocol ,
297
306
Port : listener .Port ,
298
307
TargetGroup : infrav1.TargetGroupSpec {
299
- Name : names .SimpleNameGenerator .GenerateName ("additional-listener-" ),
308
+ Name : names .SimpleNameGenerator .GenerateName (additionalTargetGroupPrefix ),
300
309
Port : listener .Port ,
301
310
Protocol : listener .Protocol ,
302
311
VpcID : s .scope .VPC ().ID ,
@@ -1573,9 +1582,11 @@ func (s *Service) reconcileTargetGroupsAndListeners(lbARN string, spec *infrav1.
1573
1582
// https://github.com/kubernetes-sigs/cluster-api-provider-aws/issues/3899
1574
1583
for _ , ln := range spec .ELBListeners {
1575
1584
var group * elbv2.TargetGroup
1585
+ tgSpec := ln .TargetGroup
1576
1586
for _ , g := range existingTargetGroups .TargetGroups {
1577
- if * g . TargetGroupName == ln . TargetGroup . Name {
1587
+ if isSDKTargetGroupEqualToTargetGroup ( g , & tgSpec ) {
1578
1588
group = g
1589
+ break
1579
1590
}
1580
1591
}
1581
1592
// create the target group first
@@ -1604,8 +1615,9 @@ func (s *Service) reconcileTargetGroupsAndListeners(lbARN string, spec *infrav1.
1604
1615
1605
1616
var listener * elbv2.Listener
1606
1617
for _ , l := range existingListeners .Listeners {
1607
- if l .DefaultActions != nil && len (l .DefaultActions ) > 0 && l .DefaultActions [0 ].TargetGroupArn == group .TargetGroupArn {
1618
+ if l .DefaultActions != nil && len (l .DefaultActions ) > 0 && * l .DefaultActions [0 ].TargetGroupArn == * group .TargetGroupArn {
1608
1619
listener = l
1620
+ break
1609
1621
}
1610
1622
}
1611
1623
@@ -1614,9 +1626,8 @@ func (s *Service) reconcileTargetGroupsAndListeners(lbARN string, spec *infrav1.
1614
1626
if err != nil {
1615
1627
return nil , nil , err
1616
1628
}
1629
+ createdListeners = append (createdListeners , listener )
1617
1630
}
1618
-
1619
- createdListeners = append (createdListeners , listener )
1620
1631
}
1621
1632
1622
1633
return createdTargetGroups , createdListeners , nil
@@ -1785,3 +1796,23 @@ func shouldReconcileSGs(scope scope.ELBScope, lb *infrav1.LoadBalancer, specSGs
1785
1796
}
1786
1797
return true
1787
1798
}
1799
+
1800
+ // isSDKTargetGroupEqualToTargetGroup checks if a given AWS SDK target group matches a target group spec.
1801
+ func isSDKTargetGroupEqualToTargetGroup (elbTG * elbv2.TargetGroup , spec * infrav1.TargetGroupSpec ) bool {
1802
+ // We can't check only the target group's name because it's randomly generated every time we get a spec
1803
+ // But CAPA-created target groups are guaranteed to have the "apiserver-target-" or "additional-listener-" prefix.
1804
+ switch {
1805
+ case strings .HasPrefix (* elbTG .TargetGroupName , apiServerTargetGroupPrefix ):
1806
+ if ! strings .HasPrefix (spec .Name , apiServerTargetGroupPrefix ) {
1807
+ return false
1808
+ }
1809
+ case strings .HasPrefix (* elbTG .TargetGroupName , additionalTargetGroupPrefix ):
1810
+ if ! strings .HasPrefix (spec .Name , additionalTargetGroupPrefix ) {
1811
+ return false
1812
+ }
1813
+ default :
1814
+ // Not created by CAPA
1815
+ return false
1816
+ }
1817
+ return ptr .Deref (elbTG .Port , 0 ) == spec .Port && strings .EqualFold (* elbTG .Protocol , spec .Protocol .String ())
1818
+ }
0 commit comments