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 }