From 4df3b5053f012c013d0f8223ed10bfcf239063ea Mon Sep 17 00:00:00 2001 From: Miguel Duarte Barroso Date: Mon, 22 Nov 2021 13:58:42 +0100 Subject: [PATCH] network-status: add GW info Signed-off-by: Miguel Duarte Barroso --- pkg/apis/k8s.cni.cncf.io/v1/types.go | 1 + pkg/utils/net-attach-def.go | 15 ++- pkg/utils/net-attach-def_test.go | 152 ++++++++++++++++++++------- 3 files changed, 131 insertions(+), 37 deletions(-) diff --git a/pkg/apis/k8s.cni.cncf.io/v1/types.go b/pkg/apis/k8s.cni.cncf.io/v1/types.go index 103659b08..d35e3068d 100644 --- a/pkg/apis/k8s.cni.cncf.io/v1/types.go +++ b/pkg/apis/k8s.cni.cncf.io/v1/types.go @@ -106,6 +106,7 @@ type NetworkStatus struct { Default bool `json:"default,omitempty"` DNS DNS `json:"dns,omitempty"` DeviceInfo *DeviceInfo `json:"device-info,omitempty"` + Gateway []string `json:"gateway,omitempty"` } // PortMapEntry for CNI PortMapEntry diff --git a/pkg/utils/net-attach-def.go b/pkg/utils/net-attach-def.go index 5e78761d7..d949acda3 100644 --- a/pkg/utils/net-attach-def.go +++ b/pkg/utils/net-attach-def.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "net" "regexp" "strings" @@ -72,7 +73,7 @@ func SetNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, statuses []v return nil } -func setPodNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, networkstatus string) (error) { +func setPodNetworkStatus(client kubernetes.Interface, pod *corev1.Pod, networkstatus string) error { if len(pod.Annotations) == 0 { pod.Annotations = make(map[string]string) } @@ -146,6 +147,12 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b netStatus.IPs = append(netStatus.IPs, ipconfig.Address.IP.String()) } + for _, route := range result.Routes { + if isDefaultRoute(route) { + netStatus.Gateway = append(netStatus.Gateway, route.GW.String()) + } + } + v1dns := convertDNS(result.DNS) netStatus.DNS = *v1dns @@ -156,6 +163,12 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b return netStatus, nil } +func isDefaultRoute(route *cnitypes.Route) bool { + return route.Dst.IP == nil && route.Dst.Mask == nil || + route.Dst.IP.Equal(net.IPv4zero) || + route.Dst.IP.Equal(net.IPv6zero) +} + // ParsePodNetworkAnnotation parses Pod annotation for net-attach-def and get NetworkSelectionElement func ParsePodNetworkAnnotation(pod *corev1.Pod) ([]*v1.NetworkSelectionElement, error) { netAnnot := pod.Annotations[v1.NetworkAttachmentAnnot] diff --git a/pkg/utils/net-attach-def_test.go b/pkg/utils/net-attach-def_test.go index 10aac7ed5..f55ad84b1 100644 --- a/pkg/utils/net-attach-def_test.go +++ b/pkg/utils/net-attach-def_test.go @@ -20,7 +20,7 @@ import ( "testing" cnitypes "github.com/containernetworking/cni/pkg/types" - cni100"github.com/containernetworking/cni/pkg/types/100" + cni100 "github.com/containernetworking/cni/pkg/types/100" v1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" @@ -106,43 +106,123 @@ var _ = Describe("Netwok Attachment Definition manipulations", func() { Expect(fakeStatus).To(Equal(getStatuses)) }) - It("create network status from cni result", func() { - cniResult := &cni100.Result{ - CNIVersion: "1.0.0", - Interfaces: []*cni100.Interface{ - { - Name: "net1", - Mac: "92:79:27:01:7c:cf", - Sandbox: "/proc/1123/ns/net", - }, - }, - IPs: []*cni100.IPConfig{ - { - Address: *EnsureCIDR("1.1.1.3/24"), + Context("create network status from cni result", func() { + var cniResult *cni100.Result + var networkStatus *v1.NetworkStatus + + BeforeEach(func() { + cniResult = &cni100.Result{ + CNIVersion: "1.0.0", + Interfaces: []*cni100.Interface{ + { + Name: "net1", + Mac: "92:79:27:01:7c:cf", + Sandbox: "/proc/1123/ns/net", + }, }, - { - Address: *EnsureCIDR("2001::1/64"), + IPs: []*cni100.IPConfig{ + { + Address: *EnsureCIDR("1.1.1.3/24"), + }, + { + Address: *EnsureCIDR("2001::1/64"), + }, }, - }, - } - devInfo := v1.DeviceInfo{ - Type: "pci", - Version: "v1.0.0", - Pci: &v1.PciDevice{ - PciAddress: "0000:01:02.2", - PfPciAddress: "0000:01:02.0", - }, - } - status, err := CreateNetworkStatus(cniResult, "test-net-attach-def", false, &devInfo) - Expect(err).NotTo(HaveOccurred()) - Expect(status.Name).To(Equal("test-net-attach-def")) - Expect(status.Interface).To(Equal("net1")) - Expect(status.Mac).To(Equal("92:79:27:01:7c:cf")) - Expect(status.IPs).To(Equal([]string{"1.1.1.3", "2001::1"})) - Expect(status.DeviceInfo.Type).To(Equal("pci")) - Expect(status.DeviceInfo.Version).To(Equal("v1.0.0")) - Expect(status.DeviceInfo.Pci.PciAddress).To(Equal("0000:01:02.2")) - Expect(status.DeviceInfo.Pci.PfPciAddress).To(Equal("0000:01:02.0")) + } + var err error + networkStatus, err = CreateNetworkStatus(cniResult, "test-net-attach-def", false, nil) + Expect(err).NotTo(HaveOccurred()) + }) + + It("create network status from cni result", func() { + Expect(networkStatus.Name).To(Equal("test-net-attach-def")) + Expect(networkStatus.Interface).To(Equal("net1")) + Expect(networkStatus.Mac).To(Equal("92:79:27:01:7c:cf")) + Expect(networkStatus.IPs).To(Equal([]string{"1.1.1.3", "2001::1"})) + }) + + It("the network status do **not** report a gateway", func() { + Expect(networkStatus.Gateway).To(BeEmpty()) + }) + + When("DeviceInfo is used as an attribute", func() { + var deviceInfo *v1.DeviceInfo + + BeforeEach(func() { + deviceInfo = &v1.DeviceInfo{ + Type: "pci", + Version: "v1.0.0", + Pci: &v1.PciDevice{ + PciAddress: "0000:01:02.2", + PfPciAddress: "0000:01:02.0", + }, + } + var err error + networkStatus, err = CreateNetworkStatus(cniResult, "test-net-attach-def", false, deviceInfo) + Expect(err).NotTo(HaveOccurred()) + }) + + It("create network status from cni result", func() { + Expect(networkStatus.DeviceInfo.Type).To(Equal("pci")) + Expect(networkStatus.DeviceInfo.Version).To(Equal("v1.0.0")) + Expect(networkStatus.DeviceInfo.Pci.PciAddress).To(Equal("0000:01:02.2")) + Expect(networkStatus.DeviceInfo.Pci.PfPciAddress).To(Equal("0000:01:02.0")) + }) + }) + + When("The CNI results features routes with default route", func() { + const gatewayIP = "10.10.10.10" + BeforeEach(func() { + cniResult.Routes = []*cnitypes.Route{ + { + Dst: net.IPNet{ + IP: net.IP{0, 0, 0, 0}, + Mask: net.CIDRMask(0, 0), + }, + GW: net.ParseIP(gatewayIP), + }, + } + var err error + networkStatus, err = CreateNetworkStatus(cniResult, "test-net-attach-def", false, nil) + Expect(err).NotTo(HaveOccurred()) + }) + + It("the network status report a gateway", func() { + Expect(networkStatus.Gateway).To(ConsistOf(gatewayIP)) + }) + + It("the network status handles multiple default routes", func() { + const secondDefaultRoute = "20.20.20.20" + + cniResult.Routes = append(cniResult.Routes, &cnitypes.Route{ + GW: net.ParseIP(secondDefaultRoute), + }) + networkStatus, err := CreateNetworkStatus(cniResult, "test-net-attach-def", false, nil) + Expect(err).NotTo(HaveOccurred()) + Expect(networkStatus.Gateway).To(ConsistOf(gatewayIP, secondDefaultRoute)) + }) + }) + + When("The CNI results features routes that are **not** the default route", func() { + BeforeEach(func() { + cniResult.Routes = []*cnitypes.Route{ + { + Dst: net.IPNet{ + IP: net.IP{10, 10, 10, 0}, + Mask: net.CIDRMask(24, 32), + }, + GW: net.IP{10, 10, 10, 10}, + }, + } + var err error + networkStatus, err = CreateNetworkStatus(cniResult, "test-net-attach-def", false, nil) + Expect(err).NotTo(HaveOccurred()) + }) + + It("the network status **should not** report a gateway", func() { + Expect(networkStatus.Gateway).To(BeEmpty()) + }) + }) }) It("parse network selection element in pod", func() {