Skip to content

Commit 67c9028

Browse files
dshehbajhaouc
authored andcommitted
test integration: add test for security group refresh
1 parent edc1a05 commit 67c9028

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

test/integration/eni-subnet-discovery/eni_subnet_discovery_enhanced_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,5 +428,183 @@ var _ = Describe("ENI Subnet Discovery Enhanced Tests", func() {
428428
time.Sleep(time.Second * 90)
429429
})
430430
})
431+
432+
Context("when security group tags change after ENI creation (automatic refresh)", func() {
433+
var (
434+
refreshTestSGID string
435+
testENIID string
436+
)
437+
438+
BeforeEach(func() {
439+
By("Creating custom security group for refresh testing (initially untagged)")
440+
createSecurityGroupOutput, err := f.CloudServices.EC2().
441+
CreateSecurityGroup(context.TODO(), "cni-refresh-test-sg", "Test SG for automatic refresh", f.Options.AWSVPCID)
442+
Expect(err).ToNot(HaveOccurred())
443+
refreshTestSGID = *createSecurityGroupOutput.GroupId
444+
445+
By("Tagging secondary subnet to enable ENI creation there")
446+
_, err = f.CloudServices.EC2().
447+
CreateTags(
448+
context.TODO(),
449+
[]string{createdSubnet},
450+
[]ec2types.Tag{
451+
{
452+
Key: aws.String("kubernetes.io/role/cni"),
453+
Value: aws.String("1"),
454+
},
455+
},
456+
)
457+
Expect(err).ToNot(HaveOccurred())
458+
})
459+
460+
AfterEach(func() {
461+
By("Cleaning up refresh test security group")
462+
if refreshTestSGID != "" {
463+
err := f.CloudServices.EC2().DeleteSecurityGroup(context.TODO(), refreshTestSGID)
464+
if err != nil {
465+
GinkgoWriter.Printf("Warning: Failed to delete refresh test SG %s: %v\n", refreshTestSGID, err)
466+
}
467+
}
468+
469+
By("Removing tags from secondary subnet")
470+
_, err = f.CloudServices.EC2().
471+
DeleteTags(
472+
context.TODO(),
473+
[]string{createdSubnet},
474+
[]ec2types.Tag{
475+
{
476+
Key: aws.String("kubernetes.io/role/cni"),
477+
Value: aws.String("1"),
478+
},
479+
},
480+
)
481+
Expect(err).ToNot(HaveOccurred())
482+
})
483+
484+
It("should automatically apply newly tagged custom security groups to existing secondary ENIs", func() {
485+
By("creating deployment to force secondary ENI creation")
486+
container := manifest.NewNetCatAlpineContainer(f.Options.TestImageRegistry).
487+
Command([]string{"sleep"}).
488+
Args([]string{"3600"}).
489+
Build()
490+
491+
deploymentBuilder := manifest.NewBusyBoxDeploymentBuilder(f.Options.TestImageRegistry).
492+
Container(container).
493+
Replicas(25). // Enough to require secondary ENIs
494+
PodLabel("refresh-test", "sg-auto-refresh").
495+
NodeName(*primaryInstance.PrivateDnsName).
496+
Build()
497+
498+
deployment, err = f.K8sResourceManagers.DeploymentManager().
499+
CreateAndWaitTillDeploymentIsReady(deploymentBuilder, utils.DefaultDeploymentReadyTimeout)
500+
Expect(err).ToNot(HaveOccurred())
501+
502+
defer func() {
503+
err = f.K8sResourceManagers.DeploymentManager().DeleteAndWaitTillDeploymentIsDeleted(deployment)
504+
Expect(err).ToNot(HaveOccurred())
505+
}()
506+
507+
// Allow deployment to stabilize and ENIs to be created
508+
time.Sleep(15 * time.Second)
509+
510+
By("finding secondary ENI created in the tagged secondary subnet")
511+
var secondaryENIs []string
512+
Eventually(func() bool {
513+
instance, err := f.CloudServices.EC2().DescribeInstance(context.TODO(), *primaryInstance.InstanceId)
514+
if err != nil {
515+
return false
516+
}
517+
518+
secondaryENIs = []string{}
519+
for _, nwInterface := range instance.NetworkInterfaces {
520+
if !common.IsPrimaryENI(nwInterface, instance.PrivateIpAddress) && *nwInterface.SubnetId == createdSubnet {
521+
secondaryENIs = append(secondaryENIs, *nwInterface.NetworkInterfaceId)
522+
if testENIID == "" {
523+
testENIID = *nwInterface.NetworkInterfaceId
524+
}
525+
}
526+
}
527+
return len(secondaryENIs) > 0
528+
}, time.Minute*2, time.Second*10).Should(BeTrue(), "Should create at least one secondary ENI in tagged subnet")
529+
530+
By("verifying secondary ENI initially uses primary security groups")
531+
var primarySGs []string
532+
instance, err := f.CloudServices.EC2().DescribeInstance(context.TODO(), *primaryInstance.InstanceId)
533+
Expect(err).ToNot(HaveOccurred())
534+
535+
// Get primary ENI security groups
536+
for _, nwInterface := range instance.NetworkInterfaces {
537+
if common.IsPrimaryENI(nwInterface, instance.PrivateIpAddress) {
538+
for _, sg := range nwInterface.Groups {
539+
primarySGs = append(primarySGs, *sg.GroupId)
540+
}
541+
break
542+
}
543+
}
544+
545+
// Verify secondary ENI has primary SGs initially (and not the refresh test SG)
546+
Eventually(func() []string {
547+
eni, err := f.CloudServices.EC2().DescribeNetworkInterface(context.TODO(), []string{testENIID})
548+
if err != nil || len(eni.NetworkInterfaces) == 0 {
549+
return nil
550+
}
551+
var sgIDs []string
552+
for _, sg := range eni.NetworkInterfaces[0].Groups {
553+
sgIDs = append(sgIDs, *sg.GroupId)
554+
}
555+
return sgIDs
556+
}, time.Second*30, time.Second*5).Should(And(
557+
ContainElements(primarySGs),
558+
Not(ContainElement(refreshTestSGID)),
559+
), "Secondary ENI should initially have primary security groups")
560+
561+
By("tagging custom security group with kubernetes.io/role/cni=1 to trigger refresh")
562+
_, err = f.CloudServices.EC2().
563+
CreateTags(
564+
context.TODO(),
565+
[]string{refreshTestSGID},
566+
[]ec2types.Tag{
567+
{
568+
Key: aws.String("kubernetes.io/role/cni"),
569+
Value: aws.String("1"),
570+
},
571+
},
572+
)
573+
Expect(err).ToNot(HaveOccurred())
574+
575+
By("waiting for automatic refresh to detect and apply the new custom security group")
576+
Eventually(func() []string {
577+
eni, err := f.CloudServices.EC2().DescribeNetworkInterface(context.TODO(), []string{testENIID})
578+
if err != nil || len(eni.NetworkInterfaces) == 0 {
579+
GinkgoWriter.Printf("Error describing ENI %s: %v\n", testENIID, err)
580+
return nil
581+
}
582+
var sgIDs []string
583+
for _, sg := range eni.NetworkInterfaces[0].Groups {
584+
sgIDs = append(sgIDs, *sg.GroupId)
585+
}
586+
GinkgoWriter.Printf("Current ENI %s security groups: %v\n", testENIID, sgIDs)
587+
return sgIDs
588+
}, time.Second*50, time.Second*5).Should(And(
589+
ContainElement(refreshTestSGID),
590+
Not(ContainElements(primarySGs)),
591+
), "Custom security group should be automatically applied within 50 seconds")
592+
593+
By("verifying the change persists after another refresh cycle")
594+
time.Sleep(35 * time.Second)
595+
596+
eni, err := f.CloudServices.EC2().DescribeNetworkInterface(context.TODO(), []string{testENIID})
597+
Expect(err).ToNot(HaveOccurred())
598+
Expect(len(eni.NetworkInterfaces)).To(BeNumerically(">", 0))
599+
600+
var finalSGIDs []string
601+
for _, sg := range eni.NetworkInterfaces[0].Groups {
602+
finalSGIDs = append(finalSGIDs, *sg.GroupId)
603+
}
604+
605+
Expect(finalSGIDs).To(ContainElement(refreshTestSGID), "Custom SG should persist after additional refresh cycle")
606+
Expect(finalSGIDs).ToNot(ContainElements(primarySGs), "Primary SGs should remain replaced")
607+
})
608+
})
431609
})
432610
})

0 commit comments

Comments
 (0)