Skip to content

Commit

Permalink
Merge pull request #73 from dougbtv/gw-for-default
Browse files Browse the repository at this point in the history
Assigns default=true on a multiple interface return for first interface with a gateway
  • Loading branch information
dougbtv authored Oct 15, 2024
2 parents 9b218a2 + 55f81d3 commit 7d2def1
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
35 changes: 33 additions & 2 deletions pkg/utils/net-attach-def.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) {
return netStatuses, err
}

// gatewayInterfaceIndex determines the index of the first interface that has a gateway
func gatewayInterfaceIndex(ips []*cni100.IPConfig) int {
for _, ipConfig := range ips {
if ipConfig.Gateway != nil && ipConfig.Interface != nil {
return *ipConfig.Interface
}
}
return -1
}

// CreateNetworkStatuses creates an array of NetworkStatus from CNI result
// Not to be confused with CreateNetworkStatus (singular)
// This is the preferred method and picks up when CNI ADD results contain multiple container interfaces
Expand Down Expand Up @@ -152,14 +162,36 @@ func CreateNetworkStatuses(r cnitypes.Result, networkName string, defaultNetwork
// Same for DNS
v1dns := convertDNS(result.DNS)

// Check for a gateway-associated interface, we'll use this later if we did to mark as the default.
gwInterfaceIdx := -1
if defaultNetwork {
gwInterfaceIdx = gatewayInterfaceIndex(result.IPs)
}

// Initialize NetworkStatus for each container interface (e.g. with sandbox present)
indexOfFoundPodInterface := 0
foundFirstSandboxIface := false
didSetDefault := false
for i, iface := range result.Interfaces {
if iface.Sandbox != "" {
isDefault := false

// If there's a gateway listed for this interface index found in the ips, we mark that interface as default
// notably, we use the first one we find.
if defaultNetwork && i == gwInterfaceIdx && !didSetDefault {
isDefault = true
didSetDefault = true
}

// Otherwise, if we didn't find it, we use the first sandbox interface.
if defaultNetwork && gwInterfaceIdx == -1 && !foundFirstSandboxIface {
isDefault = true
foundFirstSandboxIface = true
}

ns := &v1.NetworkStatus{
Name: networkName,
Default: defaultNetwork && !foundFirstSandboxIface,
Default: isDefault,
Interface: iface.Name,
Mac: iface.Mac,
Mtu: iface.Mtu,
Expand All @@ -172,7 +204,6 @@ func CreateNetworkStatuses(r cnitypes.Result, networkName string, defaultNetwork
// Map original index to the new slice index
indexMap[i] = indexOfFoundPodInterface
indexOfFoundPodInterface++
foundFirstSandboxIface = true
}
}

Expand Down
56 changes: 56 additions & 0 deletions pkg/utils/net-attach-def_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,62 @@ var _ = Describe("Netwok Attachment Definition manipulations", func() {
Expect(fakeStatus).To(Equal(getStatuses))
})

It("matches default=true when gateway is present for an interface", func() {
// CNI result using cni100.Result format
ifone := 1
iftwo := 3
cniResult := &cni100.Result{
CNIVersion: "1.0.0",
Interfaces: []*cni100.Interface{
{
Name: "0xsomething",
Mac: "be:ee:ee:ee:ee:ef",
},
{
Name: "eth0",
Mac: "b1:aa:aa:aa:a5:ee",
Sandbox: "/var/run/netns/cni-309e7579-1b15-f905-5150-2cd232b0dad9",
},
{
Name: "0xotherthing",
Mac: "b0:00:00:00:00:0f",
},
{
Name: "other-primary",
Mac: "c0:00:00:00:00:01",
Sandbox: "/var/run/netns/cni-309e7579-1b15-f905-5150-2cd232b0dad9",
},
},
IPs: []*cni100.IPConfig{
{
Interface: &ifone,
Address: *EnsureCIDR("10.244.1.6/24"),
},
{
Interface: &iftwo,
Address: *EnsureCIDR("10.20.1.3/24"),
Gateway: net.ParseIP("10.20.1.1"),
},
},
}

// Call CreateNetworkStatuses with this CNI result
networkName := "test-network"
defaultNetwork := true
deviceInfo := &v1.DeviceInfo{} // mock device info if needed

networkStatuses, err := CreateNetworkStatuses(cniResult, networkName, defaultNetwork, deviceInfo)
Expect(err).NotTo(HaveOccurred())
Expect(networkStatuses).To(HaveLen(2)) // expecting 2 statuses for sandboxed interfaces

// Check that the interface with the gateway is marked as default
Expect(networkStatuses[0].Interface).To(Equal("eth0"))
Expect(networkStatuses[0].Default).To(BeFalse())

Expect(networkStatuses[1].Interface).To(Equal("other-primary"))
Expect(networkStatuses[1].Default).To(BeTrue()) // other-primary should be default because it has a gateway
})

Context("create network status from cni result", func() {
var cniResult *cni100.Result
var networkStatus *v1.NetworkStatus
Expand Down

0 comments on commit 7d2def1

Please sign in to comment.