Updated Branches:
  refs/heads/4.2 87df51356 -> 55c0616d9

CLOUDSTACK-728 Rewrite support for lswitch connected nics on both standard and 
distributed switches.

Fix the name of the interface id in extra config, so the nic is found up using 
the nic uuid instead of the vm id.

getVlanInfo should return null when the nic is plugged on a Lswitch network.

On a distributed portgroup all vms should be connected to a single
portgroup and set a specific vlan on the port. On a standard switch each nic 
should have its own portgroup with a dedicated vlan (not related to CS vlans)


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/5bdbd72d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5bdbd72d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5bdbd72d

Branch: refs/heads/4.2
Commit: 5bdbd72d6dc1e55f6f754ff6aeceec7b6cfa8291
Parents: 87df513
Author: Hugo Trippaers <[email protected]>
Authored: Wed Jul 3 14:58:44 2013 +0200
Committer: Hugo Trippaers <[email protected]>
Committed: Fri Jul 12 14:22:44 2013 +0200

----------------------------------------------------------------------
 .../vmware/manager/VmwareManagerImpl.java       |   2 +-
 .../vmware/resource/VmwareResource.java         | 157 ++++++++++++++++++-
 .../vmware/mo/HypervisorHostHelper.java         |  69 ++++++--
 .../hypervisor/vmware/mo/VirtualMachineMO.java  |  76 ++++-----
 4 files changed, 251 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5bdbd72d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
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 c872e93..9eb6d34 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
@@ -352,7 +352,7 @@ public class VmwareManagerImpl extends ManagerBase 
implements VmwareManager, Vmw
         }
         s_logger.info("Preparing network on host " + 
hostMo.getContext().toString() + " for " + privateTrafficLabel);
         //The management network is probably always going to be a physical 
network with vlans, so assume BroadcastDomainType VLAN
-        HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", 
hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan);
+        HypervisorHostHelper.prepareNetwork(vSwitchName, "cloud.private", 
hostMo, vlanId, null, null, 180000, false, BroadcastDomainType.Vlan, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5bdbd72d/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
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 135bb03..05863eb 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
@@ -265,6 +265,7 @@ import com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO;
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
 import com.cloud.hypervisor.vmware.mo.DatastoreMO;
 import com.cloud.hypervisor.vmware.mo.DiskControllerType;
+import com.cloud.hypervisor.vmware.mo.DistributedVirtualSwitchMO;
 import com.cloud.hypervisor.vmware.mo.FeatureKeyConstants;
 import com.cloud.hypervisor.vmware.mo.HostDatastoreSystemMO;
 import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
@@ -319,6 +320,70 @@ import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineName;
 import com.cloud.vm.VmDetailConstants;
 
+import com.google.gson.Gson;
+import com.vmware.vim25.AboutInfo;
+import com.vmware.vim25.BoolPolicy;
+import com.vmware.vim25.ClusterDasConfigInfo;
+import com.vmware.vim25.ComputeResourceSummary;
+import com.vmware.vim25.DVPortConfigInfo;
+import com.vmware.vim25.DVPortConfigSpec;
+import com.vmware.vim25.DVPortSetting;
+import com.vmware.vim25.DatastoreSummary;
+import com.vmware.vim25.DistributedVirtualPort;
+import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
+import com.vmware.vim25.DistributedVirtualSwitchPortCriteria;
+import com.vmware.vim25.DynamicProperty;
+import com.vmware.vim25.GuestInfo;
+import com.vmware.vim25.GuestOsDescriptor;
+import com.vmware.vim25.HostCapability;
+import com.vmware.vim25.HostFirewallInfo;
+import com.vmware.vim25.HostFirewallRuleset;
+import com.vmware.vim25.HostHostBusAdapter;
+import com.vmware.vim25.HostInternetScsiTargetTransport;
+import com.vmware.vim25.HostScsiTopology;
+import com.vmware.vim25.HostInternetScsiHba;
+import com.vmware.vim25.HostInternetScsiHbaAuthenticationProperties;
+import com.vmware.vim25.HostInternetScsiHbaStaticTarget;
+import com.vmware.vim25.HostScsiDisk;
+import com.vmware.vim25.HostScsiTopologyInterface;
+import com.vmware.vim25.HostScsiTopologyLun;
+import com.vmware.vim25.HostScsiTopologyTarget;
+import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.ObjectContent;
+import com.vmware.vim25.OptionValue;
+import com.vmware.vim25.PerfCounterInfo;
+import com.vmware.vim25.PerfEntityMetric;
+import com.vmware.vim25.PerfEntityMetricBase;
+import com.vmware.vim25.PerfMetricId;
+import com.vmware.vim25.PerfMetricIntSeries;
+import com.vmware.vim25.PerfMetricSeries;
+import com.vmware.vim25.PerfQuerySpec;
+import com.vmware.vim25.PerfSampleInfo;
+import com.vmware.vim25.RuntimeFaultFaultMsg;
+import com.vmware.vim25.ToolsUnavailableFaultMsg;
+import com.vmware.vim25.VMwareDVSPortSetting;
+import com.vmware.vim25.VimPortType;
+import com.vmware.vim25.VirtualDevice;
+import com.vmware.vim25.VirtualDeviceBackingInfo;
+import com.vmware.vim25.VirtualDeviceConfigSpec;
+import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
+import com.vmware.vim25.VirtualDisk;
+import com.vmware.vim25.VirtualEthernetCard;
+import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
+import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo;
+import com.vmware.vim25.VirtualLsiLogicController;
+import com.vmware.vim25.VirtualMachineConfigOption;
+import com.vmware.vim25.VirtualMachineConfigSpec;
+import com.vmware.vim25.VirtualMachineFileInfo;
+import com.vmware.vim25.VirtualMachineGuestOsIdentifier;
+import com.vmware.vim25.VirtualMachinePowerState;
+import com.vmware.vim25.VirtualMachineRelocateSpec;
+import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
+import com.vmware.vim25.VirtualMachineRuntimeInfo;
+import com.vmware.vim25.VirtualSCSISharing;
+import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
+
+
 public class VmwareResource implements StoragePoolResource, ServerResource, 
VmwareHostService {
     private static final Logger s_logger = 
Logger.getLogger(VmwareResource.class);
 
@@ -1803,7 +1868,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
          */
         if (VirtualSwitchType.StandardVirtualSwitch == vSwitchType) {
             networkInfo = 
HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), 
"cloud.public",
-                    vmMo.getRunningHost(), vlanId, null, null, _ops_timeout, 
true, BroadcastDomainType.Vlan);
+                    vmMo.getRunningHost(), vlanId, null, null, _ops_timeout, 
true, BroadcastDomainType.Vlan, null);
         } else {
             networkInfo = 
HypervisorHostHelper.prepareNetwork(_publicTrafficInfo.getVirtualSwitchName(), 
"cloud.public",
                     vmMo.getRunningHost(), vlanId, null, null, null, 
_ops_timeout, vSwitchType, _portsPerDvPortGroup, null, false, 
BroadcastDomainType.Vlan);
@@ -2807,13 +2872,13 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             extraOptions.add(newVal);
             
             /**
-             * Extra Config : nvp.iface-id<num> = uuid
+             * Extra Config : nvp.iface-id.<num> = uuid
              *  - Required for Nicira NVP integration
              */
             int nicNum = 0;
             for (NicTO nicTo : sortNicsByDeviceId(nics)) {
                 newVal = new OptionValue();
-                newVal.setKey("nvp.iface-id" + nicNum);
+                newVal.setKey("nvp.iface-id." + nicNum);
                 newVal.setValue(nicTo.getUuid());
                 extraOptions.add(newVal);
                 nicNum++;
@@ -2837,9 +2902,86 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
 
             vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, 
String.valueOf(nicMask));
 
+            int nicIndex = 0;
+            for (NicTO nicTo : sortNicsByDeviceId(nics)) {
+                s_logger.debug("Checking for port configuration on NIC device 
: " + nicTo.toString());
+                if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
+                    // We need to create a port with a unique vlan and pass 
the key to the nic device
+                    s_logger.debug("Nic " + nicTo.toString() + " needs to be 
configured for NVP");
+                    VirtualDevice nicVirtualDevice = 
vmMo.getNicDeviceByIndex(nicIndex);
+                    if (nicVirtualDevice == null) {
+                        throw new Exception("Failed to find a VirtualDevice 
for nic " + nicIndex); //FIXME Generic exceptions are bad
+                    }
+                    VirtualDeviceBackingInfo backing = 
nicVirtualDevice.getBacking();
+                    if (backing instanceof 
VirtualEthernetCardDistributedVirtualPortBackingInfo) {
+                        VirtualEthernetCardDistributedVirtualPortBackingInfo 
portInfo = (VirtualEthernetCardDistributedVirtualPortBackingInfo) backing;
+                        DistributedVirtualSwitchPortConnection port = 
portInfo.getPort();
+                        String portKey = port.getPortKey();
+                        String portGroupKey = port.getPortgroupKey();
+                        String dvSwitchUuid = port.getSwitchUuid();
+                        
+                        s_logger.debug("NIC " + nicTo.toString() + " is 
connected to dvSwitch " + dvSwitchUuid + " pg " + portGroupKey + " port " + 
portKey);
+                        
+                        ManagedObjectReference dvSwitchManager = 
vmMo.getContext().getVimClient().getServiceContent().getDvSwitchManager();
+                        ManagedObjectReference dvSwitch = 
vmMo.getContext().getVimClient().getService().queryDvsByUuid(dvSwitchManager, 
dvSwitchUuid);
+                        
+                        DistributedVirtualSwitchPortCriteria criteria = new 
DistributedVirtualSwitchPortCriteria();
+                        criteria.setInside(true);
+                        criteria.getPortgroupKey().add(portGroupKey);
+                        criteria.getPortKey().add(portKey);
+                        List<DistributedVirtualPort> dvPorts = 
vmMo.getContext().getVimClient().getService().fetchDVPorts(dvSwitch, criteria);
+                        
+                        if (dvPorts.isEmpty()) {
+                            throw new Exception("Empty port list from dvSwitch 
for nic " + nicTo.toString());
+                        } else if (dvPorts.size() > 1) {
+                            throw new Exception("Expected only one port in the 
list from dvSwitch for nic " + nicTo.toString());
+                        }
+
+                        DistributedVirtualPort dvPort = dvPorts.get(0);
+                        DVPortConfigInfo dvPortConfigInfo = dvPort.getConfig();
+                        VMwareDVSPortSetting settings = (VMwareDVSPortSetting) 
dvPortConfigInfo.getSetting();
+                        
+                        VmwareDistributedVirtualSwitchVlanIdSpec vlanId = 
(VmwareDistributedVirtualSwitchVlanIdSpec) settings.getVlan();
+                        BoolPolicy blocked = settings.getBlocked();
+                        if (blocked.isValue() == Boolean.TRUE) {
+                            s_logger.debug("Port is blocked, we need to set a 
vlanid and unblock"); 
+                            DVPortConfigSpec dvPortConfigSpec = new 
DVPortConfigSpec();
+                            VMwareDVSPortSetting edittedSettings = new 
VMwareDVSPortSetting();
+                            // Unblock
+                            blocked.setValue(Boolean.FALSE);
+                            blocked.setInherited(Boolean.FALSE);
+                            edittedSettings.setBlocked(blocked);
+                            // Set vlan
+                            vlanId.setVlanId(100); //FIXME should be a 
determined based on usage
+                            vlanId.setInherited(false);
+                            edittedSettings.setVlan(vlanId);
+                            
+                            dvPortConfigSpec.setSetting(edittedSettings);
+                            dvPortConfigSpec.setOperation("edit");
+                            dvPortConfigSpec.setKey(portKey);
+                            List<DVPortConfigSpec> dvPortConfigSpecs = new 
ArrayList<DVPortConfigSpec>();
+                            dvPortConfigSpecs.add(dvPortConfigSpec);
+                            ManagedObjectReference task = 
vmMo.getContext().getVimClient().getService().reconfigureDVPortTask(dvSwitch, 
dvPortConfigSpecs);
+                            if 
(!vmMo.getContext().getVimClient().waitForTask(task)) {
+                                s_logger.error("Failed to configure the 
dvSwitch port for nic " + nicTo.toString());
+                            }
+                        } else {
+                            s_logger.trace("Port already configured and set to 
vlan " + vlanId.getVlanId());
+                        }
+                    }
+                    else {
+                        s_logger.error("nic device backing is of type " + 
backing.getClass().getName());
+                        throw new Exception("Incompatible backing for a 
VirtualDevice for nic " + nicIndex); //FIXME Generic exceptions are bad
+                    }
+                }
+                nicIndex++;
+            }
+
             if (!vmMo.powerOn()) {
                 throw new Exception("Failed to start VM. vmName: " + vmName);
             }
+            
+
 
             state = State.Running;
             return new StartAnswer(cmd);
@@ -2971,7 +3113,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         if (nicTo.getBroadcastType() == BroadcastDomainType.Native) {
             return defaultVlan;
         }
-        if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan || 
nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
+        else if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan || 
nicTo.getBroadcastType() == BroadcastDomainType.Pvlan) {
             if (nicTo.getBroadcastUri() != null) {
                 if (nicTo.getBroadcastType() == BroadcastDomainType.Vlan)
                     // For vlan, the broadcast uri is of the form 
vlan://<vlanid>
@@ -2983,6 +3125,9 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 s_logger.warn("BroadcastType is not claimed as VLAN or PVLAN, 
but without vlan info in broadcast URI. Use vlan info from labeling: " + 
defaultVlan);
                 return defaultVlan;
             }
+        } else if (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch) {
+            // We don't need to set any VLAN id for an NVP logical switch
+            return null;
         }
 
         s_logger.warn("Unrecognized broadcast type in VmwareResource, type: " 
+ nicTo.getBroadcastType().toString() + ". Use vlan info from labeling: " + 
defaultVlan);
@@ -3015,7 +3160,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         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"), 
nicTo.getBroadcastType());
+                    !namePrefix.startsWith("cloud.private"), 
nicTo.getBroadcastType(), nicTo.getUuid());
         }
         else {
             String vlanId = getVlanInfo(nicTo, switchName.second());
@@ -3029,7 +3174,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 svlanId = getPvlanInfo(nicTo);
             }
             networkInfo = 
HypervisorHostHelper.prepareNetwork(switchName.first(), namePrefix, hostMo, 
vlanId, svlanId,
-                    nicTo.getNetworkRateMbps(), 
nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType,
+                    nicTo.getNetworkRateMbps(), 
nicTo.getNetworkRateMulticastMbps(), _ops_timeout, switchType, 
                     _portsPerDvPortGroup, nicTo.getGateway(), 
configureVServiceInNexus, nicTo.getBroadcastType());
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5bdbd72d/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
----------------------------------------------------------------------
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 9df7bc3..dc1486a 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -52,6 +52,7 @@ import com.vmware.vim25.DVSTrafficShapingPolicy;
 import com.vmware.vim25.DynamicProperty;
 import com.vmware.vim25.HostNetworkSecurityPolicy;
 import com.vmware.vim25.HostNetworkTrafficShapingPolicy;
+import com.vmware.vim25.HostPortGroup;
 import com.vmware.vim25.HostPortGroupSpec;
 import com.vmware.vim25.HostVirtualSwitch;
 import com.vmware.vim25.HttpNfcLeaseDeviceUrl;
@@ -467,8 +468,12 @@ public class HypervisorHostHelper {
                 throw new InvalidParameterException("Nexus Distributed 
Virtualswitch is not supported with BroadcastDomainType " + 
                         broadcastDomainType);
             }
-            // Fixed name for the port-group on the vApp vswitch
-            networkName = "br-int";
+            /** 
+             * Nicira NVP requires all vms to be connected to a single 
port-group.
+             * A unique vlan needs to be set per port. This vlan is specific to
+             * this implementation and has no reference to other vlans in CS
+             */
+            networkName = "br-int"; // FIXME Should be set via a configuration 
item in CS
             // No doubt about this, depending on vid=null to avoid lots of 
code below
             vid = null;
         } else {
@@ -508,8 +513,7 @@ public class HypervisorHostHelper {
 
             if (broadcastDomainType == BroadcastDomainType.Lswitch) {
                 if (!dataCenterMo.hasDvPortGroup(networkName)) {
-                    // It'a bad thing if the integration bridge port-group 
does not exist
-                    throw new InvalidParameterException("Unable to find 
port-group " + networkName + " on dvSwitch " + dvSwitchName);
+                    throw new InvalidParameterException("NVP integration 
port-group " + networkName + " does not exist on the DVS " + dvSwitchName);
                 }
                 bWaitPortGroupReady = false;
             } else {
@@ -856,7 +860,7 @@ public class HypervisorHostHelper {
 
     public static Pair<ManagedObjectReference, String> prepareNetwork(String 
vSwitchName, String namePrefix,
             HostMO hostMo, String vlanId, Integer networkRateMbps, Integer 
networkRateMulticastMbps,
-            long timeOutMs, boolean syncPeerHosts, BroadcastDomainType 
broadcastDomainType) throws Exception {
+            long timeOutMs, boolean syncPeerHosts, BroadcastDomainType 
broadcastDomainType, String nicUuid) throws Exception {
 
         HostVirtualSwitch vSwitch;
         if (vSwitchName == null) {
@@ -893,8 +897,11 @@ public class HypervisorHostHelper {
         }
 
         if (broadcastDomainType == BroadcastDomainType.Lswitch) {
-            // Fixed name for the port-group on the vApp vswitch
-            networkName = "br-int";
+            /** 
+             * Nicira NVP requires each vm to have its own port-group with a 
dedicated
+             * vlan. We'll set the name of the pg to the uuid of the nic.
+             */
+            networkName = nicUuid;
             // No doubt about this, depending on vid=null to avoid lots of 
code below
             vid = null;
         } else {
@@ -933,10 +940,12 @@ public class HypervisorHostHelper {
         boolean bWaitPortGroupReady = false;
         if (broadcastDomainType == BroadcastDomainType.Lswitch) {
             if (!hostMo.hasPortGroup(vSwitch, networkName)) {
-                // It'a bad thing if the integration bridge port-group does 
not exist
-                throw new InvalidParameterException("Unable to find port-group 
" + networkName + " on dvSwitch " + vSwitchName);
+                createNvpPortGroup(hostMo, vSwitch, networkName, 
shapingPolicy);
+                
+                bWaitPortGroupReady = true;
+            } else {
+                bWaitPortGroupReady = false;
             }
-            bWaitPortGroupReady = false;
         } else {
             if (!hostMo.hasPortGroup(vSwitch, networkName)) {
                 hostMo.createPortGroup(vSwitch, networkName, vid, secPolicy, 
shapingPolicy);
@@ -982,7 +991,7 @@ public class HypervisorHostHelper {
                                         try {
                                             if(s_logger.isDebugEnabled())
                                                 s_logger.debug("Prepare 
network on other host, vlan: " + vlanId + ", host: " + 
otherHostMo.getHostName());
-                                            prepareNetwork(vSwitchName, 
namePrefix, otherHostMo, vlanId, networkRateMbps, networkRateMulticastMbps, 
timeOutMs, false, broadcastDomainType);
+                                            prepareNetwork(vSwitchName, 
namePrefix, otherHostMo, vlanId, networkRateMbps, networkRateMulticastMbps, 
timeOutMs, false, broadcastDomainType, nicUuid);
                                         } catch(Exception e) {
                                             s_logger.warn("Unable to prepare 
network on other host, vlan: " + vlanId + ", host: " + 
otherHostMo.getHostName());
                                         }
@@ -1041,6 +1050,44 @@ public class HypervisorHostHelper {
 
         return true;
     }
+    
+    private static void createNvpPortGroup(HostMO hostMo, HostVirtualSwitch 
vSwitch, String networkName, HostNetworkTrafficShapingPolicy shapingPolicy) 
throws Exception {
+        /** 
+         * No portgroup created yet for this nic
+         * We need to find an unused vlan and create the pg
+         * The vlan is limited to this vSwitch and the NVP vAPP, 
+         * so no relation to the other vlans in use in CloudStack.
+         */
+        String vSwitchName = vSwitch.getName();
+        
+        // Find all vlanids that we have in use
+        List<Integer> usedVlans = new ArrayList<Integer>();
+        for (HostPortGroup pg : hostMo.getHostNetworkInfo().getPortgroup()) {
+           HostPortGroupSpec hpgs = pg.getSpec();
+           if (vSwitchName.equals(hpgs.getVswitchName()))
+               usedVlans.add(hpgs.getVlanId());
+        }
+        
+        // Find the first free vlanid
+        int nvpVlanId = 0;
+        for (nvpVlanId = 1; nvpVlanId < 4095; nvpVlanId++) {
+            if (! usedVlans.contains(nvpVlanId)) {
+                break;
+            }
+        }
+        if (nvpVlanId == 4095) {
+            throw new InvalidParameterException("No free vlan numbers on " + 
vSwitchName + " to create a portgroup for nic " + networkName);
+        }
+        
+        // Strict security policy
+        HostNetworkSecurityPolicy secPolicy = new HostNetworkSecurityPolicy();
+        secPolicy.setAllowPromiscuous(Boolean.FALSE);
+        secPolicy.setForgedTransmits(Boolean.FALSE);
+        secPolicy.setMacChanges(Boolean.FALSE);
+        
+        // Create a portgroup with the uuid of the nic and the vlanid found 
above
+        hostMo.createPortGroup(vSwitch, networkName, nvpVlanId, secPolicy, 
shapingPolicy);      
+    }
 
     public static ManagedObjectReference waitForNetworkReady(HostMO hostMo,
             String networkName, long timeOutMs) throws Exception {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5bdbd72d/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
----------------------------------------------------------------------
diff --git 
a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java 
b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index 5214f3d..e2dd789 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -2048,47 +2048,53 @@ public class VirtualMachineMO extends BaseMO {
                return ++deviceNumber;
        }
 
-       public VirtualDevice[] getNicDevices() throws Exception {
-               List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().
-                       getDynamicProperty(_mor, "config.hardware.device");
+       private List<VirtualDevice> getNicDevices(boolean sorted) throws 
Exception {
+        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
 
-               List<VirtualDevice> nics = new ArrayList<VirtualDevice>();
-               if(devices != null) {
-                       for(VirtualDevice device : devices) {
-                               if(device instanceof VirtualEthernetCard) {
-                    nics.add(device);
+            List<VirtualDevice> nics = new ArrayList<VirtualDevice>();
+            if(devices != null) {
+                for(VirtualDevice device : devices) {
+                    if(device instanceof VirtualEthernetCard) {
+                        nics.add(device);
+                    }
                 }
-                       }
-               }
+            }
+            
+            if (sorted) {
+                Collections.sort(nics, new Comparator<VirtualDevice>() {
+                    @Override
+                    public int compare(VirtualDevice arg0, VirtualDevice arg1) 
{
+                        int unitNumber0 = arg0.getUnitNumber() != null ? 
arg0.getUnitNumber().intValue() : -1;
+                        int unitNumber1 = arg1.getUnitNumber() != null ? 
arg1.getUnitNumber().intValue() : -1;
+                        if(unitNumber0 < unitNumber1)
+                            return -1;
+                        else if(unitNumber0 > unitNumber1)
+                            return 1;
+                        return 0;
+                    }
+                });
+            }
+            
+            return nics;
+       }
 
-               return nics.toArray(new VirtualDevice[0]);
+       public VirtualDevice[] getNicDevices() throws Exception {
+               return getNicDevices(false).toArray(new VirtualDevice[0]);
+       }
+       
+       public VirtualDevice getNicDeviceByIndex(int index) throws Exception {
+           List<VirtualDevice> nics = getNicDevices(true);
+           try {
+               return nics.get(index);
+           } catch (IndexOutOfBoundsException e) {
+               // Not found
+               return null;
+           }
        }
 
        public Pair<Integer, VirtualDevice> getNicDeviceIndex(String 
networkNamePrefix) throws Exception {
-        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().
-        getDynamicProperty(_mor, "config.hardware.device");
-
-        List<VirtualDevice> nics = new ArrayList<VirtualDevice>();
-        if(devices != null) {
-            for(VirtualDevice device : devices) {
-                if(device instanceof VirtualEthernetCard) {
-                    nics.add(device);
-                }
-            }
-        }
-
-        Collections.sort(nics, new Comparator<VirtualDevice>() {
-            @Override
-            public int compare(VirtualDevice arg0, VirtualDevice arg1) {
-                int unitNumber0 = arg0.getUnitNumber() != null ? 
arg0.getUnitNumber().intValue() : -1;
-                int unitNumber1 = arg1.getUnitNumber() != null ? 
arg1.getUnitNumber().intValue() : -1;
-                if(unitNumber0 < unitNumber1)
-                    return -1;
-                else if(unitNumber0 > unitNumber1)
-                    return 1;
-                return 0;
-            }
-        });
+        List<VirtualDevice> nics = getNicDevices(true);
 
         int index = 0;
         String attachedNetworkSummary;

Reply via email to