vCloud enhancements [see also STRATOS-1192]
- added support for using multiple NICs. We use the NIC type of the first NIC 
for all the new ones. That should be a reasonable approximation of what the 
user wants and what their machine supports, UNLESS he/she is for example doing 
some funky nested virtualisation in the cartridge. Fixed IP support is not 
supported yet.
- vCloud guest customization script enhancements: rather than running 
customization scripts via SSH (this is used e.g. to inject metadata into the 
cartridge), use the vCloud guest customization script facility if at all 
possible. We don't want to always use ssh, since that imposes more requirements 
on the cartridge (root password change by vCloud, password-based SSH login 
enabled, firewall rules/network setup); the guest customization script is the 
preferable method.
- Added rudimentary disk attach support to vCloud, in jcloud and Stratos.


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

Branch: refs/heads/master-deployment-policy-fix-merge
Commit: ed952ac390cdd3140fd76f8fd047991b9d2b1740
Parents: eb091c3
Author: Martin Eppel <[email protected]>
Authored: Thu Mar 12 12:07:41 2015 -0700
Committer: Martin Eppel <[email protected]>
Committed: Thu Mar 12 12:07:41 2015 -0700

----------------------------------------------------------------------
 .../controller/iaases/vcloud/VCloudIaas.java    | 157 +++++++++-
 .../org/jclouds/vcloud/VCloudMediaType.java     |   4 +
 ...indDiskAttachOrDetachParamsToXmlPayload.java | 100 +++++++
 .../BindVCloudNetworkAdapterToXmlPayload.java   | 141 +++++++++
 ...EnvelopeOrThrowIllegalArgumentException.java |   3 -
 .../compute/options/VCloudTemplateOptions.java  |  37 +--
 ...edIntoNameThenCustomizeDeployAndPowerOn.java | 288 ++++++++++++++++---
 .../vcloud/domain/DiskAttachOrDetachParams.java | 173 +++++++++++
 .../java/org/jclouds/vcloud/features/VmApi.java |  67 +++--
 .../jclouds/vcloud/xml/OrgNetworkHandler.java   |   4 +-
 .../options/VCloudTemplateOptionsTest.java      |  20 +-
 ...ThenCustomizeDeployAndPowerOnExpectTest.java |  14 +-
 12 files changed, 900 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/vcloud/VCloudIaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/vcloud/VCloudIaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/vcloud/VCloudIaas.java
index 6a91823..b1f74b9 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/vcloud/VCloudIaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/vcloud/VCloudIaas.java
@@ -28,6 +28,7 @@ import 
org.apache.stratos.cloud.controller.util.ComputeServiceBuilderUtil;
 import org.apache.stratos.cloud.controller.domain.IaasProvider;
 import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
 import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.domain.TemplateBuilder;
@@ -38,7 +39,34 @@ import org.wso2.carbon.utils.CarbonUtils;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
+import java.net.URI;
+
+import org.apache.stratos.cloud.controller.domain.IaasProvider;
+import org.apache.stratos.cloud.controller.domain.NetworkInterface;
+import 
org.apache.stratos.cloud.controller.iaases.vcloud.VCloudPartitionValidator;
+import org.apache.stratos.cloud.controller.iaases.PartitionValidator;
+import org.jclouds.ContextBuilder;
+import org.jclouds.rest.RestContext;
+import org.jclouds.vcloud.VCloudApi;
+import org.jclouds.vcloud.domain.NetworkConnectionSection;
+import org.jclouds.vcloud.domain.ovf.VCloudHardDisk;
+import org.jclouds.vcloud.domain.NetworkConnection;
+import org.jclouds.vcloud.domain.Task;
+import org.jclouds.vcloud.domain.Vm;
+import org.jclouds.vcloud.domain.network.OrgNetwork;
+import org.jclouds.vcloud.domain.ovf.VCloudVirtualHardwareSection;
+import org.jclouds.vcloud.features.VAppApi;
+import org.jclouds.vcloud.features.VmApi;
+import org.jclouds.vcloud.domain.VApp;
+import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
+import org.jclouds.vcloud.domain.DiskAttachOrDetachParams;
+
+
 
 public class VCloudIaas extends JcloudsIaas {
 
@@ -74,6 +102,12 @@ public class VCloudIaas extends JcloudsIaas {
                        log.fatal(msg);
                        throw new CloudControllerException(msg);
                }
+               
+               //get 'native' version of jclouds' vCloud API.
+               ComputeServiceContext context = 
iaasInfo.getComputeService().getContext();
+               VCloudApi api = context.unwrapApi(VCloudApi.class);
+               
+
 
                TemplateBuilder templateBuilder = iaasInfo.getComputeService()
                                .templateBuilder();
@@ -98,9 +132,49 @@ public class VCloudIaas extends JcloudsIaas {
                // groups by Jclouds.
                template.getOptions().as(TemplateOptions.class)
                                .inboundPorts(22, 80, 8080, 443, 8243);
-
-               template.getOptions().as(VCloudTemplateOptions.class)
-                               
.ipAddressAllocationMode(IpAddressAllocationMode.POOL);
+               
+        if (iaasInfo.getNetworkInterfaces() != null) {
+            Set<String> networksSet = new 
LinkedHashSet<String>(iaasInfo.getNetworkInterfaces().length);
+            Hashtable<String, NetworkConnection> vcloudNetworkOptions = new 
Hashtable<String, NetworkConnection>(iaasInfo.getNetworkInterfaces().length);
+
+            int i = 0;
+            for (NetworkInterface ni : iaasInfo.getNetworkInterfaces()) {
+
+                String networkUuid = ni.getNetworkUuid();
+                String networkName = null;
+                IpAddressAllocationMode ipAllocMode = 
IpAddressAllocationMode.NONE;
+                if (ni.getFixedIp() != null && !ni.getFixedIp().equals("")) {
+                    ipAllocMode = IpAddressAllocationMode.MANUAL;
+                } else {
+                    ipAllocMode = IpAddressAllocationMode.POOL;
+                }
+
+                //fetch network name.
+                try {
+                    OrgNetwork orgNet = api.getNetworkApi().getNetwork(new 
URI(networkUuid));
+                    networkName = orgNet.getName();
+                } catch (URISyntaxException e) {
+                    log.error("Network UUID '" + networkUuid + "' is not a 
URI/href.");
+                }
+                NetworkConnection nc = new NetworkConnection(networkName, i, 
ni.getFixedIp(), null, true,
+                        null, //TODO: support fixed Mac addrs.
+                        ipAllocMode);
+                networksSet.add(networkUuid);
+                vcloudNetworkOptions.put(networkUuid, nc);
+
+                i++;
+            }
+            //new NetworkConnectionSection()
+
+            //VmApi vmApi = api.getVmApi();
+            //vmApi.updateNetworkConnectionOfVm();
+
+            template.getOptions().networks(networksSet);
+            
template.getOptions().as(VCloudTemplateOptions.class).networkConnections(vcloudNetworkOptions);
+        }
+
+               //template.getOptions().as(VCloudTemplateOptions.class)
+               //              
.ipAddressAllocationMode(IpAddressAllocationMode.POOL);
 
                // set Template
                iaasInfo.setTemplate(template);
@@ -111,7 +185,7 @@ public class VCloudIaas extends JcloudsIaas {
                // in vCloud case we need to run a script
                IaasProvider iaasProvider = getIaasProvider();
 
-               if (iaasProvider.getTemplate() == null) {
+               if (iaasProvider.getTemplate() == null || payload == null) {
                        if (log.isDebugEnabled()) {
                                log.debug("Payload for vCloud not found");
                        }
@@ -177,9 +251,23 @@ public class VCloudIaas extends JcloudsIaas {
                if (log.isDebugEnabled()) {
                        log.debug(String.format("The vCloud Customization 
script\n%s", customizationScript));
                }
+               
+               // Ensure the script is run.
+               if (customizationScript.length() >= 49000) {
+                       log.warn("The vCloud customization script is >=49000 
bytes in size; uploading dummy script and running real script via ssh.");
+                       String dummyCustomizationScript = "#!/bin/sh\n"
+                               + "#STRATOS: the real customization script will 
be invoked via ssh, since it exceeds the 49000 byte limit "
+                               + "imposed by vCloud;\n"
+                               + "#see "
+                               + 
"http://pubs.vmware.com/vcd-55/topic/com.vmware.vcloud.api.doc_55/GUID-1BA3B7C5-B46C-48F7-8704-945BC47A940D.html\n";;
+                       
template.getOptions().as(VCloudTemplateOptions.class).customizationScript(dummyCustomizationScript);
+                       template.getOptions().runScript(customizationScript);
+               } else {
+                       
template.getOptions().as(VCloudTemplateOptions.class).customizationScript(customizationScript);
+               }
 
                // Run the script
-               template.getOptions().runScript(customizationScript);
+               //template.getOptions().runScript(customizationScript);
        }
 
        @Override
@@ -238,8 +326,63 @@ public class VCloudIaas extends JcloudsIaas {
 
        @Override
        public String attachVolume(String instanceId, String volumeId, String 
deviceName) {
-               // TODO Auto-generated method stub
-               return null;
+        IaasProvider iaasInfo = getIaasProvider();
+
+        if (StringUtils.isEmpty(volumeId)) {
+            log.error("Volume provided to attach can not be null");
+        }
+
+        if (StringUtils.isEmpty(instanceId)) {
+            log.error("Instance provided to attach can not be null");
+        }
+
+        URI instanceIdHref = null;
+        URI volumeIdHref = null;
+        try {
+            //the instanceId format is a bit silly for vCloud.
+            instanceIdHref = new URI("https:/" + instanceId);
+        } catch (URISyntaxException e) {
+            log.error("Failed to attach volume, because the instance id cannot 
be converted into a url by concatenating "
+                + "'https:/' with " + instanceId + ". Full stacktrace: " + 
e.toString());
+            return null;
+        }
+        try {
+            volumeIdHref = new URI(volumeId);
+        } catch (URISyntaxException e) {
+            log.error("Failed to attach voluume, because the volume id '" + 
volumeId + "' is not a valid href (URI))"
+                    + e.toString());
+        }
+
+        //get 'native' version of jclouds' vCloud API.
+        ComputeServiceContext context = iaasInfo.getComputeService()
+                .getContext();
+
+        VCloudApi api = context.unwrapApi(VCloudApi.class);
+
+        //Disks need to be attached to individual VMs, not vApps. The 
instanceId is the VApp.
+        VAppApi vAppApi = api.getVAppApi();
+        Set<Vm> vmsInVapp = vAppApi.getVApp(instanceIdHref).getChildren();
+        //Each vApp today has just 1 VM in it. Validate assumption.
+        assert(vmsInVapp.size() == 1);
+        Vm vm = vmsInVapp.iterator().next();
+        URI vmHref = vm.getHref();
+        VmApi vmApi = api.getVmApi();
+
+        // invest
+        /*
+        VCloudHardDisk.Builder hardDiskBuilder = new VCloudHardDisk.Builder();
+        VCloudHardDisk hardDisk = hardDiskBuilder.instanceID(volumeId).build();
+        VCloudVirtualHardwareSection vvhs = vm.getVirtualHardwareSection();
+        VCloudHardDisk.Builder Vchd = new VCloudHardDisk.Builder();
+        
vvhs.toBuilder().item(Vchd.capacity(3).instanceID("hgfhgf").build()).build();
+        VApp va = vAppApi.getVApp(instanceIdHref);
+
+        */ //EO invest
+        DiskAttachOrDetachParams params = new 
DiskAttachOrDetachParams(volumeIdHref);
+        Task t = vmApi.attachDisk(vmHref, params);
+
+        log.info(String.format("Volume [id]: %s attachment for instance [id]: 
%s was successful [status]: Attaching. Iaas : %s, Task: %s", volumeId, 
instanceId, iaasInfo, t));
+        return "Attaching";
        }
 
        @Override

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/VCloudMediaType.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/VCloudMediaType.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/VCloudMediaType.java
index 67701fb..7126701 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/VCloudMediaType.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/VCloudMediaType.java
@@ -205,6 +205,10 @@ public interface VCloudMediaType {
     */
    public static final String RASDITEM_XML = 
"application/vnd.vmware.vcloud.rasdItem+xml";
    /**
+    * "application/vnd.vmware.vcloud.rasdItemsList+xml"
+    */
+   public static final String RASDITEMLIST_XML = 
"application/vnd.vmware.vcloud.rasdItemsList+xml";
+   /**
     * "application/vnd.vmware.vcloud.rasdItem+xml"
     */
    public static final MediaType RASDITEM_XML_TYPE = new 
MediaType("application", "vnd.vmware.vcloud.rasdItem+xml");

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindDiskAttachOrDetachParamsToXmlPayload.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindDiskAttachOrDetachParamsToXmlPayload.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindDiskAttachOrDetachParamsToXmlPayload.java
new file mode 100644
index 0000000..7e198aa
--- /dev/null
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindDiskAttachOrDetachParamsToXmlPayload.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.jclouds.vcloud.binders;
+
+import com.google.common.base.Throwables;
+import com.google.inject.Inject;
+import com.jamesmurty.utils.XMLBuilder;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.rest.binders.BindToStringPayload;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+import org.jclouds.vcloud.domain.DiskAttachOrDetachParams;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import java.util.Map;
+import java.util.Properties;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
+import static 
org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
+
+/**
+ * Created by mblokzij on 29/10/2014.
+ */
+@Singleton
+public class BindDiskAttachOrDetachParamsToXmlPayload implements MapBinder {
+
+    protected final String ns;
+    protected final String schema;
+
+    protected final BindToStringPayload stringBinder;
+
+    @Inject
+    public BindDiskAttachOrDetachParamsToXmlPayload(BindToStringPayload 
stringBinder,
+                                                    
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, 
@Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
+        this.ns = ns;
+        this.schema = schema;
+        this.stringBinder = stringBinder;
+    }
+
+    @Override
+    public <R extends HttpRequest> R bindToRequest(R request, Map<String, 
Object> postParams) {
+        checkArgument(checkNotNull(request, "request") instanceof 
GeneratedHttpRequest,
+                "this binder is only valid for GeneratedHttpRequests!");
+        DiskAttachOrDetachParams params = (DiskAttachOrDetachParams) 
checkNotNull(postParams.remove("params"), "params");
+        XMLBuilder diskAttachOrDetachParams;
+        String xml = null;
+        try {
+            diskAttachOrDetachParams = 
XMLBuilder.create("DiskAttachOrDetachParams").a("xmlns", ns);
+            XMLBuilder disk = diskAttachOrDetachParams.e("Disk");
+            if (params.getHref() != null) {
+                disk.a("href", params.getHref().toString());
+            }
+            if (params.getId() != null) {
+                disk.a("id", params.getId().toString());
+            }
+            if (params.getName() != null) {
+                disk.a("name", params.getName());
+            }
+            if (params.getType() != null) {
+                disk.a("type", params.getType());
+            }
+            if (params.getBusNumber() != null) {
+                
diskAttachOrDetachParams.e("BusNumber").t(params.getBusNumber().toString());
+            }
+            if (params.getUnitNumber() != null) {
+                
diskAttachOrDetachParams.e("UnitNumber").t(params.getUnitNumber().toString());
+            }
+
+            xml = diskAttachOrDetachParams.asString();
+        } catch (Exception e) {
+            Throwables.propagate(e);
+        }
+        return stringBinder.bindToRequest(request, xml);
+    }
+
+    @Override
+    public <R extends HttpRequest> R bindToRequest(R request, Object 
postParams) {
+        throw new 
IllegalStateException("BindDiskAttachOrDetachParamsToXmlPayload needs 
parameters");
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindVCloudNetworkAdapterToXmlPayload.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindVCloudNetworkAdapterToXmlPayload.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindVCloudNetworkAdapterToXmlPayload.java
new file mode 100644
index 0000000..b3fe262
--- /dev/null
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/binders/BindVCloudNetworkAdapterToXmlPayload.java
@@ -0,0 +1,141 @@
+/*
+ * 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 org.jclouds.vcloud.binders;
+
+import com.google.common.base.Throwables;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import com.jamesmurty.utils.XMLBuilder;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.rest.binders.BindToStringPayload;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
+
+import javax.inject.Singleton;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
+import static 
org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
+
+/**
+ * Created by michiel on 17/11/2014.
+ */
+@Singleton
+public class BindVCloudNetworkAdapterToXmlPayload implements MapBinder {
+
+    protected final String ns;
+    protected final String schema;
+
+    protected final BindToStringPayload stringBinder;
+
+    @Inject
+    public BindVCloudNetworkAdapterToXmlPayload(BindToStringPayload 
stringBinder,
+                                                
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns,
+                                                
@Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
+        this.ns = ns;
+        this.schema = schema;
+        this.stringBinder = stringBinder;
+    }
+
+    @Override
+    public <R extends HttpRequest> R bindToRequest(R request, Map<String, 
Object> postParams) {
+        checkArgument(checkNotNull(request, "request") instanceof 
GeneratedHttpRequest,
+                "this binder is only valid for GeneratedHttpRequests!");
+
+        Iterable<VCloudNetworkAdapter> networkCards = 
(Iterable<VCloudNetworkAdapter>) checkNotNull(postParams.remove("params"), 
"params");
+
+        /*
+         * The Iterable<VCloudNetworkAdapter> needs to be turned into a 
RasdItemList.
+         */
+        XMLBuilder rasdItemListBuilder;
+        String xml = null;
+        try {
+            rasdItemListBuilder = 
XMLBuilder.create("RasdItemsList").a("xmlns", ns);
+            //all sorts of other crazy XML attributes
+            rasdItemListBuilder.a("xmlns:rasd", 
"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData";);
+            rasdItemListBuilder.a("xmlns:xsi", 
"http://www.w3.org/2001/XMLSchema-instance";);
+            rasdItemListBuilder.a("type", 
"application/vnd.vmware.vcloud.rasdItemsList+xml");
+            //rasdItemListBuilder.a("href", 
"https://<vcloud>/api/vApp/vm-<UUID>/virtualHardwareSection/networkCards");
+            //rasdItemListBuilder.a("xsi:schemaLocation", 
"http://www.vmware.com/vcloud/v1.5 
http://172.28.44.90/api/v1.5/schema/master.xsd 
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData
 
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd";);
+
+            for (VCloudNetworkAdapter nic: networkCards) {
+                /*
+                 * NOTE: the order of these items IS important.
+                 */
+                XMLBuilder rasdItem = rasdItemListBuilder.elem("Item");
+                if (nic.getAddress() != null)
+                    rasdItem.elem("rasd:Address").text(nic.getAddress());
+                if (nic.getAddressOnParent() != null)
+                    
rasdItem.elem("rasd:AddressOnParent").text(nic.getAddressOnParent());
+                if (nic.isAutomaticAllocation() != null)
+                    
rasdItem.elem("rasd:AutomaticAllocation").text(String.valueOf(nic.isAutomaticAllocation()));
+
+                //the connection handling is a little bit more involved.
+                if (nic.getConnections().size() > 1) {
+                    /*
+                     * The IP address is an attribute of the <rasd:Connection 
/> element, and we only store
+                     * 1 IP address for the whole NIC. It's not clear to me 
why the nic.getConnections() returns
+                     * a list anyway.
+                     */
+                    throw new UnsupportedOperationException("Currently we only 
support 1 connection per NIC.");
+                }
+                if (nic.getConnections() != null) {
+                    for (String connection: nic.getConnections()) {
+                        XMLBuilder c = 
rasdItem.elem("rasd:Connection").a("xmlns:vcloud", ns);
+                        if (nic.getIpAddress() != null)
+                            c.a("vcloud:ipAddress", nic.getIpAddress());
+
+                        c.a("vcloud:primaryNetworkConnection", 
String.valueOf(nic.isPrimaryNetworkConnection()));
+                        if (nic.getIpAddressingMode() != null)
+                            c.a("vcloud:ipAddressingMode", 
nic.getIpAddressingMode());
+                        c.text(connection);
+                    }
+                }
+
+                if (nic.getDescription() != null)
+                    
rasdItem.elem("rasd:Description").text(nic.getDescription());
+                if (nic.getElementName() != null)
+                    
rasdItem.elem("rasd:ElementName").text(nic.getElementName());
+                if (nic.getInstanceID() != null)
+                    rasdItem.elem("rasd:InstanceID").text(nic.getInstanceID());
+                if (nic.getResourceSubType() != null)
+                    
rasdItem.elem("rasd:ResourceSubType").text(nic.getResourceSubType());
+                if (nic.getResourceType() != null)
+                    
rasdItem.elem("rasd:ResourceType").text(nic.getResourceType().value());
+
+                //TODO: remaining items
+            }
+            xml = rasdItemListBuilder.asString();
+        } catch (ParserConfigurationException e) {
+            Throwables.propagate(e);
+        } catch (TransformerException e) {
+            Throwables.propagate(e);
+        }
+
+        return stringBinder.bindToRequest(request, xml);
+    }
+
+    @Override
+    public <R extends HttpRequest> R bindToRequest(R request, Object 
postParams) {
+        throw new IllegalStateException("BindVCloudNetworkAdapterToXmlPayload 
needs parameters");
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/functions/ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/functions/ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/functions/ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException.java
index dce8306..c08a622 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/functions/ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/functions/ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException.java
@@ -51,9 +51,6 @@ public class 
ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentExceptio
    public Envelope apply(VAppTemplate from) {
       checkArgument(from.getChildren().size() == 1, "multiple vms are not 
supported: %s", from);
 
-      checkArgument(from.getNetworkSection().getNetworks().size() == 1,
-               "multiple network connections are not supported: %s", from);
-
       checkArgument(from.isOvfDescriptorUploaded(), "ovf descriptor is not 
uploaded: %s", from);
       Envelope ovf = getOVFForVAppTemplateAndValidate(from);
       return ovf;

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java
index 03b12fe..0910db4 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptions.java
@@ -21,9 +21,11 @@ import static 
com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Strings.emptyToNull;
 
 import java.net.URI;
+import java.util.Hashtable;
 import java.util.Map;
 
 import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.vcloud.domain.NetworkConnection;
 import org.jclouds.vcloud.domain.network.FenceMode;
 import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
 
@@ -62,10 +64,8 @@ public class VCloudTemplateOptions extends TemplateOptions 
implements Cloneable
             eTo.customizationScript(getCustomizationScript());
          if (getDescription() != null)
             eTo.description(getDescription());
-         if (getIpAddressAllocationMode() != null)
-            eTo.ipAddressAllocationMode(getIpAddressAllocationMode());
-         if (getIpAddressAllocationMode() != null)
-            eTo.ipAddressAllocationMode(getIpAddressAllocationMode());
+         if (getNetworkConnections() != null)
+            eTo.networkConnections(getNetworkConnections());
          if (getParentNetwork() != null)
             eTo.parentNetwork(getParentNetwork());
          if (getFenceMode() != null)
@@ -75,7 +75,9 @@ public class VCloudTemplateOptions extends TemplateOptions 
implements Cloneable
 
    private String description = null;
    private String customizationScript = null;
-   private IpAddressAllocationMode ipAddressAllocationMode = null;
+   // This Hashtable maps TemplateOptions.networks[i] to each networks' 
specific vCloud options
+   // We index by network 'name' (href in vCloud)
+   private Hashtable<String, NetworkConnection> networkConnections = null;
    private URI parentNetwork = null;
    private FenceMode fenceMode = null;
 
@@ -88,20 +90,20 @@ public class VCloudTemplateOptions extends TemplateOptions 
implements Cloneable
       VCloudTemplateOptions that = VCloudTemplateOptions.class.cast(o);
       return super.equals(that) && equal(this.description, that.description)
             && equal(this.customizationScript, that.customizationScript)
-            && equal(this.ipAddressAllocationMode, 
that.ipAddressAllocationMode)
+            && equal(this.networkConnections, that.networkConnections)
             && equal(this.parentNetwork, that.parentNetwork);
    }
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(super.hashCode(), description, 
customizationScript, ipAddressAllocationMode,
+      return Objects.hashCode(super.hashCode(), description, 
customizationScript, networkConnections,
             parentNetwork);
    }
 
    @Override
    public ToStringHelper string() {
       return super.string().add("description", 
description).add("customizationScript", customizationScript)
-            .add("ipAddressAllocationMode", 
ipAddressAllocationMode).add("parentNetwork", parentNetwork);
+            .add("networkConnections", 
networkConnections).add("parentNetwork", parentNetwork);
    }
 
    /**
@@ -122,11 +124,12 @@ public class VCloudTemplateOptions extends 
TemplateOptions implements Cloneable
    }
 
    /**
-    * Specifies the ipAddressAllocationMode used to for network interfaces on
-    * the VMs
+    * Specifies the networkConnections settings used to for network interfaces 
on
+    * the VMs. This lets you specify things like ip address allocation mode,
+    * the actual IP (in case of fixed IP) etc.
     */
-   public VCloudTemplateOptions 
ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
-      this.ipAddressAllocationMode = ipAddressAllocationMode;
+   public VCloudTemplateOptions networkConnections(Hashtable<String, 
NetworkConnection> networkConnections) {
+      this.networkConnections = networkConnections;
       return this;
    }
 
@@ -167,10 +170,10 @@ public class VCloudTemplateOptions extends 
TemplateOptions implements Cloneable
       }
 
       /**
-       * @see VCloudTemplateOptions#ipAddressAllocationMode
+       * @see VCloudTemplateOptions#networkConnections
        */
-      public static VCloudTemplateOptions 
ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
-         return new 
VCloudTemplateOptions().ipAddressAllocationMode(ipAddressAllocationMode);
+      public static VCloudTemplateOptions networkConnections(Hashtable<String, 
NetworkConnection> networkConnections) {
+         return new 
VCloudTemplateOptions().networkConnections(networkConnections);
       }
 
       /**
@@ -255,9 +258,7 @@ public class VCloudTemplateOptions extends TemplateOptions 
implements Cloneable
    /**
     * @return ipAddressAllocationMode on the vms
     */
-   public IpAddressAllocationMode getIpAddressAllocationMode() {
-      return ipAddressAllocationMode;
-   }
+   public Hashtable<String, NetworkConnection> getNetworkConnections() { 
return networkConnections; }
 
    /**
     * @return parentNetwork to connect to the vms

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java
index e8b9fcd..73868fb 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java
@@ -22,17 +22,22 @@ import static com.google.common.collect.Iterables.find;
 import static com.google.common.collect.Iterables.get;
 import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
 import static 
org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
+import static org.jclouds.util.Predicates2.retry;
 import static 
org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom;
-import static 
org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig;
+import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.net.URI;
-import java.util.Map;
+import java.net.URISyntaxException;
+import java.util.*;
 
 import javax.annotation.Resource;
 import javax.inject.Inject;
 import javax.inject.Named;
 import javax.inject.Singleton;
 
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import org.jclouds.cim.ResourceAllocationSettingData;
 import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.reference.ComputeServiceConstants;
@@ -44,16 +49,12 @@ import org.jclouds.rest.annotations.BuildVersion;
 import org.jclouds.vcloud.TaskStillRunningException;
 import org.jclouds.vcloud.VCloudApi;
 import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
-import org.jclouds.vcloud.domain.GuestCustomizationSection;
-import org.jclouds.vcloud.domain.NetworkConnection;
-import org.jclouds.vcloud.domain.NetworkConnectionSection;
+import org.jclouds.vcloud.domain.*;
 import org.jclouds.vcloud.domain.NetworkConnectionSection.Builder;
-import org.jclouds.vcloud.domain.Task;
-import org.jclouds.vcloud.domain.VApp;
-import org.jclouds.vcloud.domain.VAppTemplate;
-import org.jclouds.vcloud.domain.Vm;
+import org.jclouds.vcloud.domain.internal.VmImpl;
 import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
 import org.jclouds.vcloud.domain.network.NetworkConfig;
+import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
 import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -61,6 +62,7 @@ import com.google.common.base.Joiner;
 import com.google.common.base.Predicate;
 import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableSet;
+import org.jclouds.vcloud.predicates.TaskSuccess;
 
 @Singleton
 public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn {
@@ -132,7 +134,7 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
       waitForTask(updateVmWithNameAndCustomizationScript(vm, name, 
vOptions.getCustomizationScript()));
       logger.trace("<< updated customization vm(%s)", name);
 
-      ensureVmHasAllocationModeOrPooled(vAppResponse, 
vOptions.getIpAddressAllocationMode());
+       ensureVmHasDesiredNetworkConnectionSettings(vAppResponse, vOptions);
 
       int cpuCount = (int) getCores(template.getHardware());
       logger.trace(">> updating cpuCount(%d) vm(%s)", cpuCount, vm.getName());
@@ -169,17 +171,85 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
          throw new UnsupportedOperationException("we currently do not support 
multiple vms in a vAppTemplate "
                   + vAppTemplate);
 
-      if (vAppTemplate.getNetworkSection().getNetworks().size() > 1)
-         throw new UnsupportedOperationException(
-                  "we currently do not support multiple network connections in 
a vAppTemplate " + vAppTemplate);
+       VmImpl vmTemplate = 
VmImpl.class.cast(vAppTemplate.getChildren().iterator().next());
 
-      Network networkToConnect = 
get(vAppTemplate.getNetworkSection().getNetworks(), 0);
+      String description = 
VCloudTemplateOptions.class.cast(template.getOptions()).getDescription();
+      if (description == null) {
+         Map<String, String> md = 
metadataAndTagsAsCommaDelimitedValue(template.getOptions());
+         description = Joiner.on('\n').withKeyValueSeparator("=").join(md);
+      }
 
-      
-      NetworkConfig config = 
networkConfigurationForNetworkAndOptions.apply(networkToConnect, vOptions);
+      InstantiateVAppTemplateOptions options = 
InstantiateVAppTemplateOptions.Builder.description(description);
+
+      /*
+       * Match up networks in the vApp template with the ones in the options 
we got passed in, so that
+       * the right ones can be wired together.
+       * Note that in the end the order of the network interfaces is what's 
important, not the names. The names
+       * might not match up. In the worst case, maybe someone called their 
vApp networks A and B, but really wants
+       * them cross-connected, i.e. wired up to B and A respectively.
+       * The only potential issue here is that the networks in the vOptions 
are stored as a Set, which makes little
+       * sense. While the API is what it is, we need to rely on people higher 
up using sensible underlying
+       * datastructures (that conform to the set interface), which preserve 
their order.
+       */
+
+      int vmTemplateNumNetworks = 
vmTemplate.getNetworkConnectionSection().getConnections().size();
+
+      /*
+       * Backwards-compatibility hack: we might get passed in a parent network 
URI and an empty vOptions.networks list.
+       * In that case, move the parent network URI into the vOptions.networks 
list, and remove the parent URI.
+       */
+      if (vOptions.getNetworks().size() == 0 && vmTemplateNumNetworks == 1 && 
vOptions.getParentNetwork() != null) {
+         ArrayList<String> netlist = new ArrayList<String>();
+         netlist.add(vOptions.getParentNetwork().toASCIIString());
+         vOptions.networks(netlist);
+         vOptions.parentNetwork(null);
+      }
+
+      URI[] vOptionsNetworkIdList = new URI[vOptions.getNetworks().size()];
+      NetworkConnection[] vAppTemplateNetworkList =
+         new NetworkConnection[vmTemplateNumNetworks];
+
+      //hopefully this preserves the original order, assuming the original 
underlying datastructure was ordered.
+      int i = 0;
+      for (String network: vOptions.getNetworks()) {
+         try {
+            vOptionsNetworkIdList[i] = new URI(network);
+         } catch (URISyntaxException e) {
+             logger.error(e, "Failed to convert href '" + network + "' to URI. 
We expect a href to a network to be " +
+               "passed in, not a name for example.");
+            return null;
+         }
+         i++;
+      }
+
+      //iterate over the NetworkConnectionSection, and put them in order of 
their connection indices
+      // into the vAppTemplateNetworkList.
+      for (NetworkConnection netCon: 
vmTemplate.getNetworkConnectionSection().getConnections()) {
+         vAppTemplateNetworkList[netCon.getNetworkConnectionIndex()] = netCon;
+      }
+
+      for (i = 0; i < vOptionsNetworkIdList.length; i++) {
+         URI parentNetwork = vOptionsNetworkIdList[i];
+         NetworkConnection networkConnectionParams = 
vAppTemplateNetworkList.length > i ? vAppTemplateNetworkList[i] : null;
+         //hook 'em up.
+
+         //use network name from vAppTemplate if possible
+         String networkName;
+         if (networkConnectionParams != null) {
+            networkName = networkConnectionParams.getNetwork();
+         } else {
+            networkName = "jclouds-net-" + String.valueOf(i);
+         }
 
-      // note that in VCD 1.5, the network name after instantiation will be 
the same as the parent
-      InstantiateVAppTemplateOptions options = addNetworkConfig(config);
+         Network n = new Network(networkName, null); // ignore description, 
not needed here.
+         VCloudTemplateOptions networkTemplateOptions = vOptions.clone(); 
//we'll modify bits here
+         networkTemplateOptions.parentNetwork(parentNetwork);
+
+         NetworkConfig config = 
networkConfigurationForNetworkAndOptions.apply(n, networkTemplateOptions);
+         // note that in VCD 1.5, the network name after instantiation will be 
the same as the parent
+         options.addNetworkConfig(config);
+         logger.debug("Connecting vApp network " + n.getName() + " to org 
network " + parentNetwork + ".");
+      }
 
       // TODO make disk size specifiable
       // disk((long) ((template.getHardware().getVolumes().get(0).getSize()) *
@@ -187,13 +257,6 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
 
 
 
-      String description = 
VCloudTemplateOptions.class.cast(template.getOptions()).getDescription();
-      if (description == null) {
-         Map<String, String> md = 
metadataAndTagsAsCommaDelimitedValue(template.getOptions());
-         description = Joiner.on('\n').withKeyValueSeparator("=").join(md);
-      }
-
-      options.description(description);
       options.deploy(false);
       options.powerOn(false);
 
@@ -245,37 +308,161 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
       return 
client.getVmApi().updateGuestCustomizationOfVm(guestConfiguration, 
vm.getHref());
    }
 
-   public void ensureVmHasAllocationModeOrPooled(VApp vApp, @Nullable 
IpAddressAllocationMode ipAllocationMode) {
+   public void ensureVmHasDesiredNetworkConnectionSettings(VApp vApp, 
VCloudTemplateOptions vOptions) {
       Network networkToConnect = find(vApp.getNetworkSection().getNetworks(), 
not(networkWithNoIpAllocation));
 
       Vm vm = get(vApp.getChildren(), 0);
 
-      NetworkConnectionSection net = vm.getNetworkConnectionSection();
-      checkArgument(net.getConnections().size() > 0, "no connections on vm 
%s", vm);
-
-      NetworkConnection toConnect = findWithPoolAllocationOrFirst(net);
+      NetworkConnectionSection nets = vm.getNetworkConnectionSection();
+      checkArgument(nets.getConnections().size() > 0, "no connections on vm 
%s", vm);
+
+      /*
+       * Here we want to build the NetworkConnectionSection.
+       * This is not required if:
+       * - the user didn't pass in any vCloud specific NetworkConnection 
settings, and
+       * - there exist enough NetworkConnectionSections to cover the networks 
we need to
+       *   wire up to the VM
+       *
+       * In case of modifying the existing network connection, its important 
that
+       * those optional parameters whose value is not being changed needs to 
be returned
+       * with the existing values or vcloud puts default values for them. When 
mac address is not
+       * modified then it needs to be returned else vclouds changes the 
adapter type of the NIC to E1000.
+       *
+       * There are a couple of things that might require changes:
+       * - different parameters (e.g. ip address allocation mode)
+       * - insufficient NetworkConnection items (we need to add more to 
trigger the
+       *   creation of more NICs)
+       * - if the user didn't pass in any vCloud specific NetworkConnections, 
we might need to
+       *   create new ones here.
+       * It's easier to just unconditionally rewrite the network connection 
section,
+       * than to write some bug-prone code that checks all of the above 
conditions.
+       */
+
+      /*
+       * We also need to add NICs. If we don't do this, we'll get new NICs, 
but they'll all be E1000s.
+       * We really want to replicate the type of any existing adapters.
+       *
+       * We add the NICs only when it is needed. In case of vapp template 
having vm with multiple NICs
+       * and if we update only the existing NICs then vcloud throws error that 
primary NIC not found.
+       */
+      Set<? extends ResourceAllocationSettingData> allVirtualHWItems = 
vm.getVirtualHardwareSection().getItems();
+      Iterable<VCloudNetworkAdapter> existingNics = 
Iterables.filter(allVirtualHWItems, VCloudNetworkAdapter.class);
+      // we want to program all existing nics.
+      ArrayList<VCloudNetworkAdapter> nicsToProgram = 
Lists.newArrayList(existingNics);
+
+      //the first adapter type will be used as default for newly added ones.
+      String firstAdapterType = "E1000";
+      int nextInstanceID = 1;
+      if (nicsToProgram.size() >= 1) {
+         firstAdapterType = nicsToProgram.get(0).getResourceSubType();
+         nextInstanceID = 1 + 
Integer.valueOf(nicsToProgram.get(nicsToProgram.size() - 1).getInstanceID());
+      }
 
-      if (ipAllocationMode == null)
-         ipAllocationMode = toConnect.getIpAddressAllocationMode();
+      int i = 0;
+      LinkedHashSet<NetworkConnection> connectionsToProgram = new 
LinkedHashSet<NetworkConnection>();
+      for (String netUuid: vOptions.getNetworks()) {
+         NetworkConnection desiredNC = 
vOptions.getNetworkConnections().get(netUuid);
+         String netName;
+         String macAddr;
+         NetworkConnection vappNC = findNetworkConnectionByIndexOrNull(nets, 
i);
+         if (vappNC != null && vappNC.getNetwork() != null) {
+            netName = vappNC.getNetwork();
+         } else {
+            netName = null;
+         }
 
-      // make sure that we are in fact allocating ips
-      if (ipAllocationMode == IpAddressAllocationMode.NONE)
-         ipAllocationMode = IpAddressAllocationMode.POOL;
+         if (vappNC != null && vappNC.getMACAddress() != null) {
+            macAddr = vappNC.getMACAddress();
+         } else {
+            macAddr = null;
+         }
 
-      if (toConnect.isConnected() && toConnect.getIpAddressAllocationMode() == 
ipAllocationMode
-               && toConnect.getNetwork().equals(networkToConnect.getName())) {
-         // then we don't need to change the network settings, and can save a 
call
-      } else {
-         Builder builder = net.toBuilder();
-         
builder.connections(ImmutableSet.of(toConnect.toBuilder().network(networkToConnect.getName()).connected(true)
-                  .ipAddressAllocationMode(ipAllocationMode).build()));
-         logger.trace(">> updating networkConnection vm(%s)", vm.getName());
+         if (desiredNC != null
+             && desiredNC.getNetworkConnectionIndex() != i) {
+            logger.error("Data consistency error: the network '" + netUuid + 
"'s connection index has been specified "
+               + "in the vCloud specific NetworkConnection settings in 
VCloudTemplateOptions.networkConnections, but "
+               + "the connection index does not match the "
+               + "position of the network in the TemplateOptions.networks 
object. Ignoring vCloud specific options for this net.");
+            desiredNC = null;
+         }
+         /*
+              Its not yet clear why the mac address in desiredNC is null. This 
needs to be explored.
+              This special handling is needed as the mac address is null and 
if it is not set, it results in NIC
+              type as E1000
+          */
+         if (desiredNC != null && macAddr != null && desiredNC.getMACAddress() 
== null){
+            NetworkConnection.Builder desiredNCBuilder = desiredNC.toBuilder();
+            desiredNCBuilder.MACAddress(macAddr);
+            desiredNC = desiredNCBuilder.build();
+         }
+         if (desiredNC != null && desiredNC.getIpAddressAllocationMode() == 
null
+            || desiredNC.getIpAddressAllocationMode() == 
IpAddressAllocationMode.NONE) {
+            logger.error("Data consistency error: the network '" + netUuid + 
"'s IP address allocation mode"
+               + "has been set to 'none' or null in the vCloud specific 
NetworkConnection settings in VCloudTemplateOptions.networkConnections. "
+               + "This is invalid. Ignoring vCloud specific options for this 
net.");
+            desiredNC = null;
+         }
 
-         
waitForTask(client.getVmApi().updateNetworkConnectionOfVm(builder.build(), 
vm.getHref()));
-         logger.trace("<< updated networkConnection vm(%s)", vm.getName());
+          NetworkConnection ncToAdd = null;
+          if (desiredNC == null) {
+            // use default settings
+            ncToAdd = new NetworkConnection(netName, i, null, null, true, null,
+               IpAddressAllocationMode.POOL);
+         } else {
+            if (netName != null && !netName.equals(desiredNC.getNetwork())) {
+               //something's probably wrong.
+               logger.warn("vcloud overridden network name '" + 
desiredNC.getNetwork() + "' doesn't match the vApp's "
+                  + " network with index " + i + " name '" + netName + "'");
+            }
+
+            if (netName == null && desiredNC.getNetwork() == null) {
+               //ok we need to come up with some network name.
+               netName = "jclouds-net-" + String.valueOf(i);
+               NetworkConnection.Builder ncBuilder = desiredNC.toBuilder();
+               ncToAdd = 
ncBuilder.network(netName).connected(desiredNC.isConnected())
+                  .externalIpAddress(desiredNC.getExternalIpAddress())
+                  
.ipAddress(desiredNC.getIpAddress()).ipAddressAllocationMode(desiredNC.getIpAddressAllocationMode())
+                  
.MACAddress(desiredNC.getMACAddress()).networkConnectionIndex(desiredNC.getNetworkConnectionIndex()).build();
+            } else {
+               ncToAdd = desiredNC;
+            }
+         }
+         connectionsToProgram.add(ncToAdd);
+
+         //OK, we've now setup the network connection. Now we want to check if 
we need to add a new NIC for it.
+         if (nicsToProgram.size() < connectionsToProgram.size()) {
+            VCloudNetworkAdapter.Builder nicBuilder = 
VCloudNetworkAdapter.builder();
+            //interesting values
+            nicBuilder.addressOnParent(String.valueOf(i));
+            nicBuilder.automaticAllocation(true);
+            nicBuilder.connection(ncToAdd.getNetwork());
+            
nicBuilder.ipAddressingMode(ncToAdd.getIpAddressAllocationMode().toString());
+            nicBuilder.elementName("Network adapter " + String.valueOf(i));
+            nicBuilder.instanceID(String.valueOf(nextInstanceID));
+            nextInstanceID += 1;
+            nicBuilder.resourceSubType(firstAdapterType);
+            
nicBuilder.resourceType(ResourceAllocationSettingData.ResourceType.ETHERNET_ADAPTER);
+
+            VCloudNetworkAdapter newNic = nicBuilder.build();
+            nicsToProgram.add(newNic);
+         }
+         i++;
+      }
 
+      // Add new nics only if they are needed
+      if (nicsToProgram.size() < connectionsToProgram.size()) {
+         logger.debug("Programming NICs: %s", nicsToProgram);
+         Task t = client.getVmApi().updateNetworkCardsOfVm(nicsToProgram, 
vm.getHref());
+         waitForTask(t);
       }
 
+      // update the NetworkConnectionSection.
+      Builder builder = nets.toBuilder();
+      builder.connections(connectionsToProgram);
+      logger.trace(">> updating networkConnection vm(%s)", vm.getName());
+      logger.debug("New NetworkConnectionSection for VM %s: %s", vm.getName(), 
builder.build().toString());
+      
waitForTask(client.getVmApi().updateNetworkConnectionOfVm(builder.build(), 
vm.getHref()));
+      logger.trace("<< updated networkConnection vm(%s)", vm.getName());
    }
 
    private NetworkConnection 
findWithPoolAllocationOrFirst(NetworkConnectionSection net) {
@@ -289,6 +476,17 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
       }, get(net.getConnections(), 0));
    }
 
+    private NetworkConnection 
findNetworkConnectionByIndexOrNull(NetworkConnectionSection net, final int 
index) {
+        return find(net.getConnections(), new Predicate<NetworkConnection>() {
+
+            @Override
+            public boolean apply(NetworkConnection input) {
+                return input.getNetworkConnectionIndex() == index;
+            }
+
+        }, null);
+    }
+
    public Task updateCPUCountOfVm(Vm vm, int cpuCount) {
       return client.getVmApi().updateCPUCountOfVm(cpuCount, vm.getHref());
    }

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/domain/DiskAttachOrDetachParams.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/domain/DiskAttachOrDetachParams.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/domain/DiskAttachOrDetachParams.java
new file mode 100644
index 0000000..f3403d9
--- /dev/null
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/domain/DiskAttachOrDetachParams.java
@@ -0,0 +1,173 @@
+/*
+ * 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 org.jclouds.vcloud.domain;
+
+import java.net.URI;
+
+/**
+ * The DiskAttachOrDetachParams element forms the body of a disk attach/detach 
request
+ * see 
http://pubs.vmware.com/vchs/index.jsp?topic=%2Fcom.vmware.vcloud.api.reference.doc_56%2Fdoc%2Ftypes%2FDiskAttachOrDetachParamsType.html
+ */
+public class DiskAttachOrDetachParams {
+    protected final URI href;
+    protected final String type;
+    protected final String id;
+    protected final String name;
+    protected final Integer BusNumber;
+    protected final Integer UnitNumber;
+
+    /**
+     * "application/vnd.vmware.vcloud.disk+xml"
+     */
+    //TODO: is this the right place?
+    public static final String DISK_XML = 
"application/vnd.vmware.vcloud.disk+xml";
+
+    public DiskAttachOrDetachParams(URI href) {
+        this.href = href;
+        this.type = DISK_XML;
+        this.id = null;
+        this.name = null;
+        this.BusNumber = null;
+        this.UnitNumber = null;
+    }
+
+    public DiskAttachOrDetachParams(URI href, String name,
+                                    String id, Integer BusNumber, Integer 
UnitNumber) {
+        this.href = href;
+        this.type = DISK_XML;
+        this.id = id;
+        this.name = name;
+        this.BusNumber = BusNumber;
+        this.UnitNumber = UnitNumber;
+    }
+
+    /**
+     * get href
+     * @return href
+     */
+    public URI getHref() {
+        return href;
+    }
+
+    /**
+     * get type
+     * @return type
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * get id
+     * @return id
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * get name
+     * @return name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * get bus nr
+     * @return bus nr
+     */
+    public Integer getBusNumber() {
+        return BusNumber;
+    }
+
+    /**
+     * get unit number
+     * @return unit number
+     */
+    public Integer getUnitNumber() {
+        return UnitNumber;
+    }
+
+    @Override
+    public String toString() {
+        return "[href=" + getHref() + ", type=" + getType() + ", id=" + 
getId() + ", name=" + getName()
+                + ", BusNumber=" + getBusNumber() + ", UnitNumber=" + 
getUnitNumber() + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        int prime = 31;
+        int result = 1;
+        result = prime * result + ((href == null) ? 0 : href.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        result = prime * result + ((id == null) ? 0 : id.hashCode());
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((BusNumber == null) ? 0 : 
BusNumber.hashCode());
+        result = prime * result + ((UnitNumber == null) ? 0 : 
UnitNumber.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        DiskAttachOrDetachParams other = (DiskAttachOrDetachParams)obj;
+
+        if (href == null) {
+            if (other.href != null)
+                return false;
+        } else if (!href.equals(other.href)) {
+            return false;
+        }
+        if (type == null) {
+            if (other.type != null)
+                return false;
+        } else if (!type.equals(other.type)) {
+            return false;
+        }
+        if (id == null) {
+            if (other.id != null)
+                return false;
+        } else if (!id.equals(other.id)) {
+            return false;
+        }
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (BusNumber == null) {
+            if (other.BusNumber != null)
+                return false;
+        } else if (!BusNumber.equals(other.BusNumber)) {
+            return false;
+        }
+        if (UnitNumber == null) {
+            if (other.UnitNumber != null)
+                return false;
+        } else if (!UnitNumber.equals(other.UnitNumber)) {
+            return false;
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/features/VmApi.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/features/VmApi.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/features/VmApi.java
index 8aa186e..40b7e43 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/features/VmApi.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/features/VmApi.java
@@ -20,6 +20,7 @@ import static 
org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML;
 import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML;
 import static org.jclouds.vcloud.VCloudMediaType.NETWORKCONNECTIONSECTION_XML;
 import static org.jclouds.vcloud.VCloudMediaType.RASDITEM_XML;
+import static org.jclouds.vcloud.VCloudMediaType.RASDITEMLIST_XML;
 import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
 import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML;
 import static org.jclouds.vcloud.VCloudMediaType.VM_XML;
@@ -35,23 +36,10 @@ import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 
 import org.jclouds.Fallbacks;
-import org.jclouds.rest.annotations.BinderParam;
-import org.jclouds.rest.annotations.EndpointParam;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.PayloadParams;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.XMLResponseParser;
-import org.jclouds.vcloud.binders.BindCPUCountToXmlPayload;
-import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload;
-import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload;
-import org.jclouds.vcloud.binders.BindMemoryToXmlPayload;
-import org.jclouds.vcloud.binders.BindNetworkConnectionSectionToXmlPayload;
-import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload;
-import org.jclouds.vcloud.domain.GuestCustomizationSection;
-import org.jclouds.vcloud.domain.NetworkConnectionSection;
-import org.jclouds.vcloud.domain.Task;
-import org.jclouds.vcloud.domain.Vm;
+import org.jclouds.rest.annotations.*;
+import org.jclouds.vcloud.binders.*;
+import org.jclouds.vcloud.domain.*;
+import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
 import org.jclouds.vcloud.filters.AddVCloudAuthorizationAndCookieToRequest;
 import org.jclouds.vcloud.xml.TaskHandler;
 import org.jclouds.vcloud.xml.VmHandler;
@@ -60,6 +48,8 @@ import org.jclouds.vcloud.xml.VmHandler;
 /**
  * Provides access to VM functionality in vCloud
  * <p/>
+ * 
+ * @author Adrian Cole
  */
 @RequestFilters(AddVCloudAuthorizationAndCookieToRequest.class)
 public interface VmApi {
@@ -161,6 +151,32 @@ public interface VmApi {
    @XMLResponseParser(TaskHandler.class)
    Task powerOffVm(@EndpointParam URI href);
 
+    /**
+     * Detach disk
+     */
+    @POST
+    @Consumes(TASK_XML)
+    @Produces(DiskAttachOrDetachParams.DISK_XML)
+    @Path("/disk/action/detach")
+    @MapBinder(BindDiskAttachOrDetachParamsToXmlPayload.class)
+    @XMLResponseParser(TaskHandler.class)
+    Task detachDisk(
+            @EndpointParam URI href,
+            @PayloadParam("params") DiskAttachOrDetachParams 
diskAttachOrDetachParams);
+
+    /**
+     * Attach disk
+     */
+    @POST
+    @Consumes(TASK_XML)
+    @Produces("application/vnd.vmware.vcloud.diskAttachOrDetachParams+xml")
+    @Path("/disk/action/attach")
+    @MapBinder(BindDiskAttachOrDetachParamsToXmlPayload.class)
+    @XMLResponseParser(TaskHandler.class)
+    Task attachDisk(
+            @EndpointParam URI href,
+            @PayloadParam("params") DiskAttachOrDetachParams 
diskAttachOrDetachParams);
+
    /**
     * A shutdown request to a vApp URL shuts down all of the virtual machines 
in the vApp, as
     * specified in its StartupSection field.
@@ -290,4 +306,21 @@ public interface VmApi {
    @XMLResponseParser(TaskHandler.class)
    Task updateMemoryMBOfVm(@BinderParam(BindMemoryToXmlPayload.class) int 
memoryInMB,
                                              @EndpointParam URI href);
+
+   /**
+    * update the networkCards of an existing VM
+    *
+    * @param href
+    *           to update
+    * @param networkCards
+    *           new list of Network Interface Cards (NICs)
+    */
+   @PUT
+   @Consumes(TASK_XML)
+   @Produces(RASDITEMLIST_XML)
+   @Path("/virtualHardwareSection/networkCards")
+   @MapBinder(BindVCloudNetworkAdapterToXmlPayload.class)
+   @XMLResponseParser(TaskHandler.class)
+   Task updateNetworkCardsOfVm(@PayloadParam("params") 
Iterable<VCloudNetworkAdapter> networkCards,
+                               @EndpointParam URI href);
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/xml/OrgNetworkHandler.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/xml/OrgNetworkHandler.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/xml/OrgNetworkHandler.java
index 521f086..bd0a4d1 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/xml/OrgNetworkHandler.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/main/java/org/jclouds/vcloud/xml/OrgNetworkHandler.java
@@ -251,7 +251,7 @@ public class OrgNetworkHandler extends 
ParseSax.HandlerWithResult<OrgNetwork> {
          natType = NatType.fromValue(currentOrNull());
       } else if (SaxUtils.equalsOrSuffix(qName, "MappingMode")) {
          mappingMode = MappingMode.fromValue(currentOrNull());
-      } else if (qName.equalsIgnoreCase("ExternalIP")) {
+      } else if (qName.equalsIgnoreCase("ExternalIPAddress")) {
          externalIP = currentOrNull();
       } else if (qName.equalsIgnoreCase("VAppScopedVmId")) {
          vAppScopedVmId = currentOrNull();
@@ -267,7 +267,7 @@ public class OrgNetworkHandler extends 
ParseSax.HandlerWithResult<OrgNetwork> {
          this.vmNicId = -1;
       } else if (qName.equalsIgnoreCase("ExternalPort")) {
          externalPort = Integer.parseInt(currentOrNull());
-      } else if (qName.equalsIgnoreCase("InternalIP")) {
+      } else if (qName.equalsIgnoreCase("InternalIPAddress")) {
          internalIP = currentOrNull();
       } else if (qName.equalsIgnoreCase("InternalPort")) {
          internalPort = Integer.parseInt(currentOrNull());

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java
index 4677835..f43a0e9 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/options/VCloudTemplateOptionsTest.java
@@ -20,15 +20,17 @@ import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.b
 import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.customizationScript;
 import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.description;
 import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.inboundPorts;
-import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.ipAddressAllocationMode;
 import static 
org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.parentNetwork;
 import static org.testng.Assert.assertEquals;
 
 import java.io.IOException;
 import java.net.URI;
+import java.util.Hashtable;
 
 import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.vcloud.domain.NetworkConnection;
 import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
+import org.jclouds.vcloud.endpoints.Network;
 import org.testng.annotations.Test;
 
 /**
@@ -37,16 +39,14 @@ import org.testng.annotations.Test;
  */
 public class VCloudTemplateOptionsTest {
    @Test
-   public void testipAddressAllocationMode() {
+   public void testnetworkConnections() {
       VCloudTemplateOptions options = new VCloudTemplateOptions();
-      options.ipAddressAllocationMode(IpAddressAllocationMode.NONE);
-      assertEquals(options.getIpAddressAllocationMode(), 
IpAddressAllocationMode.NONE);
-   }
-
-   @Test
-   public void testipAddressAllocationModeStatic() {
-      VCloudTemplateOptions options = 
ipAddressAllocationMode(IpAddressAllocationMode.NONE);
-      assertEquals(options.getIpAddressAllocationMode(), 
IpAddressAllocationMode.NONE);
+      String netUuid = 
"https://myfunvcloud.com/api/admin/network/aaaabbbb-cccc-1122-3344-1234567890ab";;
+      Hashtable<String, NetworkConnection> nets = new Hashtable<String, 
NetworkConnection>(1);
+      NetworkConnection nc = new NetworkConnection(netUuid, 0, null, null, 
true, null, IpAddressAllocationMode.POOL);
+      nets.put(netUuid, nc);
+      options.networkConnections(nets);
+      assertEquals(options.getNetworkConnections().get(netUuid), nc);
    }
 
    public void testAs() {

http://git-wip-us.apache.org/repos/asf/stratos/blob/ed952ac3/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest.java
----------------------------------------------------------------------
diff --git 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest.java
 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest.java
index 2608021..2050e3f 100644
--- 
a/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest.java
+++ 
b/dependencies/jclouds/apis/vcloud/1.8.1-stratos/src/test/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest.java
@@ -113,11 +113,11 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
    
    public void 
testInstantiateVAppFromTemplateWhenUsingOverriddenNetworkAndFenceMode()
          throws Exception {
-   
+
       String name = "group-abcd";
       FenceMode fenceMode = FenceMode.NAT_ROUTED;
       URI parentNetwork = URI.create(ENDPOINT + "/v1.0/network/" + 
"foooooooo");
-   
+
       String instantiateXML = 
XMLBuilder.create("InstantiateVAppTemplateParams")
                                            .a("xmlns", ns).a("xmlns:ovf", 
"http://schemas.dmtf.org/ovf/envelope/1";)
                                            .a("deploy", "false").a("name", 
name).a("powerOn", "false")
@@ -136,14 +136,14 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
                                         .e("Source").a("href", ENDPOINT + 
"/v1.0/vAppTemplate/" + templateId).up()
                                         .e("AllEULAsAccepted").t("true").up()
                                         .asString(outputProperties);
-     
+
       HttpRequest version1_0InstantiateWithCustomizedNetwork = 
HttpRequest.builder().method("POST")
                                                                           
.endpoint(ENDPOINT + "/v1.0/vdc/" + vdcId + "/action/instantiateVAppTemplate")
                                                                           
.addHeader(HttpHeaders.ACCEPT, 
"application/vnd.vmware.vcloud.vApp+xml;version=1.0")
                                                                           
.addHeader("x-vcloud-authorization", sessionToken)
                                                                           
.addHeader(HttpHeaders.COOKIE, "vcloud-token=" + sessionToken)
                                                                           
.payload(payloadFromStringWithContentType(instantiateXML, 
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml")).build();
-                                                                        
+
       ComputeService compute = 
requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> builder()
               .put(versionsRequest, versionsResponseFromVCD1_5)
               .put(version1_0LoginRequest, 
successfulVersion1_0LoginResponseFromVCD1_5WithSingleOrg)
@@ -154,13 +154,15 @@ public class 
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
               .put(version1_0GetVAppTemplateRequest, 
successfulVersion1_0GetVAppTemplateResponseFromVCD1_5WithSingleVMAndVDCParent)
               .put(version1_0GetOVFForVAppTemplateRequest, 
successfulVersion1_0GetOVFForVAppTemplateResponseFromVCD1_5WithSingleVM)
               .put(version1_0InstantiateWithCustomizedNetwork, 
successfulVersion1_0InstantiatedVApp).build());
-   
+
       
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn 
starter = compute.getContext()
                .utils().injector().getInstance(
                         
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.class);
 
       Template template = compute.templateBuilder().build();
-      
template.getOptions().as(VCloudTemplateOptions.class).parentNetwork(parentNetwork).fenceMode(fenceMode);
+      String[] netlist = new String[1];
+      netlist[0] = parentNetwork.toASCIIString();
+      
template.getOptions().as(VCloudTemplateOptions.class).fenceMode(fenceMode).networks(netlist);
       starter.instantiateVAppFromTemplate(name, template);
 
    }

Reply via email to