blob: c965204c9728c112420b5280cb21c26c30c17ae2 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.vmware.mo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.cloud.utils.Pair;
import com.vmware.vim25.DVPortgroupConfigSpec;
import com.vmware.vim25.DVSConfigInfo;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.TaskInfo;
import com.vmware.vim25.VMwareDVSConfigInfo;
import com.vmware.vim25.VMwareDVSConfigSpec;
import com.vmware.vim25.VMwareDVSPvlanMapEntry;
public class DistributedVirtualSwitchMO extends BaseMO {
@SuppressWarnings("unused")
private static ConcurrentHashMap<String, List<String>> s_dvPortGroupCacheMap = null;
public DistributedVirtualSwitchMO(VmwareContext context, ManagedObjectReference morDvs) {
super(context, morDvs);
s_dvPortGroupCacheMap = new ConcurrentHashMap<String, List<String>>();
}
public DistributedVirtualSwitchMO(VmwareContext context, String morType, String morValue) {
super(context, morType, morValue);
s_dvPortGroupCacheMap = new ConcurrentHashMap<String, List<String>>();
}
public void createDVPortGroup(DVPortgroupConfigSpec dvPortGroupSpec) throws Exception {
List<DVPortgroupConfigSpec> dvPortGroupSpecArray = new ArrayList<DVPortgroupConfigSpec>();
dvPortGroupSpecArray.add(dvPortGroupSpec);
boolean dvPortGroupExists = false;
String dvSwitchInstance = _mor.getValue();
String dvPortGroupName = dvPortGroupSpec.getName();
String uniquedvPortGroupPerDvs = dvSwitchInstance + dvPortGroupName;
List<String> dvPortGroupList = null;
synchronized (uniquedvPortGroupPerDvs.intern()) {
// Looking up local cache rather than firing another API call to see if dvPortGroup exists already.
if (s_dvPortGroupCacheMap.containsKey(dvSwitchInstance)) {
dvPortGroupList = s_dvPortGroupCacheMap.get(dvSwitchInstance);
if (dvPortGroupList != null && dvPortGroupList.contains(dvPortGroupName)) {
dvPortGroupExists = true;
}
}
if (!dvPortGroupExists) {
ManagedObjectReference task = _context.getService().addDVPortgroupTask(_mor, dvPortGroupSpecArray);
if (!_context.getVimClient().waitForTask(task)) {
throw new Exception("Failed to create dvPortGroup " + dvPortGroupSpec.getName());
} else {
if (s_dvPortGroupCacheMap.containsKey(dvSwitchInstance)) {
dvPortGroupList = s_dvPortGroupCacheMap.get(dvSwitchInstance);
if (dvPortGroupList == null) {
dvPortGroupList = new ArrayList<String>();
}
dvPortGroupList.add(dvPortGroupName); //does this update map?
} else {
dvPortGroupList = new ArrayList<String>();
dvPortGroupList.add(dvPortGroupName);
s_dvPortGroupCacheMap.put(dvSwitchInstance, dvPortGroupList);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Created dvPortGroup. dvPortGroup cache is :" + s_dvPortGroupCacheMap);
}
} else if (logger.isDebugEnabled()) {
logger.debug("Detected dvPortGroup [" + dvPortGroupName + "] already present. Not attempting to create again.");
}
}
}
public void updateDvPortGroup(ManagedObjectReference dvPortGroupMor, DVPortgroupConfigSpec dvPortGroupSpec) throws Exception {
synchronized (dvPortGroupMor.getValue().intern()) {
ManagedObjectReference task = _context.getService().reconfigureDVPortgroupTask(dvPortGroupMor, dvPortGroupSpec);
if (!_context.getVimClient().waitForTask(task)) {
throw new Exception("Failed to update dvPortGroup " + dvPortGroupMor.getValue());
}
}
}
public void updateVMWareDVSwitch(ManagedObjectReference dvSwitchMor, VMwareDVSConfigSpec dvsSpec) throws Exception {
_context.getService().reconfigureDvsTask(dvSwitchMor, dvsSpec);
}
public TaskInfo updateVMWareDVSwitchGetTask(ManagedObjectReference dvSwitchMor, VMwareDVSConfigSpec dvsSpec) throws Exception {
ManagedObjectReference task = _context.getService().reconfigureDvsTask(dvSwitchMor, dvsSpec);
TaskInfo info = (TaskInfo)(_context.getVimClient().getDynamicProperty(task, "info"));
_context.getVimClient().waitForTask(task);
return info;
}
public String getDVSConfigVersion(ManagedObjectReference dvSwitchMor) throws Exception {
assert (dvSwitchMor != null);
DVSConfigInfo dvsConfigInfo = (DVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config");
return dvsConfigInfo.getConfigVersion();
}
public String getDVSProductVersion(ManagedObjectReference dvSwitchMor) throws Exception {
assert (dvSwitchMor != null);
DVSConfigInfo dvsConfigInfo = (DVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config");
if (dvsConfigInfo != null && dvsConfigInfo.getProductInfo() != null) {
return dvsConfigInfo.getProductInfo().getVersion();
}
return null;
}
public Map<Integer, HypervisorHostHelper.PvlanType> retrieveVlanPvlan(int vlanid, int secondaryvlanid, ManagedObjectReference dvSwitchMor) throws Exception {
assert (dvSwitchMor != null);
Map<Integer, HypervisorHostHelper.PvlanType> result = new HashMap<Integer, HypervisorHostHelper.PvlanType>();
VMwareDVSConfigInfo configinfo = (VMwareDVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config");
List<VMwareDVSPvlanMapEntry> pvlanconfig = null;
pvlanconfig = configinfo.getPvlanConfig();
if (null == pvlanconfig || 0 == pvlanconfig.size()) {
return result;
}
// Iterate through the pvlanMapList and check if the specified vlan id and pvlan id exist. If they do, set the fields in result accordingly.
for (VMwareDVSPvlanMapEntry mapEntry : pvlanconfig) {
int entryVlanid = mapEntry.getPrimaryVlanId();
int entryPvlanid = mapEntry.getSecondaryVlanId();
if (entryVlanid == entryPvlanid) {
// promiscuous
if (vlanid == entryVlanid) {
// pvlan type will always be promiscuous in this case.
result.put(vlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType()));
} else if ((vlanid != secondaryvlanid) && secondaryvlanid == entryVlanid) {
result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType()));
}
} else {
if (vlanid == entryVlanid) {
// vlan id in entry is promiscuous
result.put(vlanid, HypervisorHostHelper.PvlanType.promiscuous);
} else if (vlanid == entryPvlanid) {
result.put(vlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType()));
}
if ((vlanid != secondaryvlanid) && secondaryvlanid == entryVlanid) {
//promiscuous
result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.promiscuous);
} else if (secondaryvlanid == entryPvlanid) {
result.put(secondaryvlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType()));
}
}
// If we already know that the vlanid is being used as a non primary vlan, it's futile to
// go over the entire list. Return.
if (result.containsKey(vlanid) && result.get(vlanid) != HypervisorHostHelper.PvlanType.promiscuous)
return result;
// If we've already found both vlanid and pvlanid, we have enough info to make a decision. Return.
if (result.containsKey(vlanid) && result.containsKey(secondaryvlanid))
return result;
}
return result;
}
public Pair<Integer, HypervisorHostHelper.PvlanType> retrieveVlanFromPvlan(int pvlanid, ManagedObjectReference dvSwitchMor) throws Exception {
assert (dvSwitchMor != null);
Pair<Integer, HypervisorHostHelper.PvlanType> result = null;
VMwareDVSConfigInfo configinfo = (VMwareDVSConfigInfo)_context.getVimClient().getDynamicProperty(dvSwitchMor, "config");
List<VMwareDVSPvlanMapEntry> pvlanConfig = null;
pvlanConfig = configinfo.getPvlanConfig();
if (null == pvlanConfig || 0 == pvlanConfig.size()) {
return result;
}
// Iterate through the pvlanMapList and check if the specified pvlan id exist. If it does, set the fields in result accordingly.
for (VMwareDVSPvlanMapEntry mapEntry : pvlanConfig) {
int entryVlanid = mapEntry.getPrimaryVlanId();
int entryPvlanid = mapEntry.getSecondaryVlanId();
if (pvlanid == entryPvlanid) {
result = new Pair<>(entryVlanid, HypervisorHostHelper.PvlanType.valueOf(mapEntry.getPvlanType()));
break;
}
}
return result;
}
}