diff --git a/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status.go b/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status.go index 62bf35ba4..fb142fe67 100644 --- a/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status.go +++ b/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status.go @@ -143,9 +143,9 @@ func getGuestNetworkStatus(guestInfo *types.GuestInfo) *vmopv1.VirtualMachineNet } } - if len(guestInfo.Net) > 0 { - status.Interfaces = make([]vmopv1.VirtualMachineNetworkInterfaceStatus, 0, len(guestInfo.Net)) - for i := range guestInfo.Net { + for i := range guestInfo.Net { + // Skip pseudo devices. + if guestInfo.Net[i].DeviceConfigId != -1 { status.Interfaces = append(status.Interfaces, guestNicInfoToInterfaceStatus(i, &guestInfo.Net[i])) } } @@ -161,7 +161,6 @@ func guestNicInfoToInterfaceStatus(idx int, guestNicInfo *types.GuestNicInfo) vm status := vmopv1.VirtualMachineNetworkInterfaceStatus{} // TODO: What name exactly? The CRD name may be the most useful here but hard to line that up. - // BMV: DeviceConfigId will be -1 for our pseudo-y interfaces. Most likely want to just skip those devices. status.Name = fmt.Sprintf("nic-%d-%d", idx, guestNicInfo.DeviceConfigId) status.IP.MACAddr = guestNicInfo.MacAddress @@ -267,9 +266,31 @@ func convertNetIPRouteConfigInfo(routeConfig *types.NetIpRouteConfigInfo) []vmop return nil } - // TODO: Prob only want to show default routes. Will be very verbose on TKG nodes. - out := make([]vmopv1.VirtualMachineNetworkIPRouteStatus, 0, len(routeConfig.IpRoute)) + // Try to skip uninteresting routes so the Status isn't as cluttered. + // Otherwise, TKG nodes will have a lot of routes. + skipRoute := func(ipRoute types.NetIpRouteConfigInfoIpRoute) bool { + network, prefix := ipRoute.Network, ipRoute.PrefixLength + + ip := net.ParseIP(network) + if ip == nil { + return true + } + + if ip.To4() != nil { + return prefix == 32 + } + + ip6 := ip.To16() + return ip6 == nil || ip6.IsLinkLocalUnicast() || ip6.IsMulticast() + } + + out := make([]vmopv1.VirtualMachineNetworkIPRouteStatus, 0, 1) for _, ipRoute := range routeConfig.IpRoute { + + if skipRoute(ipRoute) { + continue + } + out = append(out, vmopv1.VirtualMachineNetworkIPRouteStatus{ Gateway: vmopv1.VirtualMachineNetworkIPRouteGatewayStatus{ Device: ipRoute.Gateway.Device, diff --git a/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status_test.go b/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status_test.go index 3d130cdc9..f9050ea97 100644 --- a/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status_test.go +++ b/pkg/vmprovider/providers/vsphere2/vmlifecycle/update_status_test.go @@ -7,14 +7,127 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/vmware/govmomi/object" + "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" conditions "github.com/vmware-tanzu/vm-operator/pkg/conditions2" + "github.com/vmware-tanzu/vm-operator/pkg/context" "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/providers/vsphere2/vmlifecycle" + "github.com/vmware-tanzu/vm-operator/test/builder" ) +var _ = Describe("UpdateStatus", func() { + + var ( + ctx *builder.TestContextForVCSim + err error + vmCtx context.VirtualMachineContextA2 + vcVM *object.VirtualMachine + vmMO *mo.VirtualMachine + ) + + BeforeEach(func() { + ctx = suite.NewTestContextForVCSim(builder.VCSimTestConfig{WithV1A2: true}) + + vm := builder.DummyVirtualMachineA2() + vm.Name = "update-status-test" + + vmCtx = context.VirtualMachineContextA2{ + Context: ctx, + Logger: suite.GetLogger().WithValues("vmName", vm.Name), + VM: vm, + } + + vcVM, err = ctx.Finder.VirtualMachine(ctx, "DC0_C0_RP0_VM0") + Expect(err).ToNot(HaveOccurred()) + + vmMO = &mo.VirtualMachine{} + }) + + AfterEach(func() { + ctx.AfterEach() + ctx = nil + }) + + JustBeforeEach(func() { + err = vmlifecycle.UpdateStatus(vmCtx, ctx.Client, vcVM, vmMO) + Expect(err).ToNot(HaveOccurred()) + }) + + Context("Network", func() { + + Context("Interfaces", func() { + BeforeEach(func() { + vmMO.Guest = &types.GuestInfo{ + Net: []types.GuestNicInfo{ + { + DeviceConfigId: -1, + MacAddress: "mac-1", + }, + { + DeviceConfigId: 4000, + MacAddress: "mac-4000", + }, + }, + } + }) + + It("Skips pseudo devices", func() { + network := vmCtx.VM.Status.Network + + Expect(network.Interfaces).To(HaveLen(1)) + Expect(network.Interfaces[0].IP.MACAddr).To(Equal("mac-4000")) + }) + }) + + Context("IPRoutes", func() { + BeforeEach(func() { + vmMO.Guest = &types.GuestInfo{ + IpStack: []types.GuestStackInfo{ + { + IpRouteConfig: &types.NetIpRouteConfigInfo{ + IpRoute: []types.NetIpRouteConfigInfoIpRoute{ + { + Network: "192.168.1.0", + PrefixLength: 24, + }, + { + Network: "192.168.1.100", + PrefixLength: 32, + }, + { + Network: "fe80::", + PrefixLength: 64, + }, + { + Network: "ff00::", + PrefixLength: 8, + }, + { + Network: "e9ef:6df5:eb14:42e2:5c09:9982:a9b5:8c2b", + PrefixLength: 48, + }, + }, + }, + }, + }, + } + }) + + It("Skips IPs", func() { + network := vmCtx.VM.Status.Network + + Expect(network.IPRoutes).To(HaveLen(2)) + Expect(network.IPRoutes[0].NetworkAddress).To(Equal("192.168.1.0/24")) + Expect(network.IPRoutes[1].NetworkAddress).To(Equal("e9ef:6df5:eb14:42e2:5c09:9982:a9b5:8c2b/48")) + }) + }) + }) +}) + var _ = Describe("VirtualMachineTools Status to VM Status Condition", func() { Context("markVMToolsRunningStatusCondition", func() { var (