diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 5d7edce12ef..d7c237d3b2d 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -29,10 +29,13 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; +import org.apache.cloudstack.api.ApiConstants; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.alert.AlertManager; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter.NetworkType; @@ -41,6 +44,7 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.DiscoveredWithErrorException; import com.cloud.exception.DiscoveryException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; @@ -49,10 +53,14 @@ import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.hypervisor.vmware.manager.VmwareManager; import com.cloud.hypervisor.vmware.mo.ClusterMO; import com.cloud.hypervisor.vmware.mo.HostMO; +import com.cloud.hypervisor.vmware.mo.VirtualSwitchType; import com.cloud.hypervisor.vmware.resource.VmwareContextFactory; import com.cloud.hypervisor.vmware.resource.VmwareResource; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.VmwareTrafficLabel; import com.cloud.network.dao.CiscoNexusVSMDeviceDao; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; @@ -60,9 +68,9 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.utils.UriUtils; @@ -98,6 +106,9 @@ public class VmwareServerDiscoverer extends DiscovererBase implements NetworkModel _netmgr; @Inject HypervisorCapabilitiesDao _hvCapabilitiesDao; + protected Map _urlParams; + protected boolean useDVS = false; + protected boolean nexusDVS = false; public VmwareServerDiscoverer() { s_logger.info("VmwareServerDiscoverer is constructed"); @@ -137,13 +148,85 @@ public class VmwareServerDiscoverer extends DiscovererBase implements String publicTrafficLabel = null; String guestTrafficLabel = null; Map vsmCredentials = null; + + VirtualSwitchType defaultVirtualSwitchType = VirtualSwitchType.StandardVirtualSwitch; + + String paramGuestVswitchType = null; + String paramGuestVswitchName = null; + String paramPublicVswitchType = null; + String paramPublicVswitchName = null; + + VmwareTrafficLabel guestTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Guest); + VmwareTrafficLabel publicTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Public); + Map clusterDetails = _clusterDetailsDao.findDetails(clusterId); + _readGlobalConfigParameters(); + + // Set default physical network end points for public and guest traffic + // Private traffic will be only on standard vSwitch for now. See below TODO. + if (useDVS) { + // Parse url parameters for type of vswitch and name of vswitch specified at cluster level + paramGuestVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC); + paramGuestVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC); + paramPublicVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC); + paramPublicVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC); + defaultVirtualSwitchType = getDefaultVirtualSwitchType(nexusDVS); + } + // Get zone wide traffic labels for Guest traffic and Public traffic + guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware); + publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware); + // Process traffic label information provided at zone level and cluster level + guestTrafficLabelObj = getTrafficInfo(TrafficType.Guest, guestTrafficLabel, defaultVirtualSwitchType, paramGuestVswitchType, paramGuestVswitchName, clusterId); + publicTrafficLabelObj = getTrafficInfo(TrafficType.Public, publicTrafficLabel, defaultVirtualSwitchType, paramPublicVswitchType, paramPublicVswitchName, clusterId); + + // Zone level vSwitch Type depends on zone level traffic labels + // + // User can override Zone wide vswitch type (for public and guest) by providing following optional parameters in addClusterCmd + // param "guestvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs + // param "publicvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs + // + // Format of label is ,, + // If a field OR is not present leave it empty. + // Ex: 1) vswitch0 + // 2) dvswitch0,200,vmwaredvs + // 3) nexusepp0,300,nexusdvs + // 4) vswitch1,400,vmwaresvs + // 5) vswitch0 + // default vswitchtype is 'vmwaresvs'. + // 'vmwaresvs' is for vmware standard vswitch + // 'vmwaredvs' is for vmware distributed virtual switch + // 'nexusdvs' is for cisco nexus distributed virtual switch + + // Configuration Check: A physical network cannot be shared by different types of virtual switches. + // + // Check if different vswitch types are chosen for same physical network + // 1. Get physical network for guest traffic - multiple networks + // 2. Get physical network for public traffic - single network + // See if 2 is in 1 + // if no - pass + // if yes - compare publicTrafficLabelObj.getVirtualSwitchType() == guestTrafficLabelObj.getVirtualSwitchType() + // true - pass + // false - throw exception - fail cluster add operation + List pNetworkListGuestTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Guest); + List pNetworkListPublicTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Public); + // Public network would be on single physical network hence getting first object of the list would suffice. + PhysicalNetwork pNetworkPublic = pNetworkListPublicTraffic.get(0); + if (pNetworkListGuestTraffic.contains(pNetworkPublic)) { + if (publicTrafficLabelObj.getVirtualSwitchType() != guestTrafficLabelObj.getVirtualSwitchType()) { + String msg = "Both public traffic and guest traffic is over same physical network " + pNetworkPublic + + ". And virtual switch type chosen for each traffic is different" + + ". A physical network cannot be shared by different types of virtual switches."; + s_logger.error(msg); + throw new InvalidParameterValueException(msg); + } + } + privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware); if (privateTrafficLabel != null) { s_logger.info("Detected private network label : " + privateTrafficLabel); } - - if (_vmwareMgr.getNexusVSwitchGlobalParameter()) { + + if (nexusDVS) { DataCenterVO zone = _dcDao.findById(dcId); NetworkType zoneType = zone.getNetworkType(); if (zoneType != NetworkType.Basic) { @@ -168,7 +251,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements context.registerStockObject("privateTrafficLabel", privateTrafficLabel); - if (_vmwareMgr.getNexusVSwitchGlobalParameter()) { + if (nexusDVS) { if (vsmCredentials != null) { s_logger.info("Stocking credentials of Nexus VSM"); context.registerStockObject("vsmcredentials", @@ -190,8 +273,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements } ManagedObjectReference morCluster = null; - Map clusterDetails = _clusterDetailsDao - .findDetails(clusterId); + clusterDetails = _clusterDetailsDao.findDetails(clusterId); if (clusterDetails.get("url") != null) { URI uriFromCluster = new URI( UriUtils.encodeURIComponent(clusterDetails.get("url"))); @@ -247,13 +329,8 @@ public class VmwareServerDiscoverer extends DiscovererBase implements params.put("private.network.vswitch.name", privateTrafficLabel); } - if (publicTrafficLabel != null) { - params.put("public.network.vswitch.name", - publicTrafficLabel); - } - if (guestTrafficLabel != null) { - params.put("guest.network.vswitch.name", guestTrafficLabel); - } + params.put("guestTrafficInfo", guestTrafficLabelObj); + params.put("publicTrafficInfo", publicTrafficLabelObj); VmwareResource resource = new VmwareResource(); try { @@ -415,4 +492,153 @@ public class VmwareServerDiscoverer extends DiscovererBase implements .getSimpleName()); return super.stop(); } + + private VmwareTrafficLabel getTrafficInfo(TrafficType trafficType, String zoneWideTrafficLabel, VirtualSwitchType defaultVirtualSwitchType, String vSwitchType, String vSwitchName, Long clusterId) { + VmwareTrafficLabel trafficLabelObj = null; + Map clusterDetails = null; + try { + trafficLabelObj = new VmwareTrafficLabel(zoneWideTrafficLabel, trafficType, defaultVirtualSwitchType); + } catch (InvalidParameterValueException e) { + s_logger.error("Failed to recognize virtual switch type specified for " + trafficType + + " traffic due to " + e.getMessage()); + throw e; + } + + if (defaultVirtualSwitchType.equals(VirtualSwitchType.StandardVirtualSwitch)|| (vSwitchType == null && vSwitchName == null)) { + // Case of no cluster level override configuration defined. + // Depend only on zone wide traffic label + // If global param for dvSwitch is false return default traffic info object with vmware standard vswitch + return trafficLabelObj; + } else { + // Need to persist cluster level override configuration to db + clusterDetails = _clusterDetailsDao.findDetails(clusterId); + } + + if (vSwitchName != null) { + trafficLabelObj.setVirtualSwitchName(vSwitchName); + if (trafficType == TrafficType.Guest) { + clusterDetails.put(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC, vSwitchName); + } else { + clusterDetails.put(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC, vSwitchName); + } + } + + if (vSwitchType != null) { + validateVswitchType(vSwitchType); + trafficLabelObj.setVirtualSwitchType(VirtualSwitchType.getType(vSwitchType)); + if (trafficType == TrafficType.Guest) { + clusterDetails.put(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC, vSwitchType); + } else { + clusterDetails.put(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC, vSwitchType); + } + } + + // Save cluster level override configuration to cluster details + _clusterDetailsDao.persist(clusterId, clusterDetails); + + return trafficLabelObj; + } + + private VmwareTrafficLabel getTrafficInfo(TrafficType trafficType, String zoneWideTrafficLabel, Map clusterDetails, VirtualSwitchType defVirtualSwitchType) { + VmwareTrafficLabel trafficLabelObj = null; + try { + trafficLabelObj = new VmwareTrafficLabel(zoneWideTrafficLabel, trafficType, defVirtualSwitchType); + } catch (InvalidParameterValueException e) { + s_logger.error("Failed to recognize virtual switch type specified for " + trafficType + + " traffic due to " + e.getMessage()); + throw e; + } + + if(defVirtualSwitchType.equals(VirtualSwitchType.StandardVirtualSwitch)) { + return trafficLabelObj; + } + + if (trafficType == TrafficType.Guest) { + if(clusterDetails.containsKey(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC)) { + trafficLabelObj.setVirtualSwitchName(clusterDetails.get(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC)); + } + if(clusterDetails.containsKey(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC)) { + trafficLabelObj.setVirtualSwitchType(VirtualSwitchType.getType(clusterDetails.get(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC))); + } + } else if (trafficType == TrafficType.Public) { + if(clusterDetails.containsKey(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC)) { + trafficLabelObj.setVirtualSwitchName(clusterDetails.get(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC)); + } + if(clusterDetails.containsKey(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC)) { + trafficLabelObj.setVirtualSwitchType(VirtualSwitchType.getType(clusterDetails.get(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC))); + } + } + + return trafficLabelObj; + } + + private void _readGlobalConfigParameters() { + String value; + if (_configDao != null) { + value = _configDao.getValue(Config.VmwareUseDVSwitch.key()); + useDVS = Boolean.parseBoolean(value); + value = _configDao.getValue(Config.VmwareUseNexusVSwitch.key()); + nexusDVS = Boolean.parseBoolean(value); + } + } + + @Override + protected HashMap buildConfigParams(HostVO host) { + HashMap params = super.buildConfigParams(host); + + Map clusterDetails = _clusterDetailsDao.findDetails(host.getClusterId()); + // Get zone wide traffic labels from guest traffic and public traffic + String guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(host.getDataCenterId(), HypervisorType.VMware); + String publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(host.getDataCenterId(), HypervisorType.VMware); + _readGlobalConfigParameters(); + VirtualSwitchType defaultVirtualSwitchType = getDefaultVirtualSwitchType(nexusDVS); + + params.put("guestTrafficInfo", getTrafficInfo(TrafficType.Guest, guestTrafficLabel, clusterDetails, defaultVirtualSwitchType)); + params.put("publicTrafficInfo", getTrafficInfo(TrafficType.Public, publicTrafficLabel, clusterDetails, defaultVirtualSwitchType)); + + return params; + } + + private VirtualSwitchType getDefaultVirtualSwitchType(boolean nexusDVS) { + return nexusDVS ? VirtualSwitchType.NexusDistributedVirtualSwitch : VirtualSwitchType.VMwareDistributedVirtualSwitch; + } + + @Override + public ServerResource reloadResource(HostVO host) { + String resourceName = host.getResource(); + ServerResource resource = getResource(resourceName); + + if (resource != null) { + _hostDao.loadDetails(host); + + HashMap params = buildConfigParams(host); + try { + resource.configure(host.getName(), params); + } catch (ConfigurationException e) { + s_logger.warn("Unable to configure resource due to " + e.getMessage()); + return null; + } + if (!resource.start()) { + s_logger.warn("Unable to start the resource"); + return null; + } + } + return resource; + } + + private void validateVswitchType(String inputVswitchType) { + VirtualSwitchType vSwitchType = VirtualSwitchType.getType(inputVswitchType); + if (vSwitchType == VirtualSwitchType.None) { + s_logger.error("Unable to resolve " + inputVswitchType + " to a valid virtual switch type in VMware environment."); + throw new InvalidParameterValueException("Invalid virtual switch type : " + inputVswitchType); + } + } + + @Override + public void putParam(Map params) { + if (_urlParams == null) { + _urlParams = new HashMap(); + } + _urlParams.putAll(params); + } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 36fa0f338b1..fb6d3d6667f 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -59,17 +59,11 @@ public interface VmwareManager { boolean beginExclusiveOperation(int timeOutSeconds); void endExclusiveOperation(); - boolean getNexusVSwitchGlobalParameter(); - boolean getFullCloneFlag(); Map getNexusVSMCredentialsByClusterId(Long clusterId); String getPrivateVSwitchName(long dcId, HypervisorType hypervisorType); - - String getPublicVSwitchName(long dcId, HypervisorType hypervisorType); - - String getGuestVSwitchName(long dcId, HypervisorType hypervisorType); public String getRootDiskController(); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index a0d9943b535..2cf1248c12a 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -126,10 +126,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw String _mountParent; StorageLayer _storage; + String _privateNetworkVSwitchName = "vSwitch0"; - String _privateNetworkVSwitchName; - String _publicNetworkVSwitchName; - String _guestNetworkVSwitchName; + int _portsPerDvPortGroup = 256; boolean _nexusVSwitchActive; boolean _fullCloneFlag; String _serviceConsoleName; @@ -195,13 +194,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw _storage = new JavaStorageLayer(); _storage.configure("StorageLayer", params); } - value = _configDao.getValue(Config.VmwareUseNexusVSwitch.key()); - if(value == null) { - _nexusVSwitchActive = false; - } - else { - _nexusVSwitchActive = Boolean.parseBoolean(value); - } value = _configDao.getValue(Config.VmwareCreateFullClone.key()); if (value == null) { @@ -210,36 +202,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw _fullCloneFlag = Boolean.parseBoolean(value); } - _privateNetworkVSwitchName = _configDao.getValue(Config.VmwarePrivateNetworkVSwitch.key()); - - if (_privateNetworkVSwitchName == null) { - if (_nexusVSwitchActive) { - _privateNetworkVSwitchName = "privateEthernetPortProfile"; - } else { - _privateNetworkVSwitchName = "vSwitch0"; - } - } - - _publicNetworkVSwitchName = _configDao.getValue(Config.VmwarePublicNetworkVSwitch.key()); - - if (_publicNetworkVSwitchName == null) { - if (_nexusVSwitchActive) { - _publicNetworkVSwitchName = "publicEthernetPortProfile"; - } else { - _publicNetworkVSwitchName = "vSwitch0"; - } - } - - _guestNetworkVSwitchName = _configDao.getValue(Config.VmwareGuestNetworkVSwitch.key()); - - if (_guestNetworkVSwitchName == null) { - if (_nexusVSwitchActive) { - _guestNetworkVSwitchName = "guestEthernetPortProfile"; - } else { - _guestNetworkVSwitchName = "vSwitch0"; - } - } - _serviceConsoleName = _configDao.getValue(Config.VmwareServiceConsole.key()); if(_serviceConsoleName == null) { _serviceConsoleName = "Service Console"; @@ -318,11 +280,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return true; } - @Override - public boolean getNexusVSwitchGlobalParameter() { - return _nexusVSwitchActive; - } - @Override public boolean getFullCloneFlag() { return _fullCloneFlag; @@ -338,15 +295,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw return _netMgr.getDefaultManagementTrafficLabel(dcId, hypervisorType); } - @Override - public String getPublicVSwitchName(long dcId, HypervisorType hypervisorType) { - return _netMgr.getDefaultPublicTrafficLabel(dcId, hypervisorType); - } - - @Override - public String getGuestVSwitchName(long dcId, HypervisorType hypervisorType) { - return _netMgr.getDefaultGuestTrafficLabel(dcId, hypervisorType); - } private void prepareHost(HostMO hostMo, String privateTrafficLabel) throws Exception { // For ESX host, we need to enable host firewall to allow VNC access @@ -368,12 +316,8 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw } s_logger.info("Preparing network on host " + hostMo.getContext().toString() + " for " + privateTrafficLabel); - if(!_nexusVSwitchActive) { - HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false); - } - else { - HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000); - } + HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", hostMo, vlanId, null, null, 180000, false); + } @Override @@ -504,10 +448,6 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public void setupResourceStartupParams(Map params) { - params.put("private.network.vswitch.name", _privateNetworkVSwitchName); - params.put("public.network.vswitch.name", _publicNetworkVSwitchName); - params.put("guest.network.vswitch.name", _guestNetworkVSwitchName); - params.put("vmware.use.nexus.vswitch", _nexusVSwitchActive); params.put("vmware.create.full.clone", _fullCloneFlag); params.put("service.console.name", _serviceConsoleName); params.put("management.portgroup.name", _managemetPortGroupName); @@ -515,6 +455,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw params.put("vmware.reserve.mem", _reserveMem); params.put("vmware.root.disk.controller", _rootDiskController); params.put("vmware.recycle.hung.wokervm", _recycleHungWorker); + params.put("ports.per.dvportgroup", _portsPerDvPortGroup); } @Override diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 4839b35b91e..3c008ef98d5 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -200,6 +200,8 @@ import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.VmwareTrafficLabel; import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.serializer.GsonHelper; @@ -286,10 +288,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected String _vCenterAddress; protected String _privateNetworkVSwitchName; - protected String _publicNetworkVSwitchName; - protected String _guestNetworkVSwitchName; - protected VirtualSwitchType _vSwitchType = VirtualSwitchType.StandardVirtualSwitch; - protected boolean _nexusVSwitch = false; + protected VmwareTrafficLabel _guestTrafficInfo = new VmwareTrafficLabel(TrafficType.Guest); + protected VmwareTrafficLabel _publicTrafficInfo = new VmwareTrafficLabel(TrafficType.Public); + protected int _portsPerDvPortGroup; protected boolean _fullCloneFlag = false; protected boolean _reserveCpu = false; @@ -1319,7 +1320,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa NicTO nicTo = cmd.getNic(); VirtualDevice nic; Pair networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo); - if (mgr.getNexusVSwitchGlobalParameter()) { + if (VmwareHelper.isDvPortGroup(networkInfo.first())) { String dvSwitchUuid; ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); @@ -1550,13 +1551,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { // TODO : probably need to set traffic shaping Pair networkInfo = null; - - if (!_nexusVSwitch) { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + VirtualSwitchType vSwitchType = VirtualSwitchType.StandardVirtualSwitch; + if (_publicTrafficInfo != null) { + vSwitchType = _publicTrafficInfo.getVirtualSwitchType(); + } + if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) { + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicTrafficInfo.getVirtualSwitchName(), "cloud.public", vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); } else { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", - vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout); + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicTrafficInfo.getVirtualSwitchName(), "cloud.public", + vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, vSwitchType, _portsPerDvPortGroup); } int nicIndex = allocPublicNicIndex(vmMo); @@ -1566,7 +1570,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VirtualEthernetCard device = (VirtualEthernetCard) nicDevices[nicIndex]; - if (!_nexusVSwitch) { + if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) { VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); nicBacking.setDeviceName(networkInfo.second()); nicBacking.setNetwork(networkInfo.first()); @@ -2265,7 +2269,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo)); Pair networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo); - if (mgr.getNexusVSwitchGlobalParameter()) { + if (VmwareHelper.isDvPortGroup(networkInfo.first())) { String dvSwitchUuid; ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); @@ -2464,21 +2468,36 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } private Pair prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo) throws Exception { + Pair switchName; + TrafficType trafficType; + VirtualSwitchType switchType; + + switchName = getTargetSwitch(nicTo); + trafficType = nicTo.getType(); + // Get switch type from resource property which is dictated by cluster property + // If a virtual switch type is specified while adding cluster that will be used. + // Else If virtual switch type is specified in physical traffic label that will be used + // Else use standard vSwitch + switchType = VirtualSwitchType.StandardVirtualSwitch; + if (trafficType == TrafficType.Guest && _guestTrafficInfo != null) { + switchType = _guestTrafficInfo.getVirtualSwitchType(); + } else if (trafficType == TrafficType.Public && _publicTrafficInfo != null) { + switchType = _publicTrafficInfo.getVirtualSwitchType(); + } - Pair switchName = getTargetSwitch(nicTo); String namePrefix = getNetworkNamePrefix(nicTo); Pair networkInfo = null; - s_logger.info("Prepare network on vSwitch: " + switchName + " with name prefix: " + namePrefix); + s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix); - if(!_nexusVSwitch) { - networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()), - nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, + if (VirtualSwitchType.StandardVirtualSwitch == switchType) { + networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()), + nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, !namePrefix.startsWith("cloud.private")); } else { networkInfo = HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, getVlanInfo(nicTo, switchName.second()), - nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout); + nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType, _portsPerDvPortGroup); } return networkInfo; @@ -2488,8 +2507,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa private Pair getTargetSwitch(NicTO nicTo) throws Exception { if(nicTo.getName() != null && !nicTo.getName().isEmpty()) { String[] tokens = nicTo.getName().split(","); - - if(tokens.length == 2) { + // Format of network traffic label is ,, + // If all 3 fields are mentioned then number of tokens would be 3. + // If only , are mentioned then number of tokens would be 2. + if(tokens.length == 2 || tokens.length == 3) { return new Pair(tokens[0], tokens[1]); } else { return new Pair(nicTo.getName(), Vlan.UNTAGGED); @@ -2497,11 +2518,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } if (nicTo.getType() == Networks.TrafficType.Guest) { - return new Pair(this._guestNetworkVSwitchName, Vlan.UNTAGGED); + return new Pair(this._guestTrafficInfo.getVirtualSwitchName(), Vlan.UNTAGGED); } else if (nicTo.getType() == Networks.TrafficType.Control || nicTo.getType() == Networks.TrafficType.Management) { return new Pair(this._privateNetworkVSwitchName, Vlan.UNTAGGED); } else if (nicTo.getType() == Networks.TrafficType.Public) { - return new Pair(this._publicNetworkVSwitchName, Vlan.UNTAGGED); + return new Pair(this._publicTrafficInfo.getVirtualSwitchName(), Vlan.UNTAGGED); } else if (nicTo.getType() == Networks.TrafficType.Storage) { return new Pair(this._privateNetworkVSwitchName, Vlan.UNTAGGED); } else if (nicTo.getType() == Networks.TrafficType.Vpn) { @@ -4542,7 +4563,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if(!"untagged".equalsIgnoreCase(tokens[2])) vlanId = tokens[2]; - HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), "cloud.public", hostMo, vlanId, networkRateMbps, null, this._ops_timeout, false); } else { s_logger.info("Skip suspecious cloud network " + networkName); @@ -4559,7 +4580,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if(!"untagged".equalsIgnoreCase(tokens[2])) vlanId = tokens[2]; - HypervisorHostHelper.prepareNetwork(this._guestNetworkVSwitchName, "cloud.guest", + HypervisorHostHelper.prepareNetwork(_guestTrafficInfo.getVirtualSwitchName(), "cloud.guest", hostMo, vlanId, networkRateMbps, null, this._ops_timeout, false); } else { s_logger.info("Skip suspecious cloud network " + networkName); @@ -4875,6 +4896,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _morHyperHost.setType(hostTokens[0]); _morHyperHost.set_value(hostTokens[1]); + _guestTrafficInfo = (VmwareTrafficLabel) params.get("guestTrafficInfo"); + _publicTrafficInfo = (VmwareTrafficLabel) params.get("publicTrafficInfo"); VmwareContext context = getServiceContext(); try { VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); @@ -4882,12 +4905,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager()); cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID); - if (mgr.getNexusVSwitchGlobalParameter()) { + if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch || + _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) { cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP); - } else { - cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC); } - + cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC); cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID); cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK); @@ -4895,15 +4917,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _hostName = hostMo.getHyperHostName(); Map vsmCredentials; - if (mgr.getNexusVSwitchGlobalParameter()) { + if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch || + _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) { vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster)); if (vsmCredentials != null) { s_logger.info("Stocking credentials while configuring resource."); context.registerStockObject("vsmcredentials", vsmCredentials); } _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); - _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); - _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); } } catch (Exception e) { @@ -4912,12 +4933,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if(_privateNetworkVSwitchName == null) { _privateNetworkVSwitchName = (String) params.get("private.network.vswitch.name"); - } - if(_publicNetworkVSwitchName == null) { - _publicNetworkVSwitchName = (String) params.get("public.network.vswitch.name"); - } - if(_guestNetworkVSwitchName == null) { - _guestNetworkVSwitchName = (String) params.get("guest.network.vswitch.name"); } String value = (String) params.get("vmware.reserve.cpu"); @@ -4938,9 +4953,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa else _rootDiskController = DiskControllerType.ide; - value = params.get("vmware.use.nexus.vswitch").toString(); - if(value != null && value.equalsIgnoreCase("true")) - _nexusVSwitch = true; + Integer intObj = (Integer) params.get("ports.per.dvportgroup"); + if (intObj != null) + _portsPerDvPortGroup = intObj.intValue(); + + s_logger.info("VmwareResource network configuration info." + + " private traffic over vSwitch: " + _privateNetworkVSwitchName + ", public traffic over " + + this._publicTrafficInfo.getVirtualSwitchType() + " : " + this._publicTrafficInfo.getVirtualSwitchName() + + ", guest traffic over " + this._guestTrafficInfo.getVirtualSwitchType() + " : " + + this._guestTrafficInfo.getVirtualSwitchName()); value = params.get("vmware.create.full.clone").toString(); if (value != null && value.equalsIgnoreCase("true")) { @@ -4949,9 +4970,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _fullCloneFlag = false; } - s_logger.info("VmwareResource network configuration info. private vSwitch: " + _privateNetworkVSwitchName + ", public vSwitch: " + _publicNetworkVSwitchName + ", guest network: " - + _guestNetworkVSwitchName); - return true; } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index c4713ad331d..a4a08aa4046 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -455,6 +455,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, + cmd.getHypervisor()); } + if (hypervisorType == HypervisorType.VMware) { + Map allParams = cmd.getFullUrlParams(); + discoverer.putParam(allParams); + } + List result = new ArrayList(); long clusterId = 0; diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java index 50f95413bd2..77f6b795af4 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -40,10 +40,12 @@ import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.vmware.vim25.BoolPolicy; +import com.vmware.vim25.DVPortSetting; import com.vmware.vim25.DVPortgroupConfigInfo; +import com.vmware.vim25.DVPortgroupConfigSpec; +import com.vmware.vim25.DVSSecurityPolicy; import com.vmware.vim25.DVSTrafficShapingPolicy; import com.vmware.vim25.DynamicProperty; -import com.vmware.vim25.HostNetworkPolicy; import com.vmware.vim25.HostNetworkSecurityPolicy; import com.vmware.vim25.HostNetworkTrafficShapingPolicy; import com.vmware.vim25.HostPortGroupSpec; @@ -57,6 +59,7 @@ import com.vmware.vim25.ObjectContent; import com.vmware.vim25.OvfCreateImportSpecParams; import com.vmware.vim25.OvfCreateImportSpecResult; import com.vmware.vim25.OvfFileItem; +import com.vmware.vim25.VMwareDVSPortSetting; import com.vmware.vim25.VirtualDeviceConfigSpec; import com.vmware.vim25.VirtualDeviceConfigSpecOperation; import com.vmware.vim25.VirtualLsiLogicController; @@ -64,6 +67,8 @@ import com.vmware.vim25.VirtualMachineConfigSpec; import com.vmware.vim25.VirtualMachineFileInfo; import com.vmware.vim25.VirtualMachineVideoCard; import com.vmware.vim25.VirtualSCSISharing; +import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec; +import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanSpec; public class HypervisorHostHelper { private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class); @@ -389,29 +394,26 @@ public class HypervisorHostHelper { * @param networkRateMbps * @param networkRateMulticastMbps * @param timeOutMs - * @return - * @throws Exception - */ + * @param vSwitchType + * @param numPorts + * @return + * @throws Exception + */ - public static Pair prepareNetwork(String ethPortProfileName, String namePrefix, - HostMO hostMo, String vlanId, Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs) - throws Exception { + public static Pair prepareNetwork(String physicalNetwork, String namePrefix, + HostMO hostMo, String vlanId, Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, + VirtualSwitchType vSwitchType, int numPorts) throws Exception { ManagedObjectReference morNetwork = null; VmwareContext context = hostMo.getContext(); ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter(); DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); - - ManagedObjectReference morEthernetPortProfile = dataCenterMo.getDvPortGroupMor(ethPortProfileName); - - if (morEthernetPortProfile == null) { - String msg = "Unable to find Ethernet port profile " + ethPortProfileName; - s_logger.error(msg); - throw new Exception(msg); - } - else { - s_logger.info("Found Ethernet port profile " + ethPortProfileName); - } - + DistributedVirtualSwitchMO dvSwitchMo = null; + ManagedObjectReference morEthernetPortProfile = null; + String ethPortProfileName = null; + ManagedObjectReference morDvSwitch = null; + ManagedObjectReference morDvPortGroup = null; + String dvSwitchName = null; + boolean bWaitPortGroupReady = false; boolean createGCTag = false; String networkName; Integer vid = null; @@ -420,54 +422,109 @@ public class HypervisorHostHelper { createGCTag = true; vid = Integer.parseInt(vlanId); } + networkName = composeCloudNetworkName(namePrefix, vlanId, networkRateMbps, physicalNetwork); - networkName = composeCloudNetworkName(namePrefix, vlanId, networkRateMbps, ethPortProfileName); + if (vSwitchType == VirtualSwitchType.VMwareDistributedVirtualSwitch) { + DVSTrafficShapingPolicy shapingPolicy; + VmwareDistributedVirtualSwitchVlanSpec vlanSpec; + DVSSecurityPolicy secPolicy; + VMwareDVSPortSetting dvsPortSetting; + DVPortgroupConfigSpec dvPortGroupSpec; + DVPortgroupConfigInfo dvPortgroupInfo; - // TODO(sateesh): Enable this for VMware DVS. -// DVSTrafficShapingPolicy shapingPolicy = null; -// if (networkRateMbps != null && networkRateMbps.intValue() > 0) { -// shapingPolicy = new DVSTrafficShapingPolicy(); -// BoolPolicy isEnabled = new BoolPolicy(); -// LongPolicy averageBandwidth = new LongPolicy(); -// LongPolicy peakBandwidth = new LongPolicy(); -// LongPolicy burstSize = new LongPolicy(); -// -// isEnabled.setValue(true); -// averageBandwidth.setValue((long) networkRateMbps.intValue() * 1024L * 1024L); -// // We chose 50% higher allocation than average bandwidth. -// // TODO(sateesh): Also let user specify the peak coefficient -// peakBandwidth.setValue((long) (averageBandwidth.getValue() * 1.5)); -// // TODO(sateesh): Also let user specify the burst coefficient -// burstSize.setValue((long) (5 * averageBandwidth.getValue() / 8)); -// -// shapingPolicy.setEnabled(isEnabled); -// shapingPolicy.setAverageBandwidth(averageBandwidth); -// shapingPolicy.setPeakBandwidth(peakBandwidth); -// shapingPolicy.setBurstSize(burstSize); -// } - DVPortgroupConfigInfo spec = dataCenterMo.getDvPortGroupSpec(networkName); - long averageBandwidth = 0L; - if (networkRateMbps != null && networkRateMbps.intValue() > 0) { - averageBandwidth = (long) (networkRateMbps.intValue() * 1024L * 1024L); + dvSwitchName = physicalNetwork; + // TODO(sateesh): Remove this after ensuring proper default value for vSwitchName throughout traffic types + // and switch types. + if (dvSwitchName == null) { + s_logger.warn("Detected null dvSwitch. Defaulting to dvSwitch0"); + dvSwitchName = "dvSwitch0"; + } + morDvSwitch = dataCenterMo.getDvSwitchMor(dvSwitchName); + if (morDvSwitch == null) { + String msg = "Unable to find distributed vSwitch " + morDvSwitch; + s_logger.error(msg); + throw new Exception(msg); + } else { + s_logger.info("Found distributed vSwitch " + morDvSwitch); + } + + dvSwitchMo = new DistributedVirtualSwitchMO(context, morDvSwitch); + + shapingPolicy = getDVSShapingPolicy(networkRateMbps); + if (vid != null) { + vlanSpec = createDVPortVlanIdSpec(vid); + } else { + vlanSpec = createDVPortVlanSpec(); + } + secPolicy = createDVSSecurityPolicy(); + dvsPortSetting = createVmwareDVPortSettingSpec(shapingPolicy, secPolicy, vlanSpec); + dvPortGroupSpec = createDvPortGroupSpec(networkName, dvsPortSetting, numPorts); + + if (!dataCenterMo.hasDvPortGroup(networkName)) { + s_logger.info("Distributed Virtual Port group " + networkName + " not found."); + // TODO(sateesh): Handle Exceptions + try { + dvSwitchMo.createDVPortGroup(dvPortGroupSpec); + } catch (Exception e) { + String msg = "Failed to create distributed virtual port group " + networkName + " on dvSwitch " + physicalNetwork; + throw new Exception(msg); + } + bWaitPortGroupReady = true; + } else { + s_logger.info("Found Distributed Virtual Port group " + networkName); + // TODO(sateesh): Handle Exceptions + dvPortgroupInfo = dataCenterMo.getDvPortGroupSpec(networkName); + if (!isSpecMatch(dvPortgroupInfo, vid, shapingPolicy)) { + s_logger.info("Updating Distributed Virtual Port group " + networkName); + dvPortGroupSpec.setDefaultPortConfig(dvsPortSetting); + dvPortGroupSpec.setConfigVersion(dvPortgroupInfo.getConfigVersion()); + morDvPortGroup = dataCenterMo.getDvPortGroupMor(networkName); + try { + dvSwitchMo.updateDvPortGroup(morDvPortGroup, dvPortGroupSpec); + } catch (Exception e) { + String msg = "Failed to update distributed virtual port group " + networkName + " on dvSwitch " + physicalNetwork; + throw new Exception(msg); + } + bWaitPortGroupReady = true; + } + } + } else if (vSwitchType == VirtualSwitchType.NexusDistributedVirtualSwitch) { + ethPortProfileName = physicalNetwork; + // TODO(sateesh): Remove this after ensuring proper default value for vSwitchName throughout traffic types + // and switch types. + if (ethPortProfileName == null) { + s_logger.warn("Detected null ethrenet port profile. Defaulting to epp0."); + ethPortProfileName = "epp0"; + } + morEthernetPortProfile = dataCenterMo.getDvPortGroupMor(ethPortProfileName); + if (morEthernetPortProfile == null) { + String msg = "Unable to find Ethernet port profile " + ethPortProfileName; + s_logger.error(msg); + throw new Exception(msg); + } else { + s_logger.info("Found Ethernet port profile " + ethPortProfileName); + } + long averageBandwidth = 0L; + if (networkRateMbps != null && networkRateMbps.intValue() > 0) { + averageBandwidth = (long) (networkRateMbps.intValue() * 1024L * 1024L); + } + // We chose 50% higher allocation than average bandwidth. + // TODO(sateesh): Optionally let user specify the peak coefficient + long peakBandwidth = (long) (averageBandwidth * 1.5); + // TODO(sateesh): Optionally let user specify the burst coefficient + long burstSize = 5 * averageBandwidth / 8; + + if (!dataCenterMo.hasDvPortGroup(networkName)) { + s_logger.info("Port profile " + networkName + " not found."); + createPortProfile(context, physicalNetwork, networkName, vid, networkRateMbps, peakBandwidth, burstSize); + bWaitPortGroupReady = true; + } else { + s_logger.info("Port profile " + networkName + " found."); + updatePortProfile(context, physicalNetwork, networkName, vid, networkRateMbps, peakBandwidth, burstSize); + } } - // We chose 50% higher allocation than average bandwidth. - // TODO(sateesh): Also let user specify the peak coefficient - long peakBandwidth = (long) (averageBandwidth * 1.5); - // TODO(sateesh): Also let user specify the burst coefficient - long burstSize = 5 * averageBandwidth / 8; - - boolean bWaitPortGroupReady = false; - if (!dataCenterMo.hasDvPortGroup(networkName)) { - s_logger.info("Port profile " + networkName + " not found."); - createPortProfile(context, ethPortProfileName, networkName, vid, networkRateMbps, peakBandwidth, burstSize); - bWaitPortGroupReady = true; - } else { - s_logger.info("Port profile " + networkName + " found."); - bWaitPortGroupReady = true; - updatePortProfile(context, ethPortProfileName, networkName, vid, networkRateMbps, peakBandwidth, burstSize); - } - // Wait for dvPortGroup on vCenter - if(bWaitPortGroupReady) + // Wait for dvPortGroup on vCenter + if (bWaitPortGroupReady) morNetwork = waitForDvPortGroupReady(dataCenterMo, networkName, timeOutMs); else morNetwork = dataCenterMo.getDvPortGroupMor(networkName); @@ -486,7 +543,7 @@ public class HypervisorHostHelper { return new Pair(morNetwork, networkName); } - private static ManagedObjectReference waitForDvPortGroupReady( + public static ManagedObjectReference waitForDvPortGroupReady( DatacenterMO dataCenterMo, String dvPortGroupName, long timeOutMs) throws Exception { ManagedObjectReference morDvPortGroup = null; @@ -505,48 +562,122 @@ public class HypervisorHostHelper { return morDvPortGroup; } - // This method would be used for VMware Distributed Virtual Switch. - private static boolean isSpecMatch(DVPortgroupConfigInfo spec, Integer vid, DVSTrafficShapingPolicy shapingPolicy) { - DVSTrafficShapingPolicy currentTrafficShapingPolicy; - currentTrafficShapingPolicy = spec.getDefaultPortConfig().getInShapingPolicy(); - // TODO(sateesh): Extract and compare vendor specific configuration specification as well. - // DistributedVirtualSwitchKeyedOpaqueBlob[] vendorSpecificConfig = spec.getVendorSpecificConfig(); - - assert(currentTrafficShapingPolicy != null); - - LongPolicy averageBandwidth = currentTrafficShapingPolicy.getAverageBandwidth(); - LongPolicy burstSize = currentTrafficShapingPolicy.getBurstSize(); - LongPolicy peakBandwidth = currentTrafficShapingPolicy.getPeakBandwidth(); - BoolPolicy isEnabled = currentTrafficShapingPolicy.getEnabled(); - - if(!isEnabled.getValue()) - return false; - - if(averageBandwidth != null && !averageBandwidth.equals(shapingPolicy.getAverageBandwidth())) { - if(s_logger.isInfoEnabled()) { - s_logger.info("Average bandwidth setting in shaping policy doesn't match with existing setting."); - } - return false; - } else if(burstSize != null && !burstSize.equals(shapingPolicy.getBurstSize())) { - if(s_logger.isInfoEnabled()) { - s_logger.info("Burst size setting in shaping policy doesn't match with existing setting."); - } - return false; - } else if(peakBandwidth != null && !peakBandwidth.equals(shapingPolicy.getPeakBandwidth())) { - if(s_logger.isInfoEnabled()) { - s_logger.info("Peak bandwidth setting in shaping policy doesn't match with existing setting."); - } - return false; - } - - return true; - } + public static boolean isSpecMatch(DVPortgroupConfigInfo configInfo, Integer vid, DVSTrafficShapingPolicy shapingPolicy) { + DVSTrafficShapingPolicy currentTrafficShapingPolicy; + currentTrafficShapingPolicy = configInfo.getDefaultPortConfig().getInShapingPolicy(); + + assert(currentTrafficShapingPolicy != null); + + LongPolicy averageBandwidth = currentTrafficShapingPolicy.getAverageBandwidth(); + LongPolicy burstSize = currentTrafficShapingPolicy.getBurstSize(); + LongPolicy peakBandwidth = currentTrafficShapingPolicy.getPeakBandwidth(); + BoolPolicy isEnabled = currentTrafficShapingPolicy.getEnabled(); + + if (!isEnabled.equals(shapingPolicy.getEnabled())) { + return false; + } + + if(averageBandwidth != null && !averageBandwidth.equals(shapingPolicy.getAverageBandwidth())) { + if(s_logger.isInfoEnabled()) { + s_logger.info("Average bandwidth setting in shaping policy doesn't match with existing setting."); + } + return false; + } else if(burstSize != null && !burstSize.equals(shapingPolicy.getBurstSize())) { + if(s_logger.isInfoEnabled()) { + s_logger.info("Burst size setting in shaping policy doesn't match with existing setting."); + } + return false; + } else if(peakBandwidth != null && !peakBandwidth.equals(shapingPolicy.getPeakBandwidth())) { + if(s_logger.isInfoEnabled()) { + s_logger.info("Peak bandwidth setting in shaping policy doesn't match with existing setting."); + } + return false; + } + + return true; + } + + public static DVPortgroupConfigSpec createDvPortGroupSpec(String dvPortGroupName, DVPortSetting portSetting, int numPorts) { + DVPortgroupConfigSpec spec = new DVPortgroupConfigSpec(); + spec.setName(dvPortGroupName); + spec.setDefaultPortConfig(portSetting); + spec.setPortNameFormat("vnic"); + spec.setType("earlyBinding"); + spec.setNumPorts(numPorts); + // TODO(sateesh): Get vSphere API version and + // if >= 5.0 set autoExpand property of dvPortGroup config spec to true. + // spec.setAutoExpand(true); + return spec; + } + + public static VMwareDVSPortSetting createVmwareDVPortSettingSpec(DVSTrafficShapingPolicy shapingPolicy, DVSSecurityPolicy secPolicy, VmwareDistributedVirtualSwitchVlanSpec vlanSpec) { + VMwareDVSPortSetting dvsPortSetting = new VMwareDVSPortSetting(); + dvsPortSetting.setVlan(vlanSpec); + dvsPortSetting.setSecurityPolicy(secPolicy); + dvsPortSetting.setInShapingPolicy(shapingPolicy); + dvsPortSetting.setOutShapingPolicy(shapingPolicy); + + return dvsPortSetting; + } + + public static DVSTrafficShapingPolicy getDVSShapingPolicy(Integer networkRateMbps) { + DVSTrafficShapingPolicy shapingPolicy = new DVSTrafficShapingPolicy(); + if (networkRateMbps == null || networkRateMbps.intValue() <= 0) { + return shapingPolicy; + } + shapingPolicy = new DVSTrafficShapingPolicy(); + BoolPolicy isEnabled = new BoolPolicy(); + LongPolicy averageBandwidth = new LongPolicy(); + LongPolicy peakBandwidth = new LongPolicy(); + LongPolicy burstSize = new LongPolicy(); + + isEnabled.setValue(true); + averageBandwidth.setValue((long) networkRateMbps.intValue() * 1024L * 1024L); + // We chose 50% higher allocation than average bandwidth. + // TODO(sateesh): Also let user specify the peak coefficient + peakBandwidth.setValue((long) (averageBandwidth.getValue() * 1.5)); + // TODO(sateesh): Also let user specify the burst coefficient + burstSize.setValue((long) (5 * averageBandwidth.getValue() / 8)); + + shapingPolicy.setEnabled(isEnabled); + shapingPolicy.setAverageBandwidth(averageBandwidth); + shapingPolicy.setPeakBandwidth(peakBandwidth); + shapingPolicy.setBurstSize(burstSize); + + return shapingPolicy; + } + + public static VmwareDistributedVirtualSwitchVlanIdSpec createDVPortVlanIdSpec(int vlanId) { + VmwareDistributedVirtualSwitchVlanIdSpec vlanIdSpec = new VmwareDistributedVirtualSwitchVlanIdSpec(); + vlanIdSpec.setVlanId(vlanId); + return vlanIdSpec; + } + + public static VmwareDistributedVirtualSwitchVlanSpec createDVPortVlanSpec() { + VmwareDistributedVirtualSwitchVlanSpec vlanSpec = new VmwareDistributedVirtualSwitchVlanSpec(); + return vlanSpec; + } + + public static DVSSecurityPolicy createDVSSecurityPolicy() { + DVSSecurityPolicy secPolicy = new DVSSecurityPolicy(); + BoolPolicy allow = new BoolPolicy(); + allow.setValue(true); + + secPolicy.setForgedTransmits(allow); + secPolicy.setAllowPromiscuous(allow); + secPolicy.setMacChanges(allow); + return secPolicy; + } public static Pair prepareNetwork(String vSwitchName, String namePrefix, HostMO hostMo, String vlanId, Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs, boolean syncPeerHosts) throws Exception { HostVirtualSwitch vSwitch; + if (vSwitchName == null) { + s_logger.info("Detected vswitch name as undefined. Defaulting to vSwitch0"); + vSwitchName = "vSwitch0"; + } vSwitch = hostMo.getHostVirtualSwitchByName(vSwitchName); if (vSwitch == null) {