66 "strings"
77 "time"
88
9- elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
109 elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
1110 . "github.com/onsi/ginkgo/v2"
1211 . "github.com/onsi/gomega"
@@ -18,6 +17,8 @@ import (
1817 "k8s.io/kubernetes/test/e2e/framework"
1918 e2eservice "k8s.io/kubernetes/test/e2e/framework/service"
2019 admissionapi "k8s.io/pod-security-admission/api"
20+
21+ ccme2e "k8s.io/cloud-provider-aws/tests/e2e"
2122)
2223
2324const (
@@ -118,21 +119,21 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
118119 It ("should create NLB service with security group attached" , func (ctx context.Context ) {
119120 isNLBFeatureEnabled (ctx )
120121
121- By ("creatomg required AWS clients " )
122- elbClient , err := createAWSClientLoadBalancer (ctx )
123- framework .ExpectNoError (err , "failed to create AWS ELB client " )
122+ By ("creating E2E test helper " )
123+ e2e , err := ccme2e . NewE2ETestHelper (ctx , cs )
124+ framework .ExpectNoError (err , "failed to create E2E test helper " )
124125
125126 By ("creating test service and deployment configuration" )
126127 serviceName := "nlb-sg-crt"
127128 _ , jig , err := createServiceNLB (ctx , cs , ns , serviceName , map [int32 ]int32 {80 : 8080 })
128129 framework .ExpectNoError (err , "failed to create NLB service load balancer" )
129130
130- foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , elbClient )
131+ foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , e2e )
131132 framework .ExpectNoError (err , "failed to get NLB metadata" )
132133 Expect (foundLB ).NotTo (BeNil (), "found load balancer is nil" )
133134
134- DeferCleanup (func (cleanupCtx context. Context ) {
135- err := deleteServiceAndWaitForLoadBalancerDeletion (cleanupCtx , jig , lbDNS )
135+ DeferCleanup (func () {
136+ err := deleteServiceAndWaitForLoadBalancerDeletion (e2e , jig , lbDNS )
136137 framework .ExpectNoError (err , "failed to delete service and wait for load balancer deletion" )
137138 })
138139
@@ -165,9 +166,9 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
165166 It ("should have security groups attached to default ingress controller NLB" , func (ctx context.Context ) {
166167 isNLBFeatureEnabled (ctx )
167168
168- By ("creatomg required AWS clients " )
169- elbClient , err := createAWSClientLoadBalancer (ctx )
170- framework .ExpectNoError (err , "failed to create AWS ELB client " )
169+ By ("creating E2E test helper " )
170+ e2e , err := ccme2e . NewE2ETestHelper (ctx , cs )
171+ framework .ExpectNoError (err , "failed to create E2E test helper " )
171172
172173 By ("getting default ingress controller service" )
173174 ingressNamespace := "openshift-ingress"
@@ -206,7 +207,7 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
206207
207208 var foundLB * elbv2types.LoadBalancer
208209 err = wait .PollUntilContextTimeout (ctx , 10 * time .Second , 3 * time .Minute , true , func (pollCtx context.Context ) (bool , error ) {
209- lb , err := getAWSLoadBalancerFromDNSName ( pollCtx , elbClient , lbDNS )
210+ lb , err := e2e . GetAWSHelper (). GetLoadBalancerFromDNSNameWithRetry ( lbDNS , 10 * time . Minute )
210211 if err != nil {
211212 framework .Logf ("Failed to find load balancer with DNS %s: %v" , lbDNS , err )
212213 return false , nil
@@ -253,24 +254,21 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
253254 It ("should update security group rules when service is updated" , func (ctx context.Context ) {
254255 isNLBFeatureEnabled (ctx )
255256
256- By ("creatomg required AWS clients" )
257- ec2Client , err := createAWSClientEC2 (ctx )
258- framework .ExpectNoError (err , "failed to create AWS EC2 client" )
259-
260- elbClient , err := createAWSClientLoadBalancer (ctx )
261- framework .ExpectNoError (err , "failed to create AWS ELB client" )
257+ By ("creating E2E test helper" )
258+ e2e , err := ccme2e .NewE2ETestHelper (ctx , cs )
259+ framework .ExpectNoError (err , "failed to create E2E test helper" )
262260
263261 By ("creating test service and deployment configuration" )
264262 serviceName := "nlb-sg-upd"
265263 _ , jig , err := createServiceNLB (ctx , cs , ns , serviceName , map [int32 ]int32 {80 : 8080 })
266264 framework .ExpectNoError (err , "failed to create NLB service load balancer" )
267265
268- foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , elbClient )
266+ foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , e2e )
269267 framework .ExpectNoError (err , "failed to get NLB metadata" )
270268 Expect (foundLB ).NotTo (BeNil (), "found load balancer is nil" )
271269
272- DeferCleanup (func (cleanupCtx context. Context ) {
273- err := deleteServiceAndWaitForLoadBalancerDeletion (cleanupCtx , jig , lbDNS )
270+ DeferCleanup (func () {
271+ err := deleteServiceAndWaitForLoadBalancerDeletion (e2e , jig , lbDNS )
274272 framework .ExpectNoError (err , "failed to delete service and wait for load balancer deletion" )
275273 })
276274
@@ -280,7 +278,7 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
280278 framework .Logf ("Load balancer has %d security group(s) attached before update" , len (foundLB .SecurityGroups ))
281279
282280 By ("getting security group rules" )
283- originalSGRules , err := getAWSSecurityGroupRules (ctx , ec2Client , foundLB .SecurityGroups )
281+ originalSGRules , err := getAWSSecurityGroupRules (ctx , e2e . GetAWSHelper (). GetEC2Client () , foundLB .SecurityGroups )
284282 framework .ExpectNoError (err , "failed to get security group rules" )
285283
286284 By ("updating service: adding a new port" )
@@ -297,7 +295,7 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
297295
298296 By ("waiting for security group rules to include the new port 443" )
299297 Eventually (ctx , func (ctx context.Context ) ([]int32 , error ) {
300- foundLB , err = getAWSLoadBalancerFromDNSName ( ctx , elbClient , lbDNS )
298+ foundLB , err = e2e . GetAWSHelper (). GetLoadBalancerFromDNSNameWithRetry ( lbDNS , 10 * time . Minute )
301299 if err != nil {
302300 framework .Logf ("Error finding load balancer: %v" , err )
303301 return nil , err
@@ -311,7 +309,7 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
311309 return nil , fmt .Errorf ("load balancer has no security groups attached" )
312310 }
313311
314- currentSGRules , err := getAWSSecurityGroupRules (ctx , ec2Client , foundLB .SecurityGroups )
312+ currentSGRules , err := getAWSSecurityGroupRules (ctx , e2e . GetAWSHelper (). GetEC2Client () , foundLB .SecurityGroups )
315313 if err != nil {
316314 framework .Logf ("failed to get security group rules to calculate the diff: %v" , err )
317315 return nil , err
@@ -364,20 +362,17 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
364362 It ("should cleanup security groups when service is deleted" , func (ctx context.Context ) {
365363 isNLBFeatureEnabled (ctx )
366364
367- By ("creatomg required AWS clients" )
368- ec2Client , err := createAWSClientEC2 (ctx )
369- framework .ExpectNoError (err , "failed to create AWS EC2 client" )
370-
371- elbClient , err := createAWSClientLoadBalancer (ctx )
372- framework .ExpectNoError (err , "failed to create AWS ELB client" )
365+ By ("creating E2E test helper" )
366+ e2e , err := ccme2e .NewE2ETestHelper (ctx , cs )
367+ framework .ExpectNoError (err , "failed to create E2E test helper" )
373368
374369 By ("creating test service and deployment configuration" )
375370 serviceName := "nlb-sg-cleanup-test"
376371
377372 _ , jig , err := createServiceNLB (ctx , cs , ns , serviceName , map [int32 ]int32 {80 : 8080 })
378373 framework .ExpectNoError (err , "failed to create NLB service load balancer" )
379374
380- foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , elbClient )
375+ foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , e2e )
381376 framework .ExpectNoError (err , "failed to get NLB metadata" )
382377 Expect (foundLB ).NotTo (BeNil (), "found load balancer is nil" )
383378
@@ -393,20 +388,20 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
393388
394389 By ("verifying security groups exist before deletion" )
395390 for _ , sgID := range securityGroupIDs {
396- exists , err := securityGroupExists (ctx , ec2Client , sgID )
391+ exists , err := securityGroupExists (ctx , e2e . GetAWSHelper (). GetEC2Client () , sgID )
397392 framework .ExpectNoError (err , "failed to check security group %s" , sgID )
398393 Expect (exists ).To (BeTrue (), "security group %s should exist before deletion" , sgID )
399394 }
400395
401- err = deleteServiceAndWaitForLoadBalancerDeletion (ctx , jig , lbDNS )
396+ err = deleteServiceAndWaitForLoadBalancerDeletion (e2e , jig , lbDNS )
402397 framework .ExpectNoError (err , "failed to delete service and wait for load balancer deletion" )
403398
404399 By ("verifying managed security groups are cleaned up" )
405400 // Poll for security group cleanup with timeout (AWS cleanup can take time)
406401 err = wait .PollUntilContextTimeout (ctx , 10 * time .Second , 3 * time .Minute , true , func (ctx context.Context ) (bool , error ) {
407402 allDeleted := true
408403 for _ , sgID := range securityGroupIDs {
409- exists , err := securityGroupExists (ctx , ec2Client , sgID )
404+ exists , err := securityGroupExists (ctx , e2e . GetAWSHelper (). GetEC2Client () , sgID )
410405 if err != nil {
411406 framework .Logf ("Error checking security group %s: %v" , sgID , err )
412407 return false , err
@@ -447,12 +442,9 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
447442 It ("should have correct security group rules for service ports" , func (ctx context.Context ) {
448443 isNLBFeatureEnabled (ctx )
449444
450- By ("creatomg required AWS clients" )
451- ec2Client , err := createAWSClientEC2 (ctx )
452- framework .ExpectNoError (err , "failed to create AWS EC2 client" )
453-
454- elbClient , err := createAWSClientLoadBalancer (ctx )
455- framework .ExpectNoError (err , "failed to create AWS ELB client" )
445+ By ("creating E2E test helper" )
446+ e2e , err := ccme2e .NewE2ETestHelper (ctx , cs )
447+ framework .ExpectNoError (err , "failed to create E2E test helper" )
456448
457449 By ("creating test service and deployment configuration" )
458450 serviceName := "nlb-sg-rules-test"
@@ -465,12 +457,12 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
465457 lbDNS := svc .Status .LoadBalancer .Ingress [0 ].Hostname
466458 framework .Logf ("Load balancer DNS: %s" , lbDNS )
467459
468- foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , elbClient )
460+ foundLB , lbDNS , err := getNLBMetaFromName (ctx , cs , ns , serviceName , e2e )
469461 framework .ExpectNoError (err , "failed to get NLB metadata" )
470462 Expect (foundLB ).NotTo (BeNil (), "found load balancer is nil" )
471463
472- DeferCleanup (func (cleanupCtx context. Context ) {
473- err := deleteServiceAndWaitForLoadBalancerDeletion (cleanupCtx , jig , lbDNS )
464+ DeferCleanup (func () {
465+ err := deleteServiceAndWaitForLoadBalancerDeletion (e2e , jig , lbDNS )
474466 framework .ExpectNoError (err , "failed to delete service and wait for load balancer deletion" )
475467 })
476468
@@ -480,7 +472,7 @@ var _ = Describe(fmt.Sprintf("%s NLB [OCPFeatureGate:%s]", e2eTestPrefixLoadBala
480472 framework .Logf ("Load balancer has %d security group(s) attached" , len (foundLB .SecurityGroups ))
481473
482474 By ("inspecting security group rules" )
483- currentSGRules , err := getAWSSecurityGroupRules (ctx , ec2Client , foundLB .SecurityGroups )
475+ currentSGRules , err := getAWSSecurityGroupRules (ctx , e2e . GetAWSHelper (). GetEC2Client () , foundLB .SecurityGroups )
484476 framework .ExpectNoError (err , "failed to get security group rules to calculate the diff" )
485477 Expect (len (currentSGRules )).To (BeNumerically (">" , 0 ), "security group rules should not be empty" )
486478
@@ -543,7 +535,7 @@ func createServiceNLB(ctx context.Context, cs clientset.Interface, ns *v1.Namesp
543535}
544536
545537// getNLBMetaFromName gets the NLB metadata (AWS API object) from the service/loadbalancer name.
546- func getNLBMetaFromName (ctx context.Context , cs clientset.Interface , ns * v1.Namespace , serviceName string , elbc * elbv2. Client ) (* elbv2types.LoadBalancer , string , error ) {
538+ func getNLBMetaFromName (ctx context.Context , cs clientset.Interface , ns * v1.Namespace , serviceName string , e2e * ccme2e. E2ETestHelper ) (* elbv2types.LoadBalancer , string , error ) {
547539 By ("getting service to extract load balancer DNS name" )
548540 svc , err := cs .CoreV1 ().Services (ns .Name ).Get (ctx , serviceName , metav1.GetOptions {})
549541 framework .ExpectNoError (err , "failed to get service %s" , serviceName )
@@ -556,29 +548,39 @@ func getNLBMetaFromName(ctx context.Context, cs clientset.Interface, ns *v1.Name
556548 Expect (lbDNS ).NotTo (BeEmpty (), "Ingress Hostname must not be empty" )
557549 framework .Logf ("Load balancer DNS: %s" , lbDNS )
558550
559- foundLB , err := getAWSLoadBalancerFromDNSName (ctx , elbc , lbDNS )
560- framework .ExpectNoError (err , "failed to find load balancer with DNS name %s" , lbDNS )
551+ // Use Eventually to handle AWS API eventual consistency - the Kubernetes service
552+ // may show the LB DNS before AWS API has fully propagated the resource.
553+ // Based on observed CI failures, this can take 30s-2min in high-load environments.
554+ var foundLB * elbv2types.LoadBalancer
555+ Eventually (ctx , func (ctx context.Context ) error {
556+ lb , err := e2e .GetAWSHelper ().GetLoadBalancerFromDNSNameWithRetry (lbDNS , 10 * time .Minute )
557+ if err != nil {
558+ e2e .GatherServiceInfo (ns .Name , serviceName )
559+ return fmt .Errorf ("failed to find load balancer with DNS name %s: %v" , lbDNS , err )
560+ }
561+ foundLB = lb
562+ return nil
563+ }, 5 * time .Minute , 5 * time .Second ).Should (Succeed (), "failed to find load balancer with DNS name %s" , lbDNS )
561564 Expect (foundLB ).NotTo (BeNil (), "found load balancer is nil" )
562565
563566 return foundLB , lbDNS , nil
564567}
565568
566569// deleteServiceAndWaitForLoadBalancerDeletion deletes the service and waits for the load balancer to be deleted.
567- func deleteServiceAndWaitForLoadBalancerDeletion (ctx context. Context , jig * e2eservice.TestJig , lbDNS string ) error {
570+ func deleteServiceAndWaitForLoadBalancerDeletion (e2e * ccme2e. E2ETestHelper , jig * e2eservice.TestJig , lbDNS string ) error {
568571 By ("deleting the service" )
572+ // using deletion context to avoid leaking resources
573+ ctx := context .TODO ()
569574 err := jig .Client .CoreV1 ().Services (jig .Namespace ).Delete (ctx , jig .Name , metav1.DeleteOptions {})
570575 framework .ExpectNoError (err , "failed to delete service" )
571576
572577 By ("waiting for load balancer to be destroyed" )
573578 loadBalancerCreateTimeout := e2eservice .GetServiceLoadBalancerCreationTimeout (ctx , jig .Client )
574579
575580 // Get ELB client once before polling
576- elbClient , err := createAWSClientLoadBalancer (ctx )
577- framework .ExpectNoError (err , "failed to create AWS ELB client" )
578-
579581 // Poll for load balancer deletion
580582 err = wait .PollUntilContextTimeout (ctx , 5 * time .Second , loadBalancerCreateTimeout , true , func (ctx context.Context ) (bool , error ) {
581- foundLB , err := getAWSLoadBalancerFromDNSName ( ctx , elbClient , lbDNS )
583+ foundLB , err := e2e . GetAWSHelper (). GetLoadBalancerFromDNSName ( lbDNS )
582584 if err != nil {
583585 // Check if the error indicates the load balancer was not found (i.e., successfully deleted)
584586 if strings .Contains (err .Error (), "no load balancer found with DNS name" ) {
0 commit comments