yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/esxi/vswitch.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 "regexp" 19 20 "github.com/coredns/coredns/plugin/pkg/log" 21 "github.com/vmware/govmomi/property" 22 "github.com/vmware/govmomi/vim25/mo" 23 "github.com/vmware/govmomi/vim25/types" 24 25 "yunion.io/x/pkg/errors" 26 ) 27 28 var DVS_PROPS = []string{"name"} 29 30 type IVirtualSwitch interface { 31 FindNetworkByVlanID(vlanID int32) (IVMNetwork, error) 32 } 33 34 type SVirtualSwitch struct { 35 Host *SHost 36 HostVirtualSwitch types.HostVirtualSwitch 37 } 38 39 func (vs *SVirtualSwitch) FindNetworkByVlanID(vlanID int32) (IVMNetwork, error) { 40 vsKey := vs.HostVirtualSwitch.Key 41 pgs := vs.Host.getHostSystem().Config.Network.Portgroup 42 var networkName string 43 for i := range pgs { 44 if pgs[i].Vswitch != vsKey { 45 continue 46 } 47 if vlanEqual(pgs[i].Spec.VlanId, vlanID) { 48 networkName = pgs[i].Spec.Name 49 break 50 } 51 } 52 if len(networkName) == 0 { 53 return nil, nil 54 } 55 networks, err := vs.Host.GetNetworks() 56 if err != nil { 57 return nil, errors.Wrapf(err, "can't get networks of host %q", vs.Host.GetGlobalId()) 58 } 59 for i := range networks { 60 if networks[i].GetName() == networkName { 61 return networks[i], nil 62 } 63 } 64 return nil, nil 65 } 66 67 type SDistributedVirtualSwitch struct { 68 Host *SHost 69 DistributedVirtualSwitch mo.DistributedVirtualSwitch 70 } 71 72 func (vs *SDistributedVirtualSwitch) FindNetworkByVlanID(vlanID int32) (IVMNetwork, error) { 73 var modvpgs []mo.DistributedVirtualPortgroup 74 filter := property.Filter{} 75 filter["config.distributedVirtualSwitch"] = vs.DistributedVirtualSwitch.Self 76 err := vs.Host.manager.scanMObjectsWithFilter(vs.Host.datacenter.object.Entity().Self, DVPORTGROUP_PROPS, &modvpgs, filter) 77 if err != nil { 78 return nil, errors.Wrapf(err, "can't fetch portgroup of DistributedVirtualSwitch %q", vs.DistributedVirtualSwitch.Name) 79 } 80 dvpgs := make([]*SDistributedVirtualPortgroup, 0, len(modvpgs)) 81 for i := range modvpgs { 82 if modvpgs[i].Config.Uplink != nil && *modvpgs[i].Config.Uplink { 83 log.Infof("dvpg %s is uplink, so skip", modvpgs[i].Name) 84 continue 85 } 86 dvpgs = append(dvpgs, NewDistributedVirtualPortgroup(vs.Host.manager, &modvpgs[i], nil)) 87 } 88 for i := range dvpgs { 89 if vlanEqual(dvpgs[i].GetVlanId(), vlanID) { 90 return dvpgs[i], nil 91 } 92 } 93 return nil, nil 94 } 95 96 func vlanEqual(v1, v2 int32) bool { 97 if v1 <= 1 && v2 <= 1 { 98 return true 99 } 100 return v1 == v2 101 } 102 103 var ( 104 vsBridgeRegex = regexp.MustCompile(`^(host-\d+)/(.*)`) 105 dvsBridgeRegex = regexp.MustCompile(`^dvs-\d+$`) 106 ) 107 108 // config.distributedVirtualSwitch 109 110 func findVirtualSwitch(host *SHost, bridge string) (IVirtualSwitch, error) { 111 group := vsBridgeRegex.FindStringSubmatch(bridge) 112 oHost := host.getHostSystem() 113 if len(group) > 0 { 114 // vswitch 115 vsName := group[2] 116 for _, vs := range oHost.Config.Network.Vswitch { 117 if vs.Name != vsName { 118 continue 119 } 120 return &SVirtualSwitch{ 121 Host: host, 122 HostVirtualSwitch: vs, 123 }, nil 124 } 125 return nil, nil 126 } 127 128 // distributed vswitch 129 if !dvsBridgeRegex.MatchString(bridge) { 130 return nil, nil 131 } 132 objRef := types.ManagedObjectReference{ 133 Type: "VmwareDistributedVirtualSwitch", 134 Value: bridge, 135 } 136 var dvs mo.DistributedVirtualSwitch 137 err := host.manager.reference2Object(objRef, DVS_PROPS, &dvs) 138 if err != nil { 139 return nil, errors.Wrapf(err, "can't fetch DistributedVirtualSwitch %q", objRef.String()) 140 } 141 return &SDistributedVirtualSwitch{ 142 Host: host, 143 DistributedVirtualSwitch: dvs, 144 }, nil 145 }