Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
orsenthil authored Sep 25, 2024
2 parents 3adee43 + abaf575 commit 934c6d8
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 29 deletions.
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ require (
github.com/aws/aws-sdk-go v1.55.5
github.com/containernetworking/cni v1.2.3
github.com/containernetworking/plugins v1.5.1
github.com/coreos/go-iptables v0.7.0
github.com/coreos/go-iptables v0.8.0
github.com/go-logr/logr v1.4.2
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.6.0
github.com/onsi/ginkgo/v2 v2.19.1
github.com/onsi/gomega v1.34.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.19.1
github.com/prometheus/client_model v0.6.0
github.com/prometheus/client_model v0.6.1
github.com/prometheus/common v0.53.0
github.com/samber/lo v1.39.0
github.com/sirupsen/logrus v1.9.3
Expand All @@ -26,7 +26,7 @@ require (
github.com/vishvananda/netlink v1.2.1-beta.2
go.uber.org/zap v1.26.0
golang.org/x/net v0.27.0
golang.org/x/sys v0.22.0
golang.org/x/sys v0.25.0
google.golang.org/grpc v1.62.0
google.golang.org/protobuf v1.34.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8F
github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M=
github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
Expand Down Expand Up @@ -351,8 +351,8 @@ github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJL
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
Expand Down Expand Up @@ -493,8 +493,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
Expand Down
15 changes: 8 additions & 7 deletions pkg/ipamd/ipamd.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
"github.com/aws/amazon-vpc-cni-k8s/pkg/ipamd/datastore"
"github.com/aws/amazon-vpc-cni-k8s/pkg/k8sapi"
"github.com/aws/amazon-vpc-cni-k8s/pkg/networkutils"
"github.com/aws/amazon-vpc-cni-k8s/pkg/utils/cniutils"
"github.com/aws/amazon-vpc-cni-k8s/pkg/utils/logger"
"github.com/aws/amazon-vpc-cni-k8s/utils"
"github.com/aws/amazon-vpc-cni-k8s/utils/prometheusmetrics"
Expand Down Expand Up @@ -1455,8 +1456,8 @@ func (c *IPAMContext) eniIPPoolReconcile(ipPool []string, attachedENI awsutils.E
attachedENIIPs := attachedENI.IPv4Addresses
needEC2Reconcile := true
// Here we can't trust attachedENI since the IMDS metadata can be stale. We need to check with EC2 API.
// +1 is for the primary IP of the ENI that is not added to the ipPool and not available for pods to use.
if 1+len(ipPool) != len(attachedENIIPs) {
// IPsSimilar will exclude primary IP of the ENI that is not added to the ipPool and not available for pods to use.
if !cniutils.IPsSimilar(ipPool, attachedENIIPs) {
log.Warnf("Instance metadata does not match data store! ipPool: %v, metadata: %v", ipPool, attachedENIIPs)
log.Debugf("We need to check the ENI status by calling the EC2 control plane.")
// Call EC2 to verify IPs on this ENI
Expand Down Expand Up @@ -1492,14 +1493,14 @@ func (c *IPAMContext) eniIPPoolReconcile(ipPool []string, attachedENI awsutils.E
}
}

func (c *IPAMContext) eniPrefixPoolReconcile(ipPool []string, attachedENI awsutils.ENIMetadata, eni string) {
func (c *IPAMContext) eniPrefixPoolReconcile(prefixPool []string, attachedENI awsutils.ENIMetadata, eni string) {
attachedENIIPs := attachedENI.IPv4Prefixes
needEC2Reconcile := true
// Here we can't trust attachedENI since the IMDS metadata can be stale. We need to check with EC2 API.
log.Debugf("Found prefix pool count %d for eni %s\n", len(ipPool), eni)
log.Debugf("Found prefix pool count %d for eni %s\n", len(prefixPool), eni)

if len(ipPool) != len(attachedENIIPs) {
log.Warnf("Instance metadata does not match data store! ipPool: %v, metadata: %v", ipPool, attachedENIIPs)
if !cniutils.PrefixSimilar(prefixPool, attachedENIIPs) {
log.Warnf("Instance metadata does not match data store! ipPool: %v, metadata: %v", prefixPool, attachedENIIPs)
log.Debugf("We need to check the ENI status by calling the EC2 control plane.")
// Call EC2 to verify IPs on this ENI
ec2Addresses, err := c.awsClient.GetIPv4PrefixesFromEC2(eni)
Expand All @@ -1515,7 +1516,7 @@ func (c *IPAMContext) eniPrefixPoolReconcile(ipPool []string, attachedENI awsuti
seenIPs := c.verifyAndAddPrefixesToDatastore(eni, attachedENIIPs, needEC2Reconcile)

// Sweep phase, delete remaining Prefixes since they should not remain in the datastore
for _, existingIP := range ipPool {
for _, existingIP := range prefixPool {
if seenIPs[existingIP] {
continue
}
Expand Down
49 changes: 49 additions & 0 deletions pkg/utils/cniutils/cni_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/aws/amazon-vpc-cni-k8s/pkg/netlinkwrapper"
"github.com/aws/amazon-vpc-cni-k8s/pkg/procsyswrapper"
"github.com/aws/amazon-vpc-cni-k8s/utils/imds"
"github.com/aws/aws-sdk-go/service/ec2"
)

const (
Expand Down Expand Up @@ -145,3 +146,51 @@ func IsIptableTargetNotExist(err error) bool {
}
return e.IsNotExist()
}

// PrefixSimilar checks if prefix pool and eni prefix are equivalent.
func PrefixSimilar(prefixPool []string, eniPrefixes []*ec2.Ipv4PrefixSpecification) bool {
if len(prefixPool) != len(eniPrefixes) {
return false
}

prefixPoolSet := make(map[string]struct{}, len(prefixPool))
for _, ip := range prefixPool {
prefixPoolSet[ip] = struct{}{}
}

for _, prefix := range eniPrefixes {
if prefix == nil || prefix.Ipv4Prefix == nil {
return false
}
if _, exists := prefixPoolSet[*prefix.Ipv4Prefix]; !exists {
return false
}
}
return true
}

// IPsSimilar checks if ipPool and eniIPs are equivalent.
func IPsSimilar(ipPool []string, eniIPs []*ec2.NetworkInterfacePrivateIpAddress) bool {
// Here we do +1 in ipPool because eniIPs will also have primary IP which is not used by pods.
if len(ipPool)+1 != len(eniIPs) {
return false
}

ipPoolSet := make(map[string]struct{}, len(ipPool))
for _, ip := range ipPool {
ipPoolSet[ip] = struct{}{}
}

for _, ip := range eniIPs {
if ip == nil || ip.PrivateIpAddress == nil || ip.Primary == nil {
return false
}
if *ip.Primary {
continue
}
if _, exists := ipPoolSet[*ip.PrivateIpAddress]; !exists {
return false
}
}
return true
}
131 changes: 131 additions & 0 deletions pkg/utils/cniutils/cni_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -208,3 +209,133 @@ func Test_FindIPConfigsByIfaceIndex(t *testing.T) {
})
}
}

func TestPrefixSimilar(t *testing.T) {
tests := []struct {
name string
prefixPool []string
eniPrefixes []*ec2.Ipv4PrefixSpecification
want bool
}{
{
name: "Empty slices",
prefixPool: []string{},
eniPrefixes: []*ec2.Ipv4PrefixSpecification{},
want: true,
},
{
name: "Different lengths",
prefixPool: []string{"192.168.1.0/24"},
eniPrefixes: []*ec2.Ipv4PrefixSpecification{},
want: false,
},
{
name: "Equivalent prefixes",
prefixPool: []string{"192.168.1.0/24", "10.0.0.0/16"},
eniPrefixes: []*ec2.Ipv4PrefixSpecification{
{Ipv4Prefix: stringPtr("192.168.1.0/24")},
{Ipv4Prefix: stringPtr("10.0.0.0/16")},
},
want: true,
},
{
name: "Different prefixes",
prefixPool: []string{"192.168.1.0/24", "10.0.0.0/16"},
eniPrefixes: []*ec2.Ipv4PrefixSpecification{
{Ipv4Prefix: stringPtr("192.168.1.0/24")},
{Ipv4Prefix: stringPtr("172.16.0.0/16")},
},
want: false,
},
{
name: "Nil prefix",
prefixPool: []string{"192.168.1.0/24"},
eniPrefixes: []*ec2.Ipv4PrefixSpecification{
nil,
},
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := PrefixSimilar(tt.prefixPool, tt.eniPrefixes); got != tt.want {
t.Errorf("in test %s PrefixSimilar() = %v, want %v", tt.name, got, tt.want)
}
})
}
}

func TestIPsSimilar(t *testing.T) {
tests := []struct {
name string
ipPool []string
eniIPs []*ec2.NetworkInterfacePrivateIpAddress
want bool
}{
{
name: "Empty IP pool",
ipPool: []string{},
eniIPs: []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: stringPtr("10.0.0.1"), Primary: boolPtr(true)},
},
want: true,
},
{
name: "Different lengths",
ipPool: []string{"192.168.1.1"},
eniIPs: []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: stringPtr("10.0.0.1"), Primary: boolPtr(true)},
{PrivateIpAddress: stringPtr("192.168.1.1"), Primary: boolPtr(false)},
{PrivateIpAddress: stringPtr("192.168.1.2"), Primary: boolPtr(false)},
},
want: false,
},
{
name: "Equivalent IPs",
ipPool: []string{"192.168.1.1", "10.0.0.2"},
eniIPs: []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: stringPtr("10.0.0.1"), Primary: boolPtr(true)},
{PrivateIpAddress: stringPtr("192.168.1.1"), Primary: boolPtr(false)},
{PrivateIpAddress: stringPtr("10.0.0.2"), Primary: boolPtr(false)},
},
want: true,
},
{
name: "Different IPs",
ipPool: []string{"192.168.1.1", "10.0.0.2"},
eniIPs: []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: stringPtr("10.0.0.1"), Primary: boolPtr(true)},
{PrivateIpAddress: stringPtr("192.168.1.1"), Primary: boolPtr(false)},
{PrivateIpAddress: stringPtr("172.16.0.1"), Primary: boolPtr(false)},
},
want: false,
},
{
name: "Nil IP",
ipPool: []string{"192.168.1.1"},
eniIPs: []*ec2.NetworkInterfacePrivateIpAddress{
{PrivateIpAddress: stringPtr("10.0.0.1"), Primary: boolPtr(true)},
nil,
},
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IPsSimilar(tt.ipPool, tt.eniIPs); got != tt.want {
t.Errorf("in test %s IPsSimilar() = %v, want %v", tt.name, got, tt.want)
}
})
}
}

// Helper functions for creating pointers
func stringPtr(s string) *string {
return &s
}

func boolPtr(b bool) *bool {
return &b
}
8 changes: 4 additions & 4 deletions test/agent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module github.com/aws/amazon-vpc-cni-k8s/test/agent
go 1.22.3

require (
github.com/coreos/go-iptables v0.7.0
github.com/vishvananda/netlink v1.1.0
golang.org/x/sys v0.22.0
github.com/coreos/go-iptables v0.8.0
github.com/vishvananda/netlink v1.3.0
golang.org/x/sys v0.24.0
)

require github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect
require github.com/vishvananda/netns v0.0.4 // indirect
19 changes: 10 additions & 9 deletions test/agent/go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

0 comments on commit 934c6d8

Please sign in to comment.