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

IPAM related bugfixes #10587

Merged
merged 5 commits into from Mar 17, 2020
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
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -281,6 +281,7 @@ generate-health-api: api/v1/health/openapi.yaml
generate-k8s-api:
$(call generate_k8s_api_all,github.com/cilium/cilium/pkg/k8s/apis,"cilium.io:v2")
$(call generate_k8s_api_deepcopy,github.com/cilium/cilium/pkg/aws,"eni:types")
$(call generate_k8s_api_deepcopy,github.com/cilium/cilium/pkg,"aws:types")
$(call generate_k8s_api_deepcopy,github.com/cilium/cilium/pkg,"azure:types")
$(call generate_k8s_api_deepcopy,github.com/cilium/cilium/pkg,"ipam:types")
$(call generate_k8s_api_deepcopy,github.com/cilium/cilium/pkg,"policy:api")
Expand Down
24 changes: 16 additions & 8 deletions pkg/aws/ec2/mock/mock.go
Expand Up @@ -95,25 +95,33 @@ func NewAPI(subnets []*ipamTypes.Subnet, vpcs []*ipamTypes.VirtualNetwork, secur
// UpdateSubnets replaces the subents which the mock API will return
func (e *API) UpdateSubnets(subnets []*ipamTypes.Subnet) {
e.mutex.Lock()
e.subnets = map[string]*ipamTypes.Subnet{}
for _, s := range subnets {
e.subnets[s.ID] = s
e.subnets[s.ID] = s.DeepCopy()
}
e.mutex.Unlock()
}

// UpdateSecurityGroups replaces the security groups which the mock API will return
func (e *API) UpdateSecurityGroups(securityGroups []*types.SecurityGroup) {
e.mutex.Lock()
e.securityGroups = map[string]*types.SecurityGroup{}
for _, sg := range securityGroups {
e.securityGroups[sg.ID] = sg
e.securityGroups[sg.ID] = sg.DeepCopy()
}
e.mutex.Unlock()
}

// UpdateENIs replaces the ENIs which the mock API will return
func (e *API) UpdateENIs(enis map[string]ENIMap) {
e.mutex.Lock()
e.enis = enis
e.enis = map[string]ENIMap{}
for instanceID, m := range enis {
e.enis[instanceID] = ENIMap{}
for eniID, eni := range m {
e.enis[instanceID][eniID] = eni.DeepCopy()
}
}
e.mutex.Unlock()
}

Expand Down Expand Up @@ -199,7 +207,7 @@ func (e *API) CreateNetworkInterface(ctx context.Context, toAllocate int64, subn
subnet.AvailableAddresses -= int(toAllocate)

e.unattached[eniID] = eni
return eniID, eni, nil
return eniID, eni.DeepCopy(), nil
}

func (e *API) DeleteNetworkInterface(ctx context.Context, eniID string) error {
Expand Down Expand Up @@ -371,7 +379,7 @@ func (e *API) GetInstances(ctx context.Context, vpcs ipamTypes.VirtualNetworkMap
}
}

instances.Add(instanceID, eni)
instances.Add(instanceID, eni.DeepCopy())
}
}

Expand All @@ -385,7 +393,7 @@ func (e *API) GetVpcs(ctx context.Context) (ipamTypes.VirtualNetworkMap, error)
defer e.mutex.RUnlock()

for _, v := range e.vpcs {
vpcs[v.ID] = v
vpcs[v.ID] = v.DeepCopy()
}
return vpcs, nil
}
Expand All @@ -397,7 +405,7 @@ func (e *API) GetSubnets(ctx context.Context) (ipamTypes.SubnetMap, error) {
defer e.mutex.RUnlock()

for _, s := range e.subnets {
subnets[s.ID] = s
subnets[s.ID] = s.DeepCopy()
}
return subnets, nil
}
Expand All @@ -423,7 +431,7 @@ func (e *API) GetSecurityGroups(ctx context.Context) (types.SecurityGroupMap, er
defer e.mutex.RUnlock()

for _, sg := range e.securityGroups {
securityGroups[sg.ID] = sg
securityGroups[sg.ID] = sg.DeepCopy()
}
return securityGroups, nil
}
17 changes: 17 additions & 0 deletions pkg/aws/ec2/mock/mock_test.go
Expand Up @@ -22,6 +22,7 @@ import (
"testing"

"github.com/cilium/cilium/pkg/aws/types"
"github.com/cilium/cilium/pkg/checker"
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"

"gopkg.in/check.v1"
Expand Down Expand Up @@ -72,6 +73,22 @@ func (e *MockSuite) TestMock(c *check.C) {
c.Assert(ok, check.Equals, false)
_, ok = api.enis["i-1"][eniID2]
c.Assert(ok, check.Equals, false)

sg1 := &types.SecurityGroup{
ID: "sg1",
VpcID: "vpc-1",
Tags: map[string]string{"k1": "v1"},
}
sg2 := &types.SecurityGroup{
ID: "sg2",
VpcID: "vpc-1",
Tags: map[string]string{"k1": "v1"},
}
api.UpdateSecurityGroups([]*types.SecurityGroup{sg1, sg2})

sgMap, err := api.GetSecurityGroups(context.TODO())
c.Assert(err, check.IsNil)
c.Assert(sgMap, checker.DeepEquals, types.SecurityGroupMap{"sg1": sg1, "sg2": sg2})
}

func (e *MockSuite) TestSetMockError(c *check.C) {
Expand Down
10 changes: 10 additions & 0 deletions pkg/aws/eni/limits.go
Expand Up @@ -22,6 +22,7 @@ import (
"strings"

ipamTypes "github.com/cilium/cilium/pkg/ipam/types"
"github.com/cilium/cilium/pkg/lock"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/external"
Expand All @@ -32,6 +33,7 @@ import (
// The mappings will be updated from agent configuration at bootstrap time
//
// Source: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html?shortFooter=true#AvailableIpPerENI
var limitsMutex lock.RWMutex
var limits = map[string]ipamTypes.Limits{
"a1.medium": {Adapters: 2, IPv4: 4, IPv6: 4},
"a1.large": {Adapters: 3, IPv4: 10, IPv6: 10},
Expand Down Expand Up @@ -254,12 +256,17 @@ var limits = map[string]ipamTypes.Limits{

// getLimits returns the instance limits of a particular instance type
func getLimits(instanceType string) (limit ipamTypes.Limits, ok bool) {
limitsMutex.RLock()
limit, ok = limits[instanceType]
limitsMutex.RUnlock()
return
}

// UpdateLimitsFromUserDefinedMappings updates limits from the given map
func UpdateLimitsFromUserDefinedMappings(m map[string]string) (err error) {
limitsMutex.Lock()
defer limitsMutex.Unlock()

for instanceType, limitString := range m {
limit, err := parseLimitString(limitString)
if err != nil {
Expand Down Expand Up @@ -304,6 +311,9 @@ func UpdateLimitsFromEC2API(ctx context.Context) error {
instanceTypeInfos = append(instanceTypeInfos, describeInstanceTypesResponse.InstanceTypes...)
}

limitsMutex.Lock()
defer limitsMutex.Unlock()

for _, instanceTypeInfo := range instanceTypeInfos {
instanceType := string(instanceTypeInfo.InstanceType)
adapterLimit := aws.Int64Value(instanceTypeInfo.NetworkInfo.MaximumNetworkInterfaces)
Expand Down
4 changes: 3 additions & 1 deletion pkg/aws/types/types.go
@@ -1,4 +1,4 @@
// Copyright 2019 Authors of Cilium
// Copyright 2019-2020 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -20,6 +20,8 @@ import (
)

// SecurityGroup is the representation of an AWS Security Group
//
// +k8s:deepcopy-gen=true
type SecurityGroup struct {
// ID is the SecurityGroup ID
ID string
Expand Down
46 changes: 46 additions & 0 deletions pkg/aws/types/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pkg/ipam/node.go
Expand Up @@ -261,7 +261,9 @@ func (n *Node) recalculateLocked() {
}

n.available = a
n.stats.UsedIPs = len(n.resource.Status.IPAM.Used)
if n.resource != nil {
n.stats.UsedIPs = len(n.resource.Status.IPAM.Used)
}
n.stats.AvailableIPs = len(n.available)
n.stats.NeededIPs = calculateNeededIPs(n.stats.AvailableIPs, n.stats.UsedIPs, n.ops.GetPreAllocate(), n.ops.GetMinAllocate())
n.stats.ExcessIPs = calculateExcessIPs(n.stats.AvailableIPs, n.stats.UsedIPs, n.ops.GetPreAllocate(), n.ops.GetMinAllocate(), n.ops.GetMaxAboveWatermark())
Expand Down
42 changes: 42 additions & 0 deletions pkg/ipam/types/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.