Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eni: Fix Cilium overallocating network interfaces #15911

Merged
merged 2 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 12 additions & 3 deletions pkg/aws/ec2/mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ func (e *API) rateLimit() {
}
}

// CreateNetworkInterface mocks the interface creation. As with the upstream
// EC2 API, the number of IP addresses in toAllocate are the number of
// secondary IPs, a primary IP is always allocated.
func (e *API) CreateNetworkInterface(ctx context.Context, toAllocate int32, subnetID, desc string, groups []string) (string, *eniTypes.ENI, error) {
e.rateLimit()
e.delaySim.Delay(CreateNetworkInterface)
Expand All @@ -182,7 +185,8 @@ func (e *API) CreateNetworkInterface(ctx context.Context, toAllocate int32, subn
return "", nil, fmt.Errorf("subnet %s not found", subnetID)
}

if int(toAllocate) > subnet.AvailableAddresses {
numAddresses := int(toAllocate) + 1 // include primary IP
if numAddresses > subnet.AvailableAddresses {
return "", nil, fmt.Errorf("subnet %s has not enough addresses available", subnetID)
}

Expand All @@ -196,15 +200,20 @@ func (e *API) CreateNetworkInterface(ctx context.Context, toAllocate int32, subn
SecurityGroups: groups,
}

primaryIP, err := e.allocator.AllocateNext()
if err != nil {
panic("Unable to allocate primary IP from allocator")
}
eni.IP = primaryIP.String()

for i := int32(0); i < toAllocate; i++ {
ip, err := e.allocator.AllocateNext()
if err != nil {
panic("Unable to allocate IP from allocator")
}
eni.Addresses = append(eni.Addresses, ip.String())
}

subnet.AvailableAddresses -= int(toAllocate)
subnet.AvailableAddresses -= numAddresses

e.unattached[eniID] = eni
return eniID, eni.DeepCopy(), nil
Expand Down
14 changes: 11 additions & 3 deletions pkg/aws/eni/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ func (n *Node) PrepareIPAllocation(scopedLog *logrus.Entry) (a *ipam.AllocationA
continue
}

availableOnENI := math.IntMax(limits.IPv4-len(e.Addresses), 0)
// The limits include the primary IP, so we need to take it into account
// when computing the amount of available addresses on the ENI.
availableOnENI := math.IntMax(limits.IPv4-len(e.Addresses)-1, 0)
if availableOnENI <= 0 {
continue
} else {
Expand Down Expand Up @@ -551,8 +553,11 @@ func (n *Node) GetMaximumAllocatableIPv4() int {
return 0
}

// limits.IPv4 contains the primary IP which is not available for allocation
maxPerInterface := math.IntMax(limits.IPv4-1, 0)

// Return the maximum amount of IP addresses allocatable on the instance
return (limits.Adapters - firstInterfaceIndex) * limits.IPv4
return (limits.Adapters - firstInterfaceIndex) * maxPerInterface
}

var adviseOperatorFlagOnce sync.Once
Expand Down Expand Up @@ -609,5 +614,8 @@ func (n *Node) GetMinimumAllocatableIPv4() int {
return 0
}

return math.IntMin(minimum, (limits.Adapters-index)*limits.IPv4)
// limits.IPv4 contains the primary IP which is not available for allocation
maxPerInterface := math.IntMax(limits.IPv4-1, 0)

return math.IntMin(minimum, (limits.Adapters-index)*maxPerInterface)
}
91 changes: 46 additions & 45 deletions pkg/aws/eni/node_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ func (e *ENISuite) TestGetNodeNames(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(mngr, check.Not(check.IsNil))

eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testGetNodeNames-1", eniID1)
c.Assert(err, check.IsNil)
eniID2, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID2, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testGetNodeNames-2", eniID2)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -116,7 +116,7 @@ func (e *ENISuite) TestNodeManagerGet(c *check.C) {
c.Assert(err, check.IsNil)
c.Assert(mngr, check.Not(check.IsNil))

eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerGet-1", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -238,7 +238,7 @@ func reachedAddressesNeeded(mngr *ipam.NodeManager, nodeName string, needed int)

// TestNodeManagerDefaultAllocation tests allocation with default parameters
//
// - m5.large (3x ENIs, 2x10 IPs)
// - m5.large (3x ENIs, 2x10-2 IPs)
// - MinAllocate 0
// - MaxAllocate 0
// - PreAllocate 8
Expand All @@ -247,7 +247,7 @@ func (e *ENISuite) TestNodeManagerDefaultAllocation(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerDefaultAllocation-0", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -278,7 +278,7 @@ func (e *ENISuite) TestNodeManagerDefaultAllocation(c *check.C) {

// TestNodeManagerENIWithSGTags tests ENI allocation + association with a SG based on tags
//
// - m5.large (3x ENIs, 2x10 IPs)
// - m5.large (3x ENIs, 2x10-2 IPs)
// - MinAllocate 0
// - MaxAllocate 0
// - PreAllocate 8
Expand All @@ -287,7 +287,7 @@ func (e *ENISuite) TestNodeManagerENIWithSGTags(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerDefaultAllocation-0", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -333,7 +333,7 @@ func (e *ENISuite) TestNodeManagerENIWithSGTags(c *check.C) {

// TestNodeManagerMinAllocate20 tests MinAllocate without PreAllocate
//
// - m5.4xlarge (8x ENIs, 7x30 IPs)
// - m5.4xlarge (8x ENIs, 7x30-7 IPs)
// - MinAllocate 10
// - MaxAllocate 0
// - PreAllocate -1
Expand All @@ -342,7 +342,7 @@ func (e *ENISuite) TestNodeManagerMinAllocate20(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerMinAllocate20-1", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -383,7 +383,7 @@ func (e *ENISuite) TestNodeManagerMinAllocate20(c *check.C) {

// TestNodeManagerMinAllocateAndPreallocate tests MinAllocate in combination with PreAllocate
//
// - m3.large (3x ENIs, 2x10 IPs)
// - m3.large (3x ENIs, 2x10-2 IPs)
// - MinAllocate 10
// - MaxAllocate 0
// - PreAllocate 1
Expand All @@ -392,7 +392,7 @@ func (e *ENISuite) TestNodeManagerMinAllocateAndPreallocate(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerMinAllocateAndPreallocate-1", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -439,17 +439,17 @@ func (e *ENISuite) TestNodeManagerMinAllocateAndPreallocate(c *check.C) {
// TestNodeManagerReleaseAddress tests PreAllocate, MinAllocate and MaxAboveWatermark
// when release excess IP is enabled
//
// - m4.large (4x ENIs, 3x15 IPs)
// - m4.large (4x ENIs, 3x15-3 IPs)
// - MinAllocate 10
// - MaxAllocate 0
// - PreAllocate 4
// - MaxAboveWatermark 4
// - PreAllocate 2
// - MaxAboveWatermark 3
// - FirstInterfaceIndex 0
func (e *ENISuite) TestNodeManagerReleaseAddress(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerReleaseAddress-1", eniID1)
c.Assert(err, check.IsNil)
Expand All @@ -459,46 +459,46 @@ func (e *ENISuite) TestNodeManagerReleaseAddress(c *check.C) {
c.Assert(mngr, check.Not(check.IsNil))

// Announce node, wait for IPs to become available
cn := newCiliumNode("node3", "i-testNodeManagerReleaseAddress-1", "m4.xlarge", "us-west-1", "vpc-1", 0, 4, 10, 0)
cn.Spec.IPAM.MaxAboveWatermark = 4
cn := newCiliumNode("node3", "i-testNodeManagerReleaseAddress-1", "m4.xlarge", "us-west-1", "vpc-1", 0, 2, 10, 0)
cn.Spec.IPAM.MaxAboveWatermark = 3
mngr.Update(cn)
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node3", 0) }, 5*time.Second), check.IsNil)

// 10 min-allocate + 4 max-above-watermark => 14 IPs must become
// available as 14 < 15 (interface limit)
// 10 min-allocate + 3 max-above-watermark => 13 IPs must become
// available as 13 < 14 (interface limit)
node := mngr.Get("node3")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 14)
c.Assert(node.Stats().AvailableIPs, check.Equals, 13)
c.Assert(node.Stats().UsedIPs, check.Equals, 0)

// Use 11 out of 14 IPs, no additional IPs should be allocated
mngr.Update(updateCiliumNode(cn, 14, 11))
// Use 11 out of 13 IPs, no additional IPs should be allocated
mngr.Update(updateCiliumNode(cn, 13, 11))
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node3", 0) }, 5*time.Second), check.IsNil)
node = mngr.Get("node3")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 15)
c.Assert(node.Stats().AvailableIPs, check.Equals, 13)
c.Assert(node.Stats().UsedIPs, check.Equals, 11)

// Use 14 out of 15 IPs, PreAllocate 4 + MaxAboveWatermark must kick in
// and allocate 8 additional IPs
mngr.Update(updateCiliumNode(cn, 15, 14))
// Use 13 out of 13 IPs, PreAllocate 2 + MaxAboveWatermark 3 must kick in
// and allocate 5 additional IPs
mngr.Update(updateCiliumNode(cn, 13, 13))
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node3", 0) }, 5*time.Second), check.IsNil)
node = mngr.Get("node3")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 22)
c.Assert(node.Stats().UsedIPs, check.Equals, 14)
c.Assert(node.Stats().AvailableIPs, check.Equals, 18)
c.Assert(node.Stats().UsedIPs, check.Equals, 13)

// Reduce used IPs to 10, this leads to 15 excess IPs but release
// Reduce used IPs to 10, this leads to 8 excess IPs but release
// occurs at interval based resync, so expect timeout at first
mngr.Update(updateCiliumNode(cn, 22, 10))
mngr.Update(updateCiliumNode(cn, 18, 10))
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node3", 0) }, 2*time.Second), check.Not(check.IsNil))
node = mngr.Get("node3")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 22)
c.Assert(node.Stats().AvailableIPs, check.Equals, 18)
c.Assert(node.Stats().UsedIPs, check.Equals, 10)

// Trigger resync manually, excess IPs should be released
// 10 used + 4 pre-allocate + 4 max-above-watermark => 18
// 10 used + 3 pre-allocate + 2 max-above-watermark => 15
node = mngr.Get("node3")
eniNode, castOK := node.Ops().(*Node)
c.Assert(castOK, check.Equals, true)
Expand All @@ -512,13 +512,13 @@ func (e *ENISuite) TestNodeManagerReleaseAddress(c *check.C) {
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node3", 0) }, 5*time.Second), check.IsNil)
node = mngr.Get("node3")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 18)
c.Assert(node.Stats().AvailableIPs, check.Equals, 15)
c.Assert(node.Stats().UsedIPs, check.Equals, 10)
}

// TestNodeManagerExceedENICapacity tests exceeding ENI capacity
//
// - t2.xlarge (3x ENIs, 3x15 IPs)
// - t2.xlarge (3x ENIs, 3x15-3 IPs)
// - MinAllocate 20
// - MaxAllocate 0
// - PreAllocate 8
Expand All @@ -527,7 +527,7 @@ func (e *ENISuite) TestNodeManagerExceedENICapacity(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerExceedENICapacity-1", eniID1)
c.Assert(err, check.IsNil)
Expand All @@ -547,13 +547,14 @@ func (e *ENISuite) TestNodeManagerExceedENICapacity(c *check.C) {
c.Assert(node.Stats().UsedIPs, check.Equals, 0)

// Use 40 out of 42 available IPs, we should reach 0 address needed once we
// assigned the remaining 3 that the t2.xlarge instance type supports (45 max)
// assigned the remaining 3 that the t2.xlarge instance type supports
// (3x15 - 3 = 42 max)
mngr.Update(updateCiliumNode(cn, 42, 40))
c.Assert(testutils.WaitUntil(func() bool { return reachedAddressesNeeded(mngr, "node2", 0) }, 5*time.Second), check.IsNil)

node = mngr.Get("node2")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 45)
c.Assert(node.Stats().AvailableIPs, check.Equals, 42)
c.Assert(node.Stats().UsedIPs, check.Equals, 40)
}

Expand All @@ -565,7 +566,7 @@ type nodeState struct {

// TestNodeManagerManyNodes tests IP allocation of 100 nodes across 3 subnets
//
// - c3.xlarge (4x ENIs, 4x15 IPs)
// - c3.xlarge (4x ENIs, 4x15-4 IPs)
// - MinAllocate 10
// - MaxAllocate 0
// - PreAllocate 1
Expand All @@ -592,7 +593,7 @@ func (e *ENISuite) TestNodeManagerManyNodes(c *check.C) {
state := make([]*nodeState, numNodes)

for i := range state {
eniID, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "mgmt-1", "desc", []string{"sg1", "sg2"})
eniID, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "mgmt-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, fmt.Sprintf("i-testNodeManagerManyNodes-%d", i), eniID)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -650,7 +651,7 @@ func (e *ENISuite) TestNodeManagerInstanceNotRunning(c *check.C) {
metricsMock := metricsmock.NewMockMetrics()
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testNodeManagerInstanceNotRunning-0", eniID1)
c.Assert(err, check.IsNil)
Expand Down Expand Up @@ -684,13 +685,13 @@ func (e *ENISuite) TestNodeManagerInstanceNotRunning(c *check.C) {
// TestInstanceBeenDeleted verifies that instance deletion is correctly detected
// and no further action is taken
//
// - m4.large (2x ENIs, 2x10 IPs)
// - m4.large (2x ENIs, 2x10-2 IPs)
// - FirstInterfaceIndex 0
func (e *ENISuite) TestInstanceBeenDeleted(c *check.C) {
ec2api := ec2mock.NewAPI([]*ipamTypes.Subnet{testSubnet}, []*ipamTypes.VirtualNetwork{testVpc}, testSecurityGroups)
instances := NewInstancesManager(ec2api)
c.Assert(instances, check.Not(check.IsNil))
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID1, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, "i-testInstanceBeenDeleted-0", eniID1)
c.Assert(err, check.IsNil)
Expand All @@ -709,7 +710,7 @@ func (e *ENISuite) TestInstanceBeenDeleted(c *check.C) {

node := mngr.Get("node1")
c.Assert(node, check.Not(check.IsNil))
c.Assert(node.Stats().AvailableIPs, check.Equals, 9)
c.Assert(node.Stats().AvailableIPs, check.Equals, 8)
c.Assert(node.Stats().UsedIPs, check.Equals, 0)

// Delete all enis attached to instance, this mocks the operation of
Expand All @@ -724,7 +725,7 @@ func (e *ENISuite) TestInstanceBeenDeleted(c *check.C) {
mngr.Update(updateCiliumNode(cn, 9, 2))

// Instance deletion detected, no allocation happened despite of the IP deficit.
c.Assert(node.Stats().AvailableIPs, check.Equals, 9)
c.Assert(node.Stats().AvailableIPs, check.Equals, 8)
c.Assert(node.Stats().UsedIPs, check.Equals, 0)
c.Assert(node.Stats().NeededIPs, check.Equals, 0)
c.Assert(node.Stats().ExcessIPs, check.Equals, 0)
Expand All @@ -748,7 +749,7 @@ func benchmarkAllocWorker(c *check.C, workers int64, delay time.Duration, rateLi

c.ResetTimer()
for i := range state {
eniID, _, err := ec2api.CreateNetworkInterface(context.TODO(), 1, "s-1", "desc", []string{"sg1", "sg2"})
eniID, _, err := ec2api.CreateNetworkInterface(context.TODO(), 0, "s-1", "desc", []string{"sg1", "sg2"})
c.Assert(err, check.IsNil)
_, err = ec2api.AttachNetworkInterface(context.TODO(), 0, fmt.Sprintf("i-benchmarkAllocWorker-%d", i), eniID)
c.Assert(err, check.IsNil)
Expand Down
8 changes: 4 additions & 4 deletions pkg/aws/eni/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ func (e *ENISuite) TestGetMaximumAllocatableIPv4(c *check.C) {
// With no k8sObj defined, it should return 0
c.Assert(n.GetMaximumAllocatableIPv4(), check.Equals, 0)

// With instance-type = m5.large and first-interface-index = 0, we should be able to allocate up to 30 addresses
// With instance-type = m5.large and first-interface-index = 0, we should be able to allocate up to 3x10-3 addresses
n.k8sObj = newCiliumNode("node", "i-testnode", "m5.large", "eu-west-1", "test-vpc", 0, 0, 0, 0)
c.Assert(n.GetMaximumAllocatableIPv4(), check.Equals, 30)
c.Assert(n.GetMaximumAllocatableIPv4(), check.Equals, 27)

// With instance-type = m5.large and first-interface-index = 1, we should be able to allocate up to 20 addresses
// With instance-type = m5.large and first-interface-index = 1, we should be able to allocate up to 2x10-2 addresses
n.k8sObj = newCiliumNode("node", "i-testnode", "m5.large", "eu-west-1", "test-vpc", 1, 0, 0, 0)
c.Assert(n.GetMaximumAllocatableIPv4(), check.Equals, 20)
c.Assert(n.GetMaximumAllocatableIPv4(), check.Equals, 18)

// With instance-type = m5.large and first-interface-index = 4, we should return 0 as there is only 3 interfaces
n.k8sObj = newCiliumNode("node", "i-testnode", "m5.large", "eu-west-1", "test-vpc", 4, 0, 0, 0)
Expand Down
3 changes: 1 addition & 2 deletions pkg/aws/eni/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,7 @@ type ENI struct {
// +optional
VPC AwsVPC `json:"vpc,omitempty"`

// Addresses is the list of all IPs associated with the ENI, including
// all secondary addresses
// Addresses is the list of all secondary IPs associated with the ENI
//
// +optional
Addresses []string `json:"addresses,omitempty"`
Expand Down