Issue 1019:add VCloudTemplateOptions.parentNetwork, bridgeMode

This commit is contained in:
Adrian Cole 2012-07-11 19:16:25 -07:00
parent 07fa5528ca
commit 65b9955abe
6 changed files with 395 additions and 140 deletions

View File

@ -18,11 +18,19 @@
*/
package org.jclouds.vcloud.compute.options;
import static com.google.common.base.Objects.equal;
import java.net.URI;
import java.util.Map;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.util.Preconditions2;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/**
* Contains options supported in the {@code ComputeService#runNode} operation on
@ -60,14 +68,45 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
eTo.description(getDescription());
if (getIpAddressAllocationMode() != null)
eTo.ipAddressAllocationMode(getIpAddressAllocationMode());
if (getIpAddressAllocationMode() != null)
eTo.ipAddressAllocationMode(getIpAddressAllocationMode());
if (getParentNetwork() != null)
eTo.parentNetwork(getParentNetwork());
if (getFenceMode() != null)
eTo.fenceMode(getFenceMode());
}
}
private String description = null;
private String customizationScript = null;
private IpAddressAllocationMode ipAddressAllocationMode = null;
private URI parentNetwork = null;
private FenceMode fenceMode = null;
public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions();
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
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.parentNetwork, that.parentNetwork);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), description, customizationScript, ipAddressAllocationMode,
parentNetwork);
}
@Override
public ToStringHelper string() {
return super.string().add("description", description).add("customizationScript", customizationScript)
.add("ipAddressAllocationMode", ipAddressAllocationMode).add("parentNetwork", parentNetwork);
}
/**
* Optional description. Used for the Description of the vApp created by this
@ -96,29 +135,61 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
return this;
}
/**
* Specifies the parentNetwork to connect the the network interfaces on the
* VMs to.
*
* @see InstantiateVAppTemplateOptions#addNetworkConfig
*/
public VCloudTemplateOptions parentNetwork(URI parentNetwork) {
this.parentNetwork = parentNetwork;
return this;
}
/**
* How to connect to the parent network
*
* @see InstantiateVAppTemplateOptions#addNetworkConfig
*/
public VCloudTemplateOptions fenceMode(FenceMode fenceMode) {
this.fenceMode = fenceMode;
return this;
}
public static class Builder {
/**
* @see VCloudTemplateOptions#description
*/
public static VCloudTemplateOptions description(String description) {
VCloudTemplateOptions options = new VCloudTemplateOptions();
return VCloudTemplateOptions.class.cast(options.description(description));
return new VCloudTemplateOptions().description(description);
}
/**
* @see VCloudTemplateOptions#customizationScript
*/
public static VCloudTemplateOptions customizationScript(String customizationScript) {
VCloudTemplateOptions options = new VCloudTemplateOptions();
return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript));
return new VCloudTemplateOptions().customizationScript(customizationScript);
}
/**
* @see VCloudTemplateOptions#ipAddressAllocationMode
*/
public static VCloudTemplateOptions ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
VCloudTemplateOptions options = new VCloudTemplateOptions();
return VCloudTemplateOptions.class.cast(options.ipAddressAllocationMode(ipAddressAllocationMode));
return new VCloudTemplateOptions().ipAddressAllocationMode(ipAddressAllocationMode);
}
/**
* @see VCloudTemplateOptions#parentNetwork(URI parentNetwork)
*/
public static VCloudTemplateOptions parentNetwork(URI parentNetwork) {
return new VCloudTemplateOptions().parentNetwork(parentNetwork);
}
/**
* @see VCloudTemplateOptions#fenceMode(FenceMode)
*/
public static VCloudTemplateOptions fenceMode(FenceMode fenceMode) {
return new VCloudTemplateOptions().fenceMode(fenceMode);
}
// methods that only facilitate returning the correct object type
@ -177,6 +248,20 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
return ipAddressAllocationMode;
}
/**
* @return parentNetwork to connect to the vms
*/
public URI getParentNetwork() {
return parentNetwork;
}
/**
* @return FenceMode to connect the parent network with
*/
public FenceMode getFenceMode() {
return fenceMode;
}
// methods that only facilitate returning the correct object type
/**
@ -233,47 +318,4 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
return VCloudTemplateOptions.class.cast(super.userMetadata(key, value));
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((ipAddressAllocationMode == null) ? 0 : ipAddressAllocationMode.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
VCloudTemplateOptions other = (VCloudTemplateOptions) obj;
if (customizationScript == null) {
if (other.customizationScript != null)
return false;
} else if (!customizationScript.equals(other.customizationScript))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (ipAddressAllocationMode != other.ipAddressAllocationMode)
return false;
return true;
}
@Override
public String toString() {
return "[customizationScript=" + (customizationScript != null) + ", description=" + description
+ ", ipAddressAllocationMode=" + ipAddressAllocationMode + ", inboundPorts="
+ inboundPorts + ", privateKey=" + (privateKey != null) + ", publicKey="
+ (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds
+ ", userMetadata: " + userMetadata + "]";
}
}

View File

@ -47,17 +47,17 @@ 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.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.NetworkConnectionSection.Builder;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.jclouds.vcloud.domain.network.NetworkConfig;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
@ -73,32 +73,21 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
protected final VCloudClient client;
protected final Predicate<URI> successTester;
protected final LoadingCache<URI, VAppTemplate> vAppTemplates;
protected final Supplier<NetworkConfig> defaultNetworkConfig;
protected final NetworkConfigurationForNetworkAndOptions networkConfigurationForNetworkAndOptions;
protected final String buildVersion;
@Inject
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(VCloudClient client,
Predicate<URI> successTester, LoadingCache<URI, VAppTemplate> vAppTemplates,
Supplier<NetworkConfig> defaultNetworkConfig, @BuildVersion String buildVersion) {
Predicate<URI> successTester, LoadingCache<URI, VAppTemplate> vAppTemplates, NetworkConfigurationForNetworkAndOptions networkConfigurationForNetworkAndOptions,
@BuildVersion String buildVersion) {
this.client = client;
this.successTester = successTester;
this.vAppTemplates = vAppTemplates;
this.defaultNetworkConfig = defaultNetworkConfig;
this.networkConfigurationForNetworkAndOptions = networkConfigurationForNetworkAndOptions;
this.buildVersion = buildVersion;
}
// TODO: filtering on "none" is a hack until we can filter on
// vAppTemplate.getNetworkConfigSection().getNetworkConfigs() where
// name = getChildren().NetworkConnectionSection.connection where ipallocationmode == none
Predicate<Network> networkWithNoIpAllocation = new Predicate<Network>() {
@Override
public boolean apply(Network input) {
return "none".equals(input.getName());
}
};
/**
* per john ellis at bluelock, vCloud Director 1.5 is more strict than earlier versions.
* <p/>
@ -124,54 +113,7 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
public NodeAndInitialCredentials<VApp> createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
// no sense waiting until failures occur later
ComputerNameValidator.INSTANCE.validate(name);
URI templateId = URI.create(template.getImage().getId());
VAppTemplate vAppTemplate = vAppTemplates.getUnchecked(templateId);
if (vAppTemplate.getChildren().size() > 1)
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);
Network networkToConnect = get(vAppTemplate.getNetworkSection().getNetworks(), 0);
NetworkConfig config;
// if we only have a disconnected network, let's add a new section for the upstream
// TODO: remove the disconnected entry
if (networkWithNoIpAllocation.apply(networkToConnect))
config = defaultNetworkConfig.get();
else
config = defaultNetworkConfig.get().toBuilder().networkName(networkToConnect.getName()).build();
// note that in VCD 1.5, the network name after instantiation will be the same as the parent
InstantiateVAppTemplateOptions options = addNetworkConfig(config);
// TODO make disk size specifiable
// disk((long) ((template.getHardware().getVolumes().get(0).getSize()) *
// 1024 * 1024l));
String customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript();
IpAddressAllocationMode ipAllocationMode = VCloudTemplateOptions.class.cast(template.getOptions())
.getIpAddressAllocationMode();
String description = VCloudTemplateOptions.class.cast(template.getOptions()).getDescription();
if (description == null)
description = vAppTemplate.getName();
options.description(description);
options.deploy(false);
options.powerOn(false);
URI VDC = URI.create(template.getLocation().getId());
logger.debug(">> instantiating vApp vDC(%s) template(%s) name(%s) options(%s) ", VDC, templateId, name, options);
VApp vAppResponse = client.getVAppTemplateClient().createVAppInVDCByInstantiatingTemplate(name, VDC, templateId,
options);
VApp vAppResponse = instantiateVAppFromTemplate(name, template);
waitForTask(vAppResponse.getTasks().get(0));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getName());
@ -181,15 +123,17 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
// per above check, we know there is only a single VM
Vm vm = get(vAppResponse.getChildren(), 0);
VCloudTemplateOptions vOptions = VCloudTemplateOptions.class.cast(template.getOptions());
// note we cannot do tasks in parallel or VCD will throw "is busy" errors
// note we must do this before any other customizations as there is a dependency on
// valid naming conventions before you can perform commands such as updateCPUCount
logger.trace(">> updating customization vm(%s) name->(%s)", vm.getName(), name);
waitForTask(updateVmWithNameAndCustomizationScript(vm, name, customizationScript));
waitForTask(updateVmWithNameAndCustomizationScript(vm, name, vOptions.getCustomizationScript()));
logger.trace("<< updated customization vm(%s)", name);
ensureVmHasAllocationModeOrPooled(vAppResponse, ipAllocationMode);
ensureVmHasAllocationModeOrPooled(vAppResponse, vOptions.getIpAddressAllocationMode());
int cpuCount = new Double(getCores(template.getHardware())).intValue();
logger.trace(">> updating cpuCount(%d) vm(%s)", cpuCount, vm.getName());
@ -214,12 +158,70 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
}
@VisibleForTesting
protected VApp instantiateVAppFromTemplate(String name, Template template) {
VCloudTemplateOptions vOptions = VCloudTemplateOptions.class.cast(template.getOptions());
URI templateId = URI.create(template.getImage().getId());
VAppTemplate vAppTemplate = vAppTemplates.getUnchecked(templateId);
if (vAppTemplate.getChildren().size() > 1)
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);
Network networkToConnect = get(vAppTemplate.getNetworkSection().getNetworks(), 0);
NetworkConfig config = networkConfigurationForNetworkAndOptions.apply(networkToConnect, vOptions);
// note that in VCD 1.5, the network name after instantiation will be the same as the parent
InstantiateVAppTemplateOptions options = addNetworkConfig(config);
// TODO make disk size specifiable
// disk((long) ((template.getHardware().getVolumes().get(0).getSize()) *
// 1024 * 1024l));
String description = VCloudTemplateOptions.class.cast(template.getOptions()).getDescription();
if (description == null)
description = vAppTemplate.getName();
options.description(description);
options.deploy(false);
options.powerOn(false);
URI VDC = URI.create(template.getLocation().getId());
logger.debug(">> instantiating vApp vDC(%s) template(%s) name(%s) options(%s) ", VDC, templateId, name, options);
VApp vAppResponse = client.getVAppTemplateClient().createVAppInVDCByInstantiatingTemplate(name, VDC, templateId,
options);
return vAppResponse;
}
// TODO: filtering on "none" is a hack until we can filter on
// vAppTemplate.getNetworkConfigSection().getNetworkConfigs() where
// name = getChildren().NetworkConnectionSection.connection where ipallocationmode == none
static Predicate<Network> networkWithNoIpAllocation = new Predicate<Network>() {
@Override
public boolean apply(Network input) {
return "none".equals(input.getName());
}
};
public void waitForTask(Task task) {
if (!successTester.apply(task.getHref())) {
throw new TaskStillRunningException(task);
}
}
/**
* Naming constraints modifying a VM on a VApp in vCloud Director (at least v1.5) can be more
* strict than those in a vAppTemplate. For example, while it is possible to instantiate a

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.compute.strategy;
import java.net.URI;
import javax.inject.Inject;
import org.jclouds.ovf.Network;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.domain.network.NetworkConfig;
import com.google.common.annotations.Beta;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
@Beta
public class NetworkConfigurationForNetworkAndOptions {
protected final Supplier<NetworkConfig> defaultNetworkConfig;
protected final FenceMode defaultFenceMode;
@Inject
protected NetworkConfigurationForNetworkAndOptions(Supplier<NetworkConfig> defaultNetworkConfig,
FenceMode defaultFenceMode) {
this.defaultNetworkConfig = defaultNetworkConfig;
this.defaultFenceMode = defaultFenceMode;
}
/**
*
* returns a {@link NetworkConfig} used to instantiate a vAppTemplate to
* either the default parent (org) network, or one specified by options.
*
* @param networkToConnect
* network defined in the VAppTemplate you wish to connect to
* @param vOptions
* options to override defaults with
* @return
*/
public NetworkConfig apply(Network networkToConnect, VCloudTemplateOptions vOptions) {
NetworkConfig config;
URI userDefinedParentNetwork = vOptions.getParentNetwork();
FenceMode fenceMode = vOptions.getFenceMode() != null ? vOptions.getFenceMode() : defaultFenceMode;
if (userDefinedParentNetwork != null) {
config = NetworkConfig.builder().networkName("jclouds").fenceMode(fenceMode)
.parentNetwork(userDefinedParentNetwork).build();
} else {
config = defaultNetworkConfig.get().toBuilder().fenceMode(fenceMode).build();
}
// if we only have a disconnected network, we are adding a new section
// for the upstream
if (InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.networkWithNoIpAllocation
.apply(networkToConnect)) {
// TODO: remove the disconnected entry
} else {
config = config.toBuilder().networkName(networkToConnect.getName()).build();
}
return config;
}
}

View File

@ -23,9 +23,11 @@ import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.c
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 org.jclouds.compute.options.TemplateOptions;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
@ -81,6 +83,25 @@ public class VCloudTemplateOptionsTest {
assertEquals(options.getCustomizationScript(), "mykeypair");
}
@Test
public void testNullparentNetwork() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
assertEquals(options.getParentNetwork(), null);
}
@Test
public void testparentNetwork() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
options.parentNetwork(URI.create("https://network"));
assertEquals(options.getParentNetwork(), URI.create("https://network"));
}
@Test
public void testparentNetworkStatic() {
VCloudTemplateOptions options = parentNetwork(URI.create("https://network"));
assertEquals(options.getParentNetwork(), URI.create("https://network"));
}
@Test
public void testdescription() {
VCloudTemplateOptions options = new VCloudTemplateOptions();

View File

@ -20,16 +20,25 @@ package org.jclouds.vcloud.compute.strategy;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Properties;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.vcloud.compute.BaseVCloudComputeServiceExpectTest;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.net.HttpHeaders;
import com.jamesmurty.utils.XMLBuilder;
/**
*
@ -39,28 +48,68 @@ import com.google.common.collect.ImmutableMap;
public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest extends
BaseVCloudComputeServiceExpectTest {
// TODO: finish me
String ns = "http://www.vmware.com/vcloud/v1";
Properties outputProperties;
public InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest(){
outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
}
HttpResponse successfulVersion1_0InstantiatedVApp = HttpResponse.builder()
.statusCode(200)
.message("HTTP/1.1 200 OK")
.payload(payloadFromResourceWithContentType("/instantiatedvapp.xml", "application/vnd.vmware.vcloud.vApp+xml")).build();
// TODO: finish me!
@Test(enabled = false)
public void testCreateNodeUsingVCloud1_0ApiAgainstVCloudDirector1_5WhenVAppTemplateHasNetworkNamedNone()
throws Exception {
ComputeService compute = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse> builder().put(
versionsRequest, versionsResponseFromVCD1_5).put(version1_0LoginRequest,
successfulVersion1_0LoginResponseFromVCD1_5WithSingleOrg).put(version1_0GetOrgRequest,
successfulVersion1_0GetOrgResponseFromVCD1_5WithSingleTasksListVDCAndNetwork).put(
version1_0GetCatalogRequest, successfulVersion1_0GetCatalogResponseFromVCD1_5WithSingleTemplate).put(
version1_0GetCatalogItemRequest, successfulVersion1_0GetCatalogItemResponseFromVCD1_5ForTemplate).put(
version1_0GetVDCRequest, successfulVersion1_0GetVDCResponseFromVCD1_5WithSingleTemplateAndNetwork).put(
version1_0GetVAppTemplateRequest,
successfulVersion1_0GetVAppTemplateResponseFromVCD1_5WithSingleVMAndVDCParent).put(
version1_0GetOVFForVAppTemplateRequest,
successfulVersion1_0GetOVFForVAppTemplateResponseFromVCD1_5WithSingleVM).build());
String group = "group";
String name = "group-abcd";
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")
.e("Description").t("UbuntuServer-x64-2GB").up()
.e("InstantiationParams")
.e("NetworkConfigSection")
.e("ovf:Info").t("Configuration parameters for logical networks").up()
.e("NetworkConfig").a("networkName", "orgNet-jclouds-External") // NOTE not "None"
.e("Configuration")
.e("ParentNetwork").a("href", ENDPOINT + "/v1.0/network/" + networkId).up()
.e("FenceMode").t("bridged").up()
.up()
.up()
.up()
.up()
.e("Source").a("href", ENDPOINT + "/v1.0/vAppTemplate/" + templateId).up()
.e("AllEULAsAccepted").t("true").up()
.asString(outputProperties);
HttpRequest version1_0InstantiateWithNetworkNamedSameAsOrgNetwork = HttpRequest.builder()
.method("POST")
.endpoint(URI.create(ENDPOINT + "/v1.0/vdc/" + vdcId + "/action/instantiateVAppTemplate"))
.headers(ImmutableMultimap.<String, String> builder()
.put(HttpHeaders.ACCEPT, "application/vnd.vmware.vcloud.vApp+xml")
.put(HttpHeaders.COOKIE, "vcloud-token=" + sessionToken).build())
.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)
.put(version1_0GetOrgRequest, successfulVersion1_0GetOrgResponseFromVCD1_5WithSingleTasksListVDCAndNetwork)
.put(version1_0GetCatalogRequest, successfulVersion1_0GetCatalogResponseFromVCD1_5WithSingleTemplate)
.put(version1_0GetCatalogItemRequest, successfulVersion1_0GetCatalogItemResponseFromVCD1_5ForTemplate)
.put(version1_0GetVDCRequest, successfulVersion1_0GetVDCResponseFromVCD1_5WithSingleTemplateAndNetwork)
.put(version1_0GetVAppTemplateRequest, successfulVersion1_0GetVAppTemplateResponseFromVCD1_5WithSingleVMAndVDCParent)
.put(version1_0GetOVFForVAppTemplateRequest, successfulVersion1_0GetOVFForVAppTemplateResponseFromVCD1_5WithSingleVM)
.put(version1_0InstantiateWithNetworkNamedSameAsOrgNetwork, successfulVersion1_0InstantiatedVApp).build());
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn starter = compute.getContext()
.utils().injector().getInstance(
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.class);
String group = "group";
String name = "group-abcd";
NodeAndInitialCredentials<VApp> appAndCreds = starter.createNodeWithGroupEncodedIntoName(group, name, compute
.templateBuilder().build());
@ -69,4 +118,59 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
assertEquals(appAndCreds.getCredentials(), LoginCredentials.builder().user("root").password("fromVApp").build());
}
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")
.e("Description").t("UbuntuServer-x64-2GB").up()
.e("InstantiationParams")
.e("NetworkConfigSection")
.e("ovf:Info").t("Configuration parameters for logical networks").up()
.e("NetworkConfig").a("networkName", "jclouds") // NOTE not "None"
.e("Configuration")
.e("ParentNetwork").a("href", parentNetwork.toASCIIString()).up()
.e("FenceMode").t(fenceMode.toString()).up()
.up()
.up()
.up()
.up()
.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(URI.create(ENDPOINT + "/v1.0/vdc/" + vdcId + "/action/instantiateVAppTemplate"))
.headers(ImmutableMultimap.<String, String> builder()
.put(HttpHeaders.ACCEPT, "application/vnd.vmware.vcloud.vApp+xml")
.put(HttpHeaders.COOKIE, "vcloud-token=" + sessionToken).build())
.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)
.put(version1_0GetOrgRequest, successfulVersion1_0GetOrgResponseFromVCD1_5WithSingleTasksListVDCAndNetwork)
.put(version1_0GetCatalogRequest, successfulVersion1_0GetCatalogResponseFromVCD1_5WithSingleTemplate)
.put(version1_0GetCatalogItemRequest, successfulVersion1_0GetCatalogItemResponseFromVCD1_5ForTemplate)
.put(version1_0GetVDCRequest, successfulVersion1_0GetVDCResponseFromVCD1_5WithSingleTemplateAndNetwork)
.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);
starter.instantiateVAppFromTemplate(name, template);
}
}

View File

@ -1,9 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<VApp href="http://10.150.4.49/api/v0.8/vApp/10" type="application/vnd.vmware.vcloud.vApp+xml"
name="centos53" status="1"
size="123456789" xmlns="http://www.vmware.com/vcloud/v0.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Link rel="up"
href="http://10.150.4.49/api/v0.8/vdc/4"
type="application/vnd.vmware.vcloud.vdc+xml"/>
<VApp xmlns="http://www.vmware.com/vcloud/v1" deployed="false" status="0" name="vcds-a47" type="application/vnd.vmware.vcloud.vApp+xml" href="https://zone01.bluelock.com/api/v1.0/vApp/vapp-dba20113-1a4a-4ec9-a5ad-52dc69ee0825" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.vmware.com/vcloud/v1 http://zone01.bluelock.com/api/v1.0/schema/master.xsd">
<Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://zone01.bluelock.com/api/v1.0/vApp/vapp-dba20113-1a4a-4ec9-a5ad-52dc69ee0825/controlAccess/"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://zone01.bluelock.com/api/v1.0/vdc/9db4ee77-33e7-4b83-96be-eee9925eaa9b"/>
<Link rel="down" type="application/vnd.vmware.vcloud.owner+xml" href="https://zone01.bluelock.com/api/v1.0/vApp/vapp-dba20113-1a4a-4ec9-a5ad-52dc69ee0825/owner"/>
<Description>OS-Ubuntu10.04_x64</Description>
<Tasks>
<Task status="running" startTime="2012-07-11T20:37:49.521-04:00" operation="Creating Virtual Application vcds-a47(dba20113-1a4a-4ec9-a5ad-52dc69ee0825)" expiryTime="2012-08-25T20:37:49.521-04:00" type="application/vnd.vmware.vcloud.task+xml" href="https://zone01.bluelock.com/api/v1.0/task/fee48ffc-8ba2-452e-a57f-ada0cd2eda31">
<Link rel="task:cancel" href="https://zone01.bluelock.com/api/v1.0/task/fee48ffc-8ba2-452e-a57f-ada0cd2eda31/action/cancel"/>
<Owner type="application/vnd.vmware.vcloud.vApp+xml" name="vcds-a47" href="https://zone01.bluelock.com/api/v1.0/vApp/vapp-dba20113-1a4a-4ec9-a5ad-52dc69ee0825"/>
</Task>
</Tasks>
</VApp>