yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/esxi/network.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package esxi
    16  
    17  import (
    18  	"github.com/vmware/govmomi/object"
    19  	"github.com/vmware/govmomi/vim25/mo"
    20  	"github.com/vmware/govmomi/vim25/types"
    21  
    22  	"yunion.io/x/pkg/errors"
    23  )
    24  
    25  type IVMNetwork interface {
    26  	GetId() string
    27  	GetName() string
    28  	GetVlanId() int32
    29  	GetNumPorts() int32
    30  	GetActivePorts() []string
    31  	GetType() string
    32  	ContainHost(host *SHost) bool
    33  	SetHostPortGroup(pg types.HostPortGroup)
    34  }
    35  
    36  const (
    37  	NET_TYPE_NETWORK     = "network"
    38  	NET_TYPE_DVPORTGROUP = "dvportgroup"
    39  
    40  	VLAN_MODE_NONE  = "none"
    41  	VLAN_MODE_VLAN  = "vlan"
    42  	VLAN_MODE_PVLAN = "pvlan"
    43  	VLAN_MODE_TRUNK = "trunk"
    44  )
    45  
    46  var NETWORK_PROPS = []string{"name", "parent", "host"}
    47  var DVPORTGROUP_PROPS = []string{"name", "parent", "host", "config", "key"}
    48  
    49  type SNetwork struct {
    50  	SManagedObject
    51  	HostPortGroup types.HostPortGroup
    52  }
    53  
    54  type SDistributedVirtualPortgroup struct {
    55  	SManagedObject
    56  	HostPortGroup types.HostPortGroup
    57  }
    58  
    59  func NewNetwork(manager *SESXiClient, net *mo.Network, dc *SDatacenter) *SNetwork {
    60  	return &SNetwork{SManagedObject: newManagedObject(manager, net, dc)}
    61  }
    62  
    63  func NewDistributedVirtualPortgroup(manager *SESXiClient, net *mo.DistributedVirtualPortgroup, dc *SDatacenter) *SDistributedVirtualPortgroup {
    64  	return &SDistributedVirtualPortgroup{SManagedObject: newManagedObject(manager, net, dc)}
    65  }
    66  
    67  func (net *SNetwork) getMONetwork() *mo.Network {
    68  	return net.object.(*mo.Network)
    69  }
    70  
    71  func (net *SNetwork) GetName() string {
    72  	return net.getMONetwork().Name
    73  }
    74  
    75  func (net *SNetwork) GetType() string {
    76  	return NET_TYPE_NETWORK
    77  }
    78  
    79  func (net *SNetwork) GetVlanId() int32 {
    80  	return net.HostPortGroup.Spec.VlanId
    81  }
    82  
    83  func (net *SNetwork) GetVlanMode() string {
    84  	return VLAN_MODE_NONE
    85  }
    86  
    87  func (net *SNetwork) GetNumPorts() int32 {
    88  	return -1
    89  }
    90  
    91  func (net *SNetwork) GetActivePorts() []string {
    92  	return nil
    93  }
    94  
    95  func (net *SNetwork) ContainHost(host *SHost) bool {
    96  	objs := net.getMONetwork().Host
    97  	moHost := host.getHostSystem()
    98  	for _, obj := range objs {
    99  		if obj.Value == moHost.Reference().Value {
   100  			return true
   101  		}
   102  	}
   103  	return false
   104  }
   105  
   106  func (net *SNetwork) SetHostPortGroup(pg types.HostPortGroup) {
   107  	net.HostPortGroup = pg
   108  }
   109  
   110  func (net *SDistributedVirtualPortgroup) getMODVPortgroup() *mo.DistributedVirtualPortgroup {
   111  	return net.object.(*mo.DistributedVirtualPortgroup)
   112  }
   113  
   114  func (net *SDistributedVirtualPortgroup) GetName() string {
   115  	return net.getMODVPortgroup().Name
   116  }
   117  
   118  func (net *SDistributedVirtualPortgroup) GetType() string {
   119  	return NET_TYPE_DVPORTGROUP
   120  }
   121  
   122  func (net *SDistributedVirtualPortgroup) GetVlanId() int32 {
   123  	dvpg := net.getMODVPortgroup()
   124  	switch conf := dvpg.Config.DefaultPortConfig.(type) {
   125  	case *types.VMwareDVSPortSetting:
   126  		switch vlanConf := conf.Vlan.(type) {
   127  		case *types.VmwareDistributedVirtualSwitchTrunkVlanSpec:
   128  			return -1
   129  		case *types.VmwareDistributedVirtualSwitchPvlanSpec:
   130  			return vlanConf.PvlanId
   131  		case *types.VmwareDistributedVirtualSwitchVlanIdSpec:
   132  			return vlanConf.VlanId
   133  		}
   134  	}
   135  	return -1
   136  }
   137  
   138  func (net *SDistributedVirtualPortgroup) GetVlanMode() string {
   139  	dvpg := net.getMODVPortgroup()
   140  	switch conf := dvpg.Config.DefaultPortConfig.(type) {
   141  	case *types.VMwareDVSPortSetting:
   142  		switch conf.Vlan.(type) {
   143  		case *types.VmwareDistributedVirtualSwitchTrunkVlanSpec:
   144  			return VLAN_MODE_TRUNK
   145  		case *types.VmwareDistributedVirtualSwitchPvlanSpec:
   146  			return VLAN_MODE_PVLAN
   147  		case *types.VmwareDistributedVirtualSwitchVlanIdSpec:
   148  			return VLAN_MODE_VLAN
   149  		}
   150  	}
   151  	return VLAN_MODE_NONE
   152  }
   153  
   154  func (net *SDistributedVirtualPortgroup) GetNumPorts() int32 {
   155  	dvpg := net.getMODVPortgroup()
   156  	return dvpg.Config.NumPorts
   157  }
   158  
   159  func (net *SDistributedVirtualPortgroup) GetActivePorts() []string {
   160  	dvpg := net.getMODVPortgroup()
   161  	switch conf := dvpg.Config.DefaultPortConfig.(type) {
   162  	case *types.VMwareDVSPortSetting:
   163  		return conf.UplinkTeamingPolicy.UplinkPortOrder.ActiveUplinkPort
   164  	}
   165  	return nil
   166  }
   167  
   168  func (net *SDistributedVirtualPortgroup) ContainHost(host *SHost) bool {
   169  	objs := net.getMODVPortgroup().Host
   170  	moHost := host.getHostSystem()
   171  	for _, obj := range objs {
   172  		if obj.Value == moHost.Reference().Value {
   173  			return true
   174  		}
   175  	}
   176  	return false
   177  }
   178  
   179  func (net *SDistributedVirtualPortgroup) SetHostPortGroup(pg types.HostPortGroup) {
   180  	net.HostPortGroup = pg
   181  }
   182  
   183  func (net *SDistributedVirtualPortgroup) Uplink() bool {
   184  	dvpg := net.getMODVPortgroup()
   185  	return *dvpg.Config.Uplink
   186  }
   187  
   188  func (net *SDistributedVirtualPortgroup) GetDVSUuid() (string, error) {
   189  	dvgp := net.getMODVPortgroup()
   190  	var dvs mo.DistributedVirtualSwitch
   191  	err := net.manager.reference2Object(*dvgp.Config.DistributedVirtualSwitch, []string{"uuid"}, &dvs)
   192  	if err != nil {
   193  		return "", errors.Wrap(err, "reference2Object")
   194  	}
   195  	return dvs.Uuid, nil
   196  }
   197  
   198  func (net *SDistributedVirtualPortgroup) FindPort() (*types.DistributedVirtualPort, error) {
   199  	dvgp := net.getMODVPortgroup()
   200  	odvs := object.NewDistributedVirtualSwitch(net.manager.client.Client, *dvgp.Config.DistributedVirtualSwitch)
   201  	var (
   202  		False = false
   203  		True  = true
   204  	)
   205  	criteria := types.DistributedVirtualSwitchPortCriteria{
   206  		Connected:    &False,
   207  		Inside:       &True,
   208  		PortgroupKey: []string{dvgp.Key},
   209  	}
   210  	ports, err := odvs.FetchDVPorts(net.manager.context, &criteria)
   211  	if err != nil {
   212  		return nil, errors.Wrap(err, "object.DVS.FetchDVPorts")
   213  	}
   214  	if len(ports) > 0 {
   215  		// release extra space timely
   216  		return &ports[:1][0], nil
   217  	}
   218  	return nil, nil
   219  }
   220  
   221  func (net *SDistributedVirtualPortgroup) AddHostToDVS(host *SHost) (err error) {
   222  	// get dvs
   223  	dvgp := net.getMODVPortgroup()
   224  	var s mo.DistributedVirtualSwitch
   225  	err = net.manager.reference2Object(*dvgp.Config.DistributedVirtualSwitch, []string{"config"}, &s)
   226  	if err != nil {
   227  		return errors.Wrapf(err, "fail to convert reference to object")
   228  	}
   229  	moHost := host.getHostSystem()
   230  
   231  	// check firstly
   232  	for _, host := range s.Config.GetDVSConfigInfo().Host {
   233  		if host.Config.Host.Value == moHost.Reference().Value {
   234  			// host is already a member of dvs
   235  			return nil
   236  		}
   237  	}
   238  	config := &types.DVSConfigSpec{ConfigVersion: s.Config.GetDVSConfigInfo().ConfigVersion}
   239  	backing := new(types.DistributedVirtualSwitchHostMemberPnicBacking)
   240  	pnics := moHost.Config.Network.Pnic
   241  
   242  	if len(pnics) == 0 {
   243  		return errors.Error("no pnic in this host")
   244  	}
   245  
   246  	config.Host = []types.DistributedVirtualSwitchHostMemberConfigSpec{
   247  		{
   248  			Operation: "add",
   249  			Host:      moHost.Reference(),
   250  			Backing:   backing,
   251  		},
   252  	}
   253  	dvs := object.NewDistributedVirtualSwitch(net.manager.client.Client, s.Reference())
   254  	task, err := dvs.Reconfigure(net.manager.context, config)
   255  	if err != nil {
   256  		return errors.Wrapf(err, "dvs.Reconfigure")
   257  	}
   258  	err = task.Wait(net.manager.context)
   259  	if err == nil {
   260  		return nil
   261  	}
   262  	return err
   263  }