From 7db5ae4d16e5ab12f6ab604bb5d785197c96a62c Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 10 Mar 2020 22:24:08 +0800 Subject: [PATCH] fix(esxi): Fix bugs when using network with vlanID --- pkg/multicloud/esxi/devtools.go | 2 +- pkg/multicloud/esxi/host.go | 63 ++++++++++++++++++++++++++---- pkg/multicloud/esxi/network.go | 65 ++++++++----------------------- pkg/multicloud/esxi/shell/host.go | 14 +++++++ 4 files changed, 87 insertions(+), 57 deletions(-) diff --git a/pkg/multicloud/esxi/devtools.go b/pkg/multicloud/esxi/devtools.go index bb296af1ea..f70fcd54b4 100644 --- a/pkg/multicloud/esxi/devtools.go +++ b/pkg/multicloud/esxi/devtools.go @@ -132,7 +132,7 @@ func NewVNICDev(host *SHost, mac, driver string, vlanId int32, key, ctlKey, inde if err != nil { return nil, errors.Wrap(err, "SHost.FindNetworkByVlanID") } - if inet == nil { + if inet == nil || reflect.ValueOf(inet).IsNil() { return nil, errors.Error(fmt.Sprintf("VLAN %d not found", vlanId)) } diff --git a/pkg/multicloud/esxi/host.go b/pkg/multicloud/esxi/host.go index e2635dece3..9a25301433 100644 --- a/pkg/multicloud/esxi/host.go +++ b/pkg/multicloud/esxi/host.go @@ -1199,20 +1199,33 @@ func (host *SHost) FileUrlPathToDsPath(path string) (string, error) { } func (host *SHost) FindNetworkByVlanID(vlanID int32) (IVMNetwork, error) { - if vlanID > 1 && vlanID < 4095 { - return host.findVlanDVPG(int32(vlanID)) + if vlanID >= 1 && vlanID < 4095 { + net, err := host.findBasicNetwork(vlanID) + if err != nil { + return nil, errors.Wrap(err, "findBasicNetwork error") + } + if net != nil { + return net, nil + } + + // no found in basic network + dvpg, err := host.findVlanDVPG(vlanID) + if err != nil { + return nil, errors.Wrap(err, "findVlanDVPG") + } + return dvpg, nil } - n, err := host.findNovlanDVPG() + n, err := host.findBasicNetwork(vlanID) if err != nil { - return nil, err + return nil, errors.Wrap(err, "find Basic network") } if n != nil { return n, err } - return host.findBasicNetwork() + return host.findNovlanDVPG() } -func (host *SHost) findBasicNetwork() (*SNetwork, error) { +func (host *SHost) findBasicNetwork(vlanID int32) (*SNetwork, error) { nets, err := host.GetNetwork() if err != nil { return nil, err @@ -1220,7 +1233,15 @@ func (host *SHost) findBasicNetwork() (*SNetwork, error) { if len(nets) == 0 { return nil, nil } - return &nets[0], nil + if vlanID < 1 || vlanID >= 4095 { + return &nets[0], nil + } + for i := range nets { + if nets[i].GetVlanId() == vlanID { + return &nets[i], nil + } + } + return nil, nil } func (host *SHost) GetNetwork() ([]SNetwork, error) { @@ -1237,6 +1258,23 @@ func (host *SHost) GetNetwork() ([]SNetwork, error) { for i := range moNets { nets[i] = *NewNetwork(host.manager, &moNets[i], host.datacenter) } + + // network map + netMap := make(map[string]*SNetwork) + for i := range nets { + netMap[nets[i].GetName()] = &nets[i] + } + + // fetch all portgroup + portgroups := host.getHostSystem().Config.Network.Portgroup + for _, pg := range portgroups { + net, ok := netMap[pg.Spec.Name] + if !ok { + log.Infof("SNetwork corresponding to the portgroup whose name is %s could not be found", pg.Spec.Name) + continue + } + net.HostPortGroup = pg + } host.networks = nets return host.networks, nil } @@ -1266,11 +1304,20 @@ func (host *SHost) findVlanDVPG(vlanId int32) (*SDistributedVirtualPortgroup, er } for _, net := range nets { dvpg, ok := net.(*SDistributedVirtualPortgroup) - if !ok || !dvpg.ContainHost(host) || len(dvpg.GetActivePorts()) == 0 { + if !ok || len(dvpg.GetActivePorts()) == 0 { continue } nvlan := dvpg.GetVlanId() if nvlan == vlanId { + if dvpg.ContainHost(host) { + return dvpg, nil + } + // add host to dvg + log.Debugf("Find dvpg with correct vlan but it didn't contain this host") + err := dvpg.AddHostToDVS(host) + if err != nil { + return nil, errors.Wrapf(err, "dvpg %s add host to dvs error", dvpg.GetName()) + } return dvpg, nil } } diff --git a/pkg/multicloud/esxi/network.go b/pkg/multicloud/esxi/network.go index 5a6d04c739..966ad27497 100644 --- a/pkg/multicloud/esxi/network.go +++ b/pkg/multicloud/esxi/network.go @@ -15,8 +15,6 @@ package esxi import ( - "strings" - "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" @@ -49,6 +47,7 @@ var DVPORTGROUP_PROPS = []string{"name", "parent", "summary", "host", "vm", "con type SNetwork struct { SManagedObject + HostPortGroup types.HostPortGroup } type SDistributedVirtualPortgroup struct { @@ -76,7 +75,7 @@ func (net *SNetwork) GetType() string { } func (net *SNetwork) GetVlanId() int32 { - return -1 + return net.HostPortGroup.Spec.VlanId } func (net *SNetwork) GetVlanMode() string { @@ -224,51 +223,21 @@ func (net *SDistributedVirtualPortgroup) AddHostToDVS(host *SHost) (err error) { return errors.Error("no pnic in this host") } - // try one by one - // have some bug - for i := 0; i < len(pnics); i++ { - backing.PnicSpec = []types.DistributedVirtualSwitchHostMemberPnicSpec{ - { - PnicDevice: pnics[i].Device, - }, - } - config.Host = []types.DistributedVirtualSwitchHostMemberConfigSpec{ - { - Operation: "add", - Host: moHost.Reference(), - Backing: backing, - }, - } - var task *object.Task - dvs := object.NewDistributedVirtualSwitch(net.manager.client.Client, s.Reference()) - task, err = dvs.Reconfigure(net.manager.context, config) - if err != nil { - return errors.Wrapf(err, "dvs.Reconfigure") - } - err = task.Wait(net.manager.context) - if err == nil { - return nil - } - if strings.Contains(err.Error(), "concurrent modification") { - i -= 1 - } + config.Host = []types.DistributedVirtualSwitchHostMemberConfigSpec{ + { + Operation: "add", + Host: moHost.Reference(), + Backing: backing, + }, + } + dvs := object.NewDistributedVirtualSwitch(net.manager.client.Client, s.Reference()) + task, err := dvs.Reconfigure(net.manager.context, config) + if err != nil { + return errors.Wrapf(err, "dvs.Reconfigure") + } + err = task.Wait(net.manager.context) + if err == nil { + return nil } return err } - -func FindVlanDistVswitch(nets []IVMNetwork, vlanID int32) IVMNetwork { - for _, net := range nets { - _, ok := net.(*SDistributedVirtualPortgroup) - if !ok { - continue - } - if len(net.GetActivePorts()) == 0 { - continue - } - nvlan := net.GetVlanId() - if nvlan == vlanID { - return net - } - } - return nil -} diff --git a/pkg/multicloud/esxi/shell/host.go b/pkg/multicloud/esxi/shell/host.go index b2a81eade8..fccb80bdc6 100644 --- a/pkg/multicloud/esxi/shell/host.go +++ b/pkg/multicloud/esxi/shell/host.go @@ -75,4 +75,18 @@ func init() { printList(nics, nil) return nil }) + + shellutils.R(&HostShowOptions{}, "host-network", "Show all network of a given host", func(cli *esxi.SESXiClient, + args *HostShowOptions) error { + host, err := cli.FindHostByIp(args.IP) + if err != nil { + return err + } + networks, err := host.GetNetwork() + if err != nil { + return err + } + printList(networks, nil) + return nil + }) }