Merge pull request #5439 from rainzm/fix/esxi_network_vlan

fix(esxi): Fix bugs when using network with vlanID
This commit is contained in:
yunion-ci-robot
2020-03-12 02:46:02 +08:00
committed by GitHub
4 changed files with 87 additions and 57 deletions
+1 -1
View File
@@ -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))
}
+55 -8
View File
@@ -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
}
}
+17 -48
View File
@@ -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
}
+14
View File
@@ -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
})
}