@@ -844,6 +844,84 @@ func (e *ENISuite) TestInstanceBeenDeleted(c *check.C) {
844
844
c .Assert (node .Stats ().ExcessIPs , check .Equals , 0 )
845
845
}
846
846
847
+ // TestNodeManagerStaticIP tests allocation with a static IP
848
+ //
849
+ // - m5.large (3x ENIs, 2x10-2 IPs)
850
+ // - MinAllocate 0
851
+ // - MaxAllocate 0
852
+ // - PreAllocate 8
853
+ // - FirstInterfaceIndex 0
854
+ func (e * ENISuite ) TestNodeManagerStaticIP (c * check.C ) {
855
+ const instanceID = "i-testNodeManagerStaticIP-0"
856
+
857
+ ec2api := ec2mock .NewAPI ([]* ipamTypes.Subnet {testSubnet }, []* ipamTypes.VirtualNetwork {testVpc }, testSecurityGroups )
858
+ instances := NewInstancesManager (ec2api )
859
+ c .Assert (instances , check .Not (check .IsNil ))
860
+ eniID1 , _ , err := ec2api .CreateNetworkInterface (context .TODO (), 0 , "s-1" , "desc" , []string {"sg1" , "sg2" }, false )
861
+ c .Assert (err , check .IsNil )
862
+ _ , err = ec2api .AttachNetworkInterface (context .TODO (), 0 , instanceID , eniID1 )
863
+ c .Assert (err , check .IsNil )
864
+ instances .Resync (context .TODO ())
865
+ mngr , err := ipam .NewNodeManager (instances , k8sapi , metricsapi , 10 , false , false )
866
+ c .Assert (err , check .IsNil )
867
+ c .Assert (mngr , check .Not (check .IsNil ))
868
+
869
+ staticIPTags := map [string ]string {"some-eip-tag" : "some-value" }
870
+ cn := newCiliumNode ("node1" , withTestDefaults (), withInstanceID (instanceID ), withInstanceType ("m5.large" ), withIPAMPreAllocate (8 ), withIPAMStaticIPTags (staticIPTags ))
871
+ mngr .Upsert (cn )
872
+ c .Assert (testutils .WaitUntil (func () bool { return reachedAddressesNeeded (mngr , "node1" , 0 ) }, 5 * time .Second ), check .IsNil )
873
+
874
+ node := mngr .Get ("node1" )
875
+ c .Assert (node , check .Not (check .IsNil ))
876
+ c .Assert (node .Stats ().AvailableIPs , check .Equals , 8 )
877
+ c .Assert (node .Stats ().UsedIPs , check .Equals , 0 )
878
+
879
+ // Use 1 IP
880
+ mngr .Upsert (updateCiliumNode (cn , 8 , 1 ))
881
+ c .Assert (testutils .WaitUntil (func () bool { return reachedAddressesNeeded (mngr , "node1" , 0 ) }, 5 * time .Second ), check .IsNil )
882
+
883
+ node = mngr .Get ("node1" )
884
+ c .Assert (node , check .Not (check .IsNil ))
885
+ // Verify that the static IP has been successfully assigned
886
+ c .Assert (node .Stats ().AssignedStaticIP , check .Equals , "192.0.2.254" )
887
+ }
888
+
889
+ // TestNodeManagerStaticIPAlreadyAssociated verifies that when an ENI already has a public IP assigned to it, it is properly detected
890
+ //
891
+ // - m5.large (3x ENIs, 2x10-2 IPs)
892
+ // - MinAllocate 0
893
+ // - MaxAllocate 0
894
+ // - PreAllocate 8
895
+ // - FirstInterfaceIndex 0
896
+ func (e * ENISuite ) TestNodeManagerStaticIPAlreadyAssociated (c * check.C ) {
897
+ const instanceID = "i-testNodeManagerStaticIPAlreadyAssociated-0"
898
+
899
+ ec2api := ec2mock .NewAPI ([]* ipamTypes.Subnet {testSubnet }, []* ipamTypes.VirtualNetwork {testVpc }, testSecurityGroups )
900
+ instances := NewInstancesManager (ec2api )
901
+ c .Assert (instances , check .Not (check .IsNil ))
902
+ eniID1 , _ , err := ec2api .CreateNetworkInterface (context .TODO (), 0 , "s-1" , "desc" , []string {"sg1" , "sg2" }, false )
903
+ c .Assert (err , check .IsNil )
904
+ _ , err = ec2api .AttachNetworkInterface (context .TODO (), 0 , instanceID , eniID1 )
905
+ c .Assert (err , check .IsNil )
906
+ staticIP , err := ec2api .AssociateEIP (context .TODO (), instanceID , make (ipamTypes.Tags ))
907
+ c .Assert (err , check .IsNil )
908
+ instances .Resync (context .TODO ())
909
+ mngr , err := ipam .NewNodeManager (instances , k8sapi , metricsapi , 10 , false , false )
910
+ c .Assert (err , check .IsNil )
911
+ c .Assert (mngr , check .Not (check .IsNil ))
912
+
913
+ cn := newCiliumNode ("node1" , withTestDefaults (), withInstanceID (instanceID ), withInstanceType ("m5.large" ), withIPAMPreAllocate (8 ))
914
+ mngr .Upsert (cn )
915
+ c .Assert (testutils .WaitUntil (func () bool { return reachedAddressesNeeded (mngr , "node1" , 0 ) }, 5 * time .Second ), check .IsNil )
916
+
917
+ node := mngr .Get ("node1" )
918
+ c .Assert (node , check .Not (check .IsNil ))
919
+ c .Assert (node .Stats ().AvailableIPs , check .Equals , 8 )
920
+ c .Assert (node .Stats ().UsedIPs , check .Equals , 0 )
921
+ // Verify that the static IP which has already been assigned to the ENI has been successfully detected
922
+ c .Assert (node .Stats ().AssignedStaticIP , check .Equals , staticIP )
923
+ }
924
+
847
925
func benchmarkAllocWorker (c * check.C , workers int64 , delay time.Duration , rateLimit float64 , burst int ) {
848
926
testSubnet1 := & ipamTypes.Subnet {ID : "s-1" , AvailabilityZone : "us-west-1" , VirtualNetworkID : "vpc-1" , AvailableAddresses : 1000000 }
849
927
testSubnet2 := & ipamTypes.Subnet {ID : "s-2" , AvailabilityZone : "us-west-1" , VirtualNetworkID : "vpc-1" , AvailableAddresses : 1000000 }
@@ -1004,6 +1082,12 @@ func withIPAMMaxAboveWatermark(aboveWM int) func(*v2.CiliumNode) {
1004
1082
}
1005
1083
}
1006
1084
1085
+ func withIPAMStaticIPTags (tags map [string ]string ) func (* v2.CiliumNode ) {
1086
+ return func (cn * v2.CiliumNode ) {
1087
+ cn .Spec .IPAM .StaticIPTags = tags
1088
+ }
1089
+ }
1090
+
1007
1091
func withExcludeInterfaceTags (tags map [string ]string ) func (* v2.CiliumNode ) {
1008
1092
return func (cn * v2.CiliumNode ) {
1009
1093
cn .Spec .ENI .ExcludeInterfaceTags = tags
0 commit comments