Issue 710: support vCloud Director 1.5 via vCloud 1.0 API

This commit is contained in:
Adrian Cole 2012-01-14 21:13:29 -08:00
parent 16a973c08c
commit 87ced325e1
35 changed files with 1015 additions and 363 deletions

View File

@ -0,0 +1,43 @@
/**
* 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;
import org.jclouds.vcloud.domain.Task;
/**
*
* @author Adrian Cole
*
*/
public class TaskInErrorStateException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Task task;
public TaskInErrorStateException(Task task) {
super("error on task: " + task + " error: " + task.getError());
this.task = task;
}
public Task getTask() {
return task;
}
}

View File

@ -0,0 +1,43 @@
/**
* 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;
import org.jclouds.vcloud.domain.Task;
/**
*
* @author Adrian Cole
*
*/
public class TaskStillRunningException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final Task task;
public TaskStillRunningException(Task task) {
super("task still running: " + task);
this.task = task;
}
public Task getTask() {
return task;
}
}

View File

@ -21,7 +21,7 @@ package org.jclouds.vcloud.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_FENCEMODE;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
@ -30,8 +30,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.xml.parsers.FactoryConfigurationError;
@ -39,11 +38,10 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.Vm;
@ -54,10 +52,8 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.jamesmurty.utils.XMLBuilder;
/**
@ -73,21 +69,21 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
protected final BindToStringPayload stringBinder;
protected final ReferenceType defaultNetwork;
protected final FenceMode defaultFenceMode;
protected final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate;
protected final VCloudClient client;
protected final LoadingCache<URI, VAppTemplate> templateCache;
protected final Function<VAppTemplate, String> defaultNetworkNameInTemplate;
@Inject
public BindInstantiateVAppTemplateParamsToXmlPayload(DefaultNetworkNameInTemplate defaultNetworkNameInTemplate,
BindToStringPayload stringBinder, @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns,
@Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema, @Network ReferenceType network,
@Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode, VCloudClient client) {
public BindInstantiateVAppTemplateParamsToXmlPayload(LoadingCache<URI, VAppTemplate> templateCache,
@Network Function<VAppTemplate, String> defaultNetworkNameInTemplate, BindToStringPayload stringBinder,
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema,
@Network ReferenceType network, FenceMode fenceMode) {
this.templateCache = templateCache;
this.defaultNetworkNameInTemplate = defaultNetworkNameInTemplate;
this.ns = ns;
this.schema = schema;
this.stringBinder = stringBinder;
this.defaultNetwork = network;
this.defaultFenceMode = FenceMode.fromValue(fenceMode);
this.client = client;
this.defaultFenceMode = fenceMode;
}
@Override
@ -97,33 +93,29 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
GeneratedHttpRequest<?> gRequest = (GeneratedHttpRequest<?>) request;
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
String name = checkNotNull(postParams.remove("name"), "name");
final URI template = URI.create(checkNotNull(postParams.remove("template"), "template"));
boolean deploy = true;
boolean powerOn = true;
URI template = URI.create(checkNotNull(postParams.remove("template"), "template"));
Set<NetworkConfig> networkConfig = null;
NetworkConfigDecorator networknetworkConfigDecorator = new NetworkConfigDecorator(template,
NetworkConfigDecorator networkConfigDecorator = new NetworkConfigDecorator(templateCache.getUnchecked(template),
defaultNetwork.getHref(), defaultFenceMode, defaultNetworkNameInTemplate);
InstantiateVAppTemplateOptions options = findOptionsInArgsOrNull(gRequest);
if (options != null) {
if (options.getNetworkConfig().size() > 0)
networkConfig = Sets.newLinkedHashSet(Iterables.transform(options.getNetworkConfig(),
networknetworkConfigDecorator));
deploy = ifNullDefaultTo(options.shouldDeploy(), deploy);
powerOn = ifNullDefaultTo(options.shouldPowerOn(), powerOn);
networkConfig = ImmutableSet
.copyOf(transform(options.getNetworkConfig(), networkConfigDecorator));
} else {
options = new InstantiateVAppTemplateOptions();
}
if (networkConfig == null)
networkConfig = ImmutableSet.of(networknetworkConfigDecorator.apply(null));
networkConfig = ImmutableSet.of(networkConfigDecorator.apply(null));
try {
return stringBinder.bindToRequest(
request,
generateXml(name, options.getDescription(), deploy, powerOn, template, networkConfig));
return stringBinder.bindToRequest(request, generateXml(name, options.getDescription(), options.shouldDeploy(),
options.shouldPowerOn(), template, networkConfig));
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (FactoryConfigurationError e) {
@ -136,9 +128,9 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
@VisibleForTesting
Set<Vm> ifCustomizationScriptIsSetGetVmsInTemplate(String customizationScript, final URI template) {
Set<Vm> vms = Sets.newLinkedHashSet();
Set<Vm> vms = ImmutableSet.of();
if (customizationScript != null) {
VAppTemplate vAppTemplate = client.getVAppTemplateClient().getVAppTemplate(template);
VAppTemplate vAppTemplate = templateCache.getUnchecked(template);
checkArgument(vAppTemplate != null, "vAppTemplate %s not found!", template);
vms = vAppTemplate.getChildren();
checkArgument(vms.size() > 0, "no vms found in vAppTemplate %s", vAppTemplate);
@ -147,13 +139,13 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
}
protected static final class NetworkConfigDecorator implements Function<NetworkConfig, NetworkConfig> {
private final URI template;
private final VAppTemplate template;
private final URI defaultNetwork;
private final FenceMode defaultFenceMode;
private final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate;
private final Function<VAppTemplate, String> defaultNetworkNameInTemplate;
protected NetworkConfigDecorator(URI template, URI defaultNetwork, FenceMode defaultFenceMode,
DefaultNetworkNameInTemplate defaultNetworkNameInTemplate) {
protected NetworkConfigDecorator(VAppTemplate template, URI defaultNetwork, FenceMode defaultFenceMode,
Function<VAppTemplate, String> defaultNetworkNameInTemplate) {
this.template = checkNotNull(template, "template");
this.defaultNetwork = checkNotNull(defaultNetwork, "defaultNetwork");
this.defaultFenceMode = checkNotNull(defaultFenceMode, "defaultFenceMode");
@ -166,38 +158,14 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
return new NetworkConfig(defaultNetworkNameInTemplate.apply(template), defaultNetwork, defaultFenceMode);
URI network = ifNullDefaultTo(from.getParentNetwork(), defaultNetwork);
FenceMode fenceMode = ifNullDefaultTo(from.getFenceMode(), defaultFenceMode);
// using conditional statement instead of ifNullDefaultTo so that we lazy invoke the
// function, as it is an expensive one.
String networkName = from.getNetworkName() != null ? from.getNetworkName() : defaultNetworkNameInTemplate
.apply(template);
return new NetworkConfig(networkName, network, fenceMode);
}
}
@Singleton
public static class DefaultNetworkNameInTemplate implements Function<URI, String> {
@Resource
protected Logger logger = Logger.NULL;
private final VCloudClient client;
@Inject
DefaultNetworkNameInTemplate(VCloudClient client) {
this.client = client;
}
@Override
public String apply(URI template) {
String networkName;
VAppTemplate vAppTemplate = client.getVAppTemplateClient().getVAppTemplate(template);
checkArgument(vAppTemplate != null, "vAppTemplate %s not found!", template);
Set<org.jclouds.ovf.Network> networks = vAppTemplate.getNetworkSection().getNetworks();
checkArgument(networks.size() > 0, "no networks found in vAppTemplate %s", vAppTemplate);
if (networks.size() > 1)
logger.warn("multiple networks found for %s, choosing first from: %s", vAppTemplate.getName(), networks);
networkName = Iterables.get(networks, 0).getName();
return networkName;
}
}
protected String generateXml(String name, @Nullable String description, boolean deploy, boolean powerOn,
URI template, Iterable<NetworkConfig> networkConfig)
throws ParserConfigurationException, FactoryConfigurationError, TransformerException {

View File

@ -45,9 +45,13 @@ import org.jclouds.vcloud.compute.internal.VCloudTemplateBuilderImpl;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.compute.strategy.VCloudComputeServiceAdapter;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.domain.network.NetworkConfig;
import org.jclouds.vcloud.endpoints.Network;
import org.jclouds.vcloud.functions.VAppTemplatesInOrg;
import com.google.common.annotations.VisibleForTesting;
@ -110,6 +114,14 @@ public class VCloudComputeServiceDependenciesModule extends AbstractModule {
}).to((Class) IdentityFunction.class);
}
@Provides
@Singleton
public NetworkConfig networkConfig(@Network ReferenceType network, FenceMode defaultFenceMode) {
return new NetworkConfig(network.getName(), network.getHref(), defaultFenceMode);
}
@Singleton
public static class DefaultVDC implements Supplier<Location> {
private final Supplier<Set<? extends Location>> locationsSupplier;

View File

@ -30,7 +30,6 @@ import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Envelope;
import org.jclouds.ovf.VirtualHardwareSection;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VAppTemplate;
import com.google.common.base.Function;
@ -45,37 +44,25 @@ public class HardwareForVAppTemplate implements Function<VAppTemplate, Hardware>
@Resource
protected Logger logger = Logger.NULL;
private final VCloudClient client;
private final Function<VAppTemplate, Envelope> templateToEnvelope;
private final FindLocationForResource findLocationForResource;
private final VCloudHardwareBuilderFromResourceAllocations rasdToHardwareBuilder;
@Inject
protected HardwareForVAppTemplate(VCloudClient client, FindLocationForResource findLocationForResource,
protected HardwareForVAppTemplate(Function<VAppTemplate, Envelope> templateToEnvelope,
FindLocationForResource findLocationForResource,
VCloudHardwareBuilderFromResourceAllocations rasdToHardwareBuilder) {
this.client = checkNotNull(client, "client");
this.templateToEnvelope = checkNotNull(templateToEnvelope, "templateToEnvelope");
this.findLocationForResource = checkNotNull(findLocationForResource, "findLocationForResource");
this.rasdToHardwareBuilder = checkNotNull(rasdToHardwareBuilder, "rasdToHardwareBuilder");
}
@Override
public Hardware apply(VAppTemplate from) {
checkNotNull(from, "VAppTemplate");
if (!from.isOvfDescriptorUploaded()) {
logger.warn("cannot parse hardware as ovf descriptor for %s is not uploaded", from);
return null;
}
Envelope ovf = templateToEnvelope.apply(from);
Envelope ovf = client.getVAppTemplateClient().getOvfEnvelopeForVAppTemplate(from.getHref());
if (ovf == null) {
logger.warn("cannot parse hardware as no ovf envelope found for %s", from);
return null;
}
if (ovf.getVirtualSystem().getVirtualHardwareSections().size() == 0) {
logger.warn("cannot parse hardware for %s as no hardware sections exist in ovf %s", ovf);
return null;
}
if (ovf.getVirtualSystem().getVirtualHardwareSections().size() > 1) {
logger.warn("multiple hardware choices found. using first", ovf);
}
@ -89,6 +76,7 @@ public class HardwareForVAppTemplate implements Function<VAppTemplate, Hardware>
builder.ids(from.getHref().toASCIIString()).name(from.getName()).supportsImage(
ImagePredicates.idEquals(from.getHref().toASCIIString()));
return builder.build();
}
protected String getName(String name) {

View File

@ -20,14 +20,17 @@ package org.jclouds.vcloud.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Envelope;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VAppTemplate;
import com.google.common.base.Function;
@ -37,18 +40,26 @@ import com.google.common.base.Function;
*/
@Singleton
public class ImageForVAppTemplate implements Function<VAppTemplate, Image> {
private final VCloudClient client;
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
public Logger logger = Logger.NULL;
private final Function<VAppTemplate, Envelope> templateToEnvelope;
private final FindLocationForResource findLocationForResource;
@Inject
protected ImageForVAppTemplate(VCloudClient client, FindLocationForResource findLocationForResource) {
this.client = checkNotNull(client, "client");
protected ImageForVAppTemplate(Function<VAppTemplate, Envelope> templateToEnvelope,
FindLocationForResource findLocationForResource) {
this.templateToEnvelope = checkNotNull(templateToEnvelope, "templateToEnvelope");
this.findLocationForResource = checkNotNull(findLocationForResource, "findLocationForResource");
}
@Override
public Image apply(VAppTemplate from) {
checkNotNull(from, "VAppTemplate");
Envelope ovf = templateToEnvelope.apply(from);
ImageBuilder builder = new ImageBuilder();
builder.ids(from.getHref().toASCIIString());
builder.uri(from.getHref());
@ -59,7 +70,6 @@ public class ImageForVAppTemplate implements Function<VAppTemplate, Image> {
// otherwise, it could be in a public catalog, which is not assigned to a VDC
}
builder.description(from.getDescription() != null ? from.getDescription() : from.getName());
Envelope ovf = client.getVAppTemplateClient().getOvfEnvelopeForVAppTemplate(from.getHref());
builder.operatingSystem(CIMOperatingSystem.toComputeOs(ovf));
return builder.build();
}

View File

@ -76,3 +76,4 @@ public class ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentExceptio
return ovf;
}
}

View File

@ -18,8 +18,14 @@
*/
package org.jclouds.vcloud.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.get;
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig;
import java.net.URI;
@ -31,7 +37,11 @@ import javax.inject.Singleton;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Network;
import org.jclouds.predicates.validators.DnsNameValidator;
import org.jclouds.vcloud.TaskStillRunningException;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.GuestCustomizationSection;
@ -39,14 +49,16 @@ import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
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.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
@ -59,100 +71,218 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
protected final VCloudClient client;
protected final Predicate<URI> successTester;
protected final LoadingCache<URI, VAppTemplate> vAppTemplates;
protected final NetworkConfig defaultNetworkConfig;
protected final String buildVersion;
@Inject
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate<URI> successTester,
VCloudClient client) {
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(VCloudClient client,
Predicate<URI> successTester, LoadingCache<URI, VAppTemplate> vAppTemplates,
NetworkConfig defaultNetworkConfig, @Named(PROPERTY_BUILD_VERSION) String buildVersion) {
this.client = client;
this.successTester = successTester;
this.vAppTemplates = vAppTemplates;
this.defaultNetworkConfig = defaultNetworkConfig;
this.buildVersion = buildVersion;
}
public NodeAndInitialCredentials<VApp> createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
// 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/>
* It appears to be 15 characters to match Windows' hostname limitation. Must be alphanumeric, at
* least one non-number character and hyphens and underscores are the only non-alpha character
* allowed.
*/
public static enum ComputerNameValidator {
INSTANCE;
private DnsNameValidator validator;
ComputerNameValidator(){
this.validator = new DnsNameValidator(3, 15);
}
public void validate(@Nullable String t) throws IllegalArgumentException {
this.validator.validate(t);
}
}
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;
else
config = defaultNetworkConfig.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 ipAddressAllocationMode = VCloudTemplateOptions.class.cast(template.getOptions())
IpAddressAllocationMode ipAllocationMode = VCloudTemplateOptions.class.cast(template.getOptions())
.getIpAddressAllocationMode();
options.description(VCloudTemplateOptions.class.cast(template.getOptions()).getDescription());
String description = VCloudTemplateOptions.class.cast(template.getOptions()).getDescription();
if (description == null)
description = vAppTemplate.getName();
options.description(description);
options.deploy(false);
options.powerOn(false);
if (!template.getOptions().shouldBlockUntilRunning())
options.block(false);
URI VDC = URI.create(template.getLocation().getId());
URI templateId = URI.create(template.getImage().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);
waitForTask(vAppResponse.getTasks().get(0), vAppResponse);
waitForTask(vAppResponse.getTasks().get(0));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getName());
// note customization is a serial concern at the moment
Vm vm = Iterables.get(client.getVAppClient().getVApp(vAppResponse.getHref()).getChildren(), 0);
if (customizationScript != null) {
logger.trace(">> updating customization vm(%s) ", vm.getName());
waitForTask(updateVmWithCustomizationScript(vm, customizationScript), vAppResponse);
logger.trace("<< updated customization vm(%s) ", vm.getName());
}
if (ipAddressAllocationMode != null) {
logger.trace(">> updating ipAddressAllocationMode(%s) vm(%s) ", ipAddressAllocationMode, vm.getName());
waitForTask(updateVmWithIpAddressAllocationMode(vm, ipAddressAllocationMode), vAppResponse);
logger.trace("<< updated ipAddressAllocationMode vm(%s) ", vm.getName());
}
// vm data is available after instantiate completes
vAppResponse = client.getVAppClient().getVApp(vAppResponse.getHref());
// per above check, we know there is only a single VM
Vm vm = get(vAppResponse.getChildren(), 0);
// 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));
logger.trace("<< updated customization vm(%s)", name);
ensureVmHasAllocationModeOrPooled(vAppResponse, ipAllocationMode);
int cpuCount = new Double(getCores(template.getHardware())).intValue();
logger.trace(">> updating cpuCount(%d) vm(%s)", cpuCount, vm.getName());
waitForTask(updateCPUCountOfVm(vm, cpuCount), vAppResponse);
waitForTask(updateCPUCountOfVm(vm, cpuCount));
logger.trace("<< updated cpuCount vm(%s)", vm.getName());
int memoryMB = template.getHardware().getRam();
logger.trace(">> updating memoryMB(%d) vm(%s)", memoryMB, vm.getName());
waitForTask(updateMemoryMBOfVm(vm, memoryMB), vAppResponse);
waitForTask(updateMemoryMBOfVm(vm, memoryMB));
logger.trace("<< updated memoryMB vm(%s)", vm.getName());
logger.trace(">> deploying and powering on vApp(%s) ", vAppResponse.getName());
vAppResponse = blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, client.getVAppClient()
.deployAndPowerOnVApp(vAppResponse.getHref()));
logger.trace(">> deploying vApp(%s)", vAppResponse.getName());
waitForTask(client.getVAppClient().deployVApp(vAppResponse.getHref()));
logger.trace("<< deployed vApp(%s)", vAppResponse.getName());
// only after deploy is the password valid
vAppResponse = client.getVAppClient().getVApp(vAppResponse.getHref());
logger.trace(">> powering on vApp(%s)", vAppResponse.getName());
client.getVAppClient().powerOnVApp(vAppResponse.getHref());
return new NodeAndInitialCredentials<VApp>(vAppResponse, vAppResponse.getHref().toASCIIString(),
getCredentialsFrom(vAppResponse));
}
public void waitForTask(Task task, VApp vAppResponse) {
public void waitForTask(Task task) {
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", task.getName(), vAppResponse.getName(), task));
throw new TaskStillRunningException(task);
}
}
public Task updateVmWithCustomizationScript(Vm vm, String customizationScript) {
/**
* 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
* vAppTemplate with a VM named (incorrectly) {@code Ubuntu_10.04}, you must change the name to a
* valid (alphanumeric underscore) name before you can update it.
*/
public Task updateVmWithNameAndCustomizationScript(Vm vm, String name, @Nullable String customizationScript) {
GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection();
// TODO: determine if the server version is beyond 1.0.0, and if so append
// to, but
// not overwrite the customization script. In version 1.0.0, the api
// returns a script that
// loses newlines.
guestConfiguration.setComputerName(name);
if (customizationScript != null) {
// In version 1.0.0, the api returns a script that loses newlines, so we cannot append to a
// customization script.
// TODO: parameterize whether to overwrite or append existing customization
if (!buildVersion.startsWith("1.0.0") && !"".endsWith(buildVersion)
&& guestConfiguration.getCustomizationScript() != null)
customizationScript = guestConfiguration.getCustomizationScript() + "\n" + customizationScript;
guestConfiguration.setCustomizationScript(customizationScript);
}
return client.getVmClient().updateGuestCustomizationOfVm(guestConfiguration, vm.getHref());
}
public Task updateVmWithIpAddressAllocationMode(Vm vm, final IpAddressAllocationMode ipAddressAllocationMode) {
NetworkConnectionSection net = vm.getNetworkConnectionSection();
Builder builder = net.toBuilder();
builder.connections(Iterables.transform(net.getConnections(),
new Function<NetworkConnection, NetworkConnection>() {
public void ensureVmHasAllocationModeOrPooled(VApp vApp, @Nullable IpAddressAllocationMode ipAllocationMode) {
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);
if (ipAllocationMode == null)
ipAllocationMode = toConnect.getIpAddressAllocationMode();
// make sure that we are in fact allocating ips
if (ipAllocationMode == IpAddressAllocationMode.NONE)
ipAllocationMode = IpAddressAllocationMode.POOL;
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());
waitForTask(client.getVmClient().updateNetworkConnectionOfVm(builder.build(), vm.getHref()));
logger.trace("<< updated networkConnection vm(%s)", vm.getName());
@Override
public NetworkConnection apply(NetworkConnection arg0) {
return arg0.toBuilder().connected(true).ipAddressAllocationMode(ipAddressAllocationMode).build();
}
}));
return client.getVmClient().updateNetworkConnectionOfVm(builder.build(), vm.getHref());
}
private NetworkConnection findWithPoolAllocationOrFirst(NetworkConnectionSection net) {
return find(net.getConnections(), new Predicate<NetworkConnection>() {
@Override
public boolean apply(NetworkConnection input) {
return input.getIpAddressAllocationMode() == IpAddressAllocationMode.POOL;
}
}, get(net.getConnections(), 0));
}
public Task updateCPUCountOfVm(Vm vm, int cpuCount) {
@ -162,12 +292,4 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
public Task updateMemoryMBOfVm(Vm vm, int memoryInMB) {
return client.getVmClient().updateMemoryMBOfVm(memoryInMB, vm.getHref());
}
private VApp blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse, Task task) {
if (options.shouldBlock()) {
waitForTask(task, vAppResponse);
logger.debug("<< ready vApp(%s)", vAppResponse.getName());
}
return client.getVAppClient().getVApp(vAppResponse.getHref());
}
}

View File

@ -35,6 +35,9 @@ import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Envelope;
import org.jclouds.vcloud.TaskInErrorStateException;
import org.jclouds.vcloud.TaskStillRunningException;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.compute.suppliers.OrgAndVDCToLocationSupplier;
@ -47,9 +50,11 @@ import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.suppliers.VAppTemplatesSupplier;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableSet.Builder;
/**
@ -69,18 +74,20 @@ public class VCloudComputeServiceAdapter implements ComputeServiceAdapter<VApp,
protected final InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn booter;
protected final Supplier<Map<String, Org>> nameToOrg;
protected final Supplier<Set<VAppTemplate>> templates;
protected final Function<VAppTemplate, Envelope> templateToEnvelope;
protected final Supplier<Set<? extends Location>> locations;
@Inject
protected VCloudComputeServiceAdapter(VCloudClient client, Predicate<URI> successTester,
InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn booter,
Supplier<Map<String, Org>> nameToOrg, VAppTemplatesSupplier templates,
OrgAndVDCToLocationSupplier locations) {
Function<VAppTemplate, Envelope> templateToEnvelope, OrgAndVDCToLocationSupplier locations) {
this.client = checkNotNull(client, "client");
this.successTester = checkNotNull(successTester, "successTester");
this.booter = checkNotNull(booter, "booter");
this.nameToOrg = checkNotNull(nameToOrg, "nameToOrg");
this.templates = checkNotNull(templates, "templates");
this.templateToEnvelope = checkNotNull(templateToEnvelope, "templateToEnvelope");
this.locations = checkNotNull(locations, "locations");
}
@ -114,7 +121,7 @@ public class VCloudComputeServiceAdapter implements ComputeServiceAdapter<VApp,
@Override
public Iterable<VAppTemplate> listImages() {
return templates.get();
return supportedTemplates();
}
@Override
@ -157,70 +164,79 @@ public class VCloudComputeServiceAdapter implements ComputeServiceAdapter<VApp,
public VApp getNode(String in) {
URI id = URI.create(in);
return client.getVAppClient().getVApp(id);
}
@Override
public void destroyNode(String id) {
URI vappId = URI.create(checkNotNull(id, "node.id"));
VApp vApp = client.getVAppClient().getVApp(vappId);
waitForPendingTasksToComplete(vApp);
vApp = undeployVAppIfDeployed(vApp);
deleteVApp(vApp);
}
void waitForPendingTasksToComplete(VApp vApp) {
for (Task task : vApp.getTasks())
waitForTask(task, vApp);
}
public void waitForTask(Task task, VApp vAppResponse) {
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", task.getName(), vAppResponse.getName(), task));
}
}
void deleteVApp(VApp vApp) {
logger.debug(">> deleting vApp(%s)", vApp.getHref());
waitForTask(client.getVAppClient().deleteVApp(vApp.getHref()), vApp);
logger.debug("<< deleted vApp(%s)", vApp.getHref());
}
VApp undeployVAppIfDeployed(VApp vApp) {
VApp vApp = cancelAnyRunningTasks(vappId);
if (vApp.getStatus() != Status.OFF) {
logger.debug(">> powering off VApp vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
try {
waitForTask(client.getVAppClient().powerOffVApp(vApp.getHref()));
vApp = client.getVAppClient().getVApp(vApp.getHref());
logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
} catch (IllegalStateException e) {
logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
}
logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
try {
waitForTask(client.getVAppClient().undeployVApp(vApp.getHref()), vApp);
waitForTask(client.getVAppClient().undeployVApp(vApp.getHref()));
vApp = client.getVAppClient().getVApp(vApp.getHref());
logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
} catch (IllegalStateException e) {
logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
}
}
logger.debug(">> deleting vApp(%s)", vApp.getHref());
waitForTask(client.getVAppClient().deleteVApp(vApp.getHref()));
logger.debug("<< deleted vApp(%s)", vApp.getHref());
}
VApp waitForPendingTasksToComplete(URI vappId) {
VApp vApp = client.getVAppClient().getVApp(vappId);
if (vApp.getTasks().size() == 0)
return vApp;
for (Task task : vApp.getTasks())
waitForTask(task);
return client.getVAppClient().getVApp(vappId);
}
VApp cancelAnyRunningTasks(URI vappId) {
VApp vApp = client.getVAppClient().getVApp(vappId);
if (vApp.getTasks().size() == 0)
return vApp;
for (Task task : vApp.getTasks()) {
try {
client.getTaskClient().cancelTask(task.getHref());
waitForTask(task);
} catch (TaskInErrorStateException e) {
}
}
return client.getVAppClient().getVApp(vappId);
}
public void waitForTask(Task task) {
if (!successTester.apply(task.getHref()))
throw new TaskStillRunningException(task);
}
@Override
public void rebootNode(String in) {
URI id = URI.create(checkNotNull(in, "node.id"));
Task task = client.getVAppClient().resetVApp(id);
successTester.apply(task.getHref());
waitForTask(client.getVAppClient().resetVApp(id));
}
@Override
public void resumeNode(String in) {
URI id = URI.create(checkNotNull(in, "node.id"));
Task task = client.getVAppClient().powerOnVApp(id);
successTester.apply(task.getHref());
waitForTask(client.getVAppClient().powerOnVApp(id));
}
@Override
public void suspendNode(String in) {
URI id = URI.create(checkNotNull(in, "node.id"));
Task task = client.getVAppClient().powerOffVApp(id);
successTester.apply(task.getHref());
waitForTask(client.getVAppClient().powerOffVApp(id));
}
}

View File

@ -77,10 +77,6 @@ public class VCloudComputeUtils {
public static LoginCredentials getCredentialsFrom(Vm vm) {
LoginCredentials.Builder builder = LoginCredentials.builder();
builder.user("root");
if (vm.getOperatingSystemSection() != null && vm.getOperatingSystemSection().getDescription() != null
&& vm.getOperatingSystemSection().getDescription().indexOf("Windows") >= 0)
builder.user("Administrator");
if (vm.getGuestCustomizationSection() != null)
builder.password(vm.getGuestCustomizationSection().getAdminPassword());
return builder.build();

View File

@ -20,20 +20,24 @@ package org.jclouds.vcloud.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.base.Suppliers.compose;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.getLast;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.transformValues;
import static com.google.common.collect.Maps.uniqueIndex;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_FENCEMODE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@ -50,6 +54,7 @@ import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.ovf.Envelope;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.AuthorizationException;
@ -61,6 +66,7 @@ import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudToken;
import org.jclouds.vcloud.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.compute.functions.FindLocationForResource;
import org.jclouds.vcloud.compute.functions.ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.Org;
@ -68,6 +74,8 @@ import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.VCloudSession;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.endpoints.Network;
import org.jclouds.vcloud.endpoints.OrgList;
import org.jclouds.vcloud.features.CatalogAsyncClient;
import org.jclouds.vcloud.features.CatalogClient;
@ -89,22 +97,25 @@ import org.jclouds.vcloud.functions.AllCatalogItemsInCatalog;
import org.jclouds.vcloud.functions.AllCatalogItemsInOrg;
import org.jclouds.vcloud.functions.AllCatalogsInOrg;
import org.jclouds.vcloud.functions.AllVDCsInOrg;
import org.jclouds.vcloud.functions.DefaultNetworkNameInTemplate;
import org.jclouds.vcloud.functions.OrgsForLocations;
import org.jclouds.vcloud.functions.OrgsForNames;
import org.jclouds.vcloud.functions.VAppTemplatesForCatalogItems;
import org.jclouds.vcloud.handlers.ParseVCloudErrorFromHttpResponse;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.loaders.OVFLoader;
import org.jclouds.vcloud.loaders.VAppTemplateLoader;
import org.jclouds.vcloud.predicates.TaskSuccess;
import org.jclouds.vcloud.xml.ovf.VCloudResourceAllocationSettingDataHandler;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import static com.google.common.base.Predicates.*;
import com.google.common.base.Supplier;
import static com.google.common.base.Suppliers.*;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import static com.google.common.collect.Iterables.*;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
@ -192,6 +203,27 @@ public class VCloudRestClientModule extends RestClientModule<VCloudClient, VClou
bind(new TypeLiteral<Function<Org, Iterable<CatalogItem>>>() {
}).to(new TypeLiteral<AllCatalogItemsInOrg>() {
});
bindCacheLoaders();
bind(new TypeLiteral<Function<VAppTemplate, String>>() {
}).annotatedWith(Network.class).to(new TypeLiteral<DefaultNetworkNameInTemplate>() {
});
bind(new TypeLiteral<Function<VAppTemplate, Envelope>>() {
}).to(new TypeLiteral<ValidateVAppTemplateAndReturnEnvelopeOrThrowIllegalArgumentException>() {
});
}
protected void bindCacheLoaders() {
bind(new TypeLiteral<CacheLoader<URI, VAppTemplate>>() {
}).to(new TypeLiteral<VAppTemplateLoader>() {
});
bind(new TypeLiteral<CacheLoader<URI, Envelope>>() {
}).to(new TypeLiteral<OVFLoader>() {
});
}
@Provides
@ -487,6 +519,25 @@ public class VCloudRestClientModule extends RestClientModule<VCloudClient, VClou
authException, seconds, supplier);
}
@Provides
@Singleton
protected FenceMode defaultFenceMode(@Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode){
return FenceMode.fromValue(fenceMode);
}
@Provides
@Singleton
protected LoadingCache<URI, VAppTemplate> vAppTemplates(CacheLoader<URI, VAppTemplate> vAppTemplates) {
return CacheBuilder.newBuilder().build(vAppTemplates);
}
@Provides
@Singleton
protected LoadingCache<URI, Envelope> envelopes(CacheLoader<URI, Envelope> envelopes) {
return CacheBuilder.newBuilder().build(envelopes);
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseVCloudErrorFromHttpResponse.class);

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.vcloud.domain.ovf.VCloudNetworkSection;
/**
* A VApp is the result of instantiation of a {@link VAppTemplate}. <h2>note</h2>
@ -77,4 +78,12 @@ public interface VApp extends ReferenceType {
*/
Set<Vm> getChildren();
/**
* description of the predefined vApp internal networks in this template
*
* @return null if the vApp is not yet instantiated
* @since vcloud api 1.0
*/
@Nullable
VCloudNetworkSection getNetworkSection();
}

View File

@ -31,6 +31,8 @@ import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.TaskStatus;
import org.jclouds.vcloud.domain.VCloudError;
import com.google.common.base.Objects;
/**
*
* @author Adrian Cole
@ -88,10 +90,9 @@ public class TaskImpl extends ReferenceTypeImpl implements Task {
@Override
public String toString() {
return "TaskImpl [endTime=" + endTime + ", error=" + error + ", expiryTime=" + expiryTime + ", operation="
+ operation + ", owner=" + owner + ", startTime=" + startTime + ", status=" + status + ", getHref()="
+ getHref() + ", getName()=" + getName() + ", getType()=" + getType() + ", toString()="
+ super.toString() + ", getClass()=" + getClass() + "]";
return Objects.toStringHelper("").add("href", getHref()).add("name", getName()).add("owner", owner).add(
"operation", operation).add("startTime", startTime).add("endTime", endTime)
.add("expiryTime", expiryTime).add("error", error).toString();
}
public Date getExpiryTime() {

View File

@ -31,6 +31,7 @@ import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.domain.ovf.VCloudNetworkSection;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@ -51,9 +52,12 @@ public class VAppImpl extends ReferenceTypeImpl implements VApp {
private final List<Task> tasks = Lists.newArrayList();
private final boolean ovfDescriptorUploaded;
private final Set<Vm> children = Sets.newLinkedHashSet();
@Nullable
private final VCloudNetworkSection networkSection;
public VAppImpl(String name, String type, URI id, Status status, ReferenceType vdc, @Nullable String description,
Iterable<Task> tasks, boolean ovfDescriptorUploaded, Iterable<Vm> children) {
Iterable<Task> tasks, boolean ovfDescriptorUploaded, Iterable<Vm> children,
@Nullable VCloudNetworkSection networkSection) {
super(name, type, id);
this.status = checkNotNull(status, "status");
this.vdc = vdc;// TODO: once <1.0 is killed check not null
@ -61,6 +65,7 @@ public class VAppImpl extends ReferenceTypeImpl implements VApp {
Iterables.addAll(this.tasks, checkNotNull(tasks, "tasks"));
this.ovfDescriptorUploaded = ovfDescriptorUploaded;
Iterables.addAll(this.children, checkNotNull(children, "children"));
this.networkSection = networkSection; // can be null when copying
}
/**
@ -111,6 +116,14 @@ public class VAppImpl extends ReferenceTypeImpl implements VApp {
return children;
}
/**
* {@inheritDoc}
*/
@Override
public VCloudNetworkSection getNetworkSection() {
return networkSection;
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -23,12 +23,51 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.ovf.NetworkSection;
/**
*
* @author Adrian Cole
*/
public class NetworkConfig {
public Builder toBuilder() {
return builder().fromNetworkConfig(this);
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String networkName;
private URI parentNetwork;
private FenceMode fenceMode;
public Builder networkName(String networkName) {
this.networkName = networkName;
return this;
}
public Builder parentNetwork(URI parentNetwork) {
this.parentNetwork = parentNetwork;
return this;
}
public Builder fenceMode(FenceMode fenceMode) {
this.fenceMode = fenceMode;
return this;
}
public Builder fromNetworkConfig(NetworkConfig in) {
return networkName(in.getNetworkName()).parentNetwork(in.getParentNetwork()).fenceMode(in.getFenceMode());
}
public NetworkConfig build() {
return new NetworkConfig(networkName, parentNetwork, fenceMode);
}
}
@Nullable
private final String networkName;
private final URI parentNetwork;
@ -87,7 +126,6 @@ public class NetworkConfig {
return fenceMode;
}
@Override
public int hashCode() {
final int prime = 31;

View File

@ -18,11 +18,9 @@
*/
package org.jclouds.vcloud.functions;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.Org;
@ -36,9 +34,6 @@ import com.google.common.collect.Iterables;
@Singleton
public class AllCatalogItemsInOrg implements Function<Org, Iterable<CatalogItem>> {
@Resource
public Logger logger = Logger.NULL;
private final Function<Org, Iterable<Catalog>> allCatalogsInOrg;
private final Function<Catalog, Iterable<CatalogItem>> allCatalogItemsInCatalog;

View File

@ -0,0 +1,49 @@
/**
* 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.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.get;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Network;
import org.jclouds.vcloud.domain.VAppTemplate;
import com.google.common.base.Function;
@Singleton
public class DefaultNetworkNameInTemplate implements Function<VAppTemplate, String> {
@Resource
protected Logger logger = Logger.NULL;
@Override
public String apply(VAppTemplate vAppTemplate) {
checkArgument(vAppTemplate != null, "vAppTemplate was null!");
Set<Network> networks = vAppTemplate.getNetworkSection().getNetworks();
checkArgument(networks.size() > 0, "no networks found in vAppTemplate %s", vAppTemplate);
if (networks.size() > 1)
logger.warn("multiple networks found for %s, choosing first from: %s", vAppTemplate.getName(), networks);
return get(networks, 0).getName();
}
}

View File

@ -18,20 +18,21 @@
*/
package org.jclouds.vcloud.functions;
import java.util.Map;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.collect.Iterables.filter;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Credentials;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.functions.AllCatalogItemsInOrg;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
@ -39,13 +40,12 @@ import com.google.common.collect.Iterables;
@Singleton
public class VAppTemplatesInOrg implements Function<Org, Iterable<VAppTemplate>> {
private final AllCatalogItemsInOrg allCatalogItemsInOrg;
private final Function<Org, Iterable<CatalogItem>> allCatalogItemsInOrg;
private final Function<Iterable<CatalogItem>, Iterable<VAppTemplate>> vAppTemplatesForCatalogItems;
@Inject
VAppTemplatesInOrg(AllCatalogItemsInOrg allCatalogItemsInOrg,
Function<Iterable<CatalogItem>, Iterable<VAppTemplate>> vAppTemplatesForCatalogItems,
Map<String, Credentials> credentialStore) {
VAppTemplatesInOrg(Function<Org, Iterable<CatalogItem>> allCatalogItemsInOrg,
Function<Iterable<CatalogItem>, Iterable<VAppTemplate>> vAppTemplatesForCatalogItems) {
this.allCatalogItemsInOrg = allCatalogItemsInOrg;
this.vAppTemplatesForCatalogItems = vAppTemplatesForCatalogItems;
}
@ -54,7 +54,17 @@ public class VAppTemplatesInOrg implements Function<Org, Iterable<VAppTemplate>>
public Iterable<VAppTemplate> apply(Org from) {
Iterable<CatalogItem> catalogs = allCatalogItemsInOrg.apply(from);
Iterable<VAppTemplate> vAppTemplates = vAppTemplatesForCatalogItems.apply(catalogs);
return Iterables.filter(vAppTemplates, Predicates.notNull());
return filter(vAppTemplates, and(notNull(), new Predicate<VAppTemplate>(){
//TODO: test this
@Override
public boolean apply(VAppTemplate input) {
if (input == null)
return false;
return ImmutableSet.of(Status.RESOLVED, Status.OFF).contains(input.getStatus());
}
}));
}
}

View File

@ -0,0 +1,49 @@
/**
* 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.loaders;
import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.ovf.Envelope;
import org.jclouds.vcloud.VCloudClient;
import com.google.common.cache.CacheLoader;
@Singleton
public class OVFLoader extends CacheLoader<URI, Envelope> {
@Resource
protected Logger logger = Logger.NULL;
private final VCloudClient client;
@Inject
OVFLoader(VCloudClient client) {
this.client = client;
}
@Override
public Envelope load(URI template) {
return client.getVAppTemplateClient().getOvfEnvelopeForVAppTemplate(template);
}
}

View File

@ -0,0 +1,49 @@
/**
* 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.loaders;
import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VAppTemplate;
import com.google.common.cache.CacheLoader;
@Singleton
public class VAppTemplateLoader extends CacheLoader<URI, VAppTemplate> {
@Resource
protected Logger logger = Logger.NULL;
private final VCloudClient client;
@Inject
VAppTemplateLoader(VCloudClient client) {
this.client = client;
}
@Override
public VAppTemplate load(URI template) {
return client.getVAppTemplateClient().getVAppTemplate(template);
}
}

View File

@ -36,7 +36,6 @@ public class InstantiateVAppTemplateOptions {
private Boolean customizeOnInstantiate;
private String description = null;
private boolean block = true;
private boolean deploy = true;
private boolean powerOn = true;
@ -44,10 +43,6 @@ public class InstantiateVAppTemplateOptions {
return description;
}
public boolean shouldBlock() {
return block;
}
public boolean shouldDeploy() {
return deploy;
}
@ -81,14 +76,6 @@ public class InstantiateVAppTemplateOptions {
return this;
}
/**
* block until instantiate or deployment operations complete?
*/
public InstantiateVAppTemplateOptions block(boolean block) {
this.block = block;
return this;
}
/**
* {@networkConfig VAppTemplate}s have internal networks that can be
* connected in order to access the internet or other external networks.
@ -116,14 +103,6 @@ public class InstantiateVAppTemplateOptions {
public static class Builder {
/**
* @see InstantiateVAppTemplateOptions#block
*/
public static InstantiateVAppTemplateOptions block(boolean block) {
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
return options.block(block);
}
/**
* @see InstantiateVAppTemplateOptions#description
*/
@ -161,14 +140,13 @@ public class InstantiateVAppTemplateOptions {
@Override
public String toString() {
return "[networkConfig=" + networkConfig + ", customizeOnInstantiate=" + customizeOnInstantiate
+ ", description=" + description + ", block=" + block + ", deploy=" + deploy + ", powerOn=" + powerOn + "]";
+ ", description=" + description + ", deploy=" + deploy + ", powerOn=" + powerOn + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (block ? 1231 : 1237);
result = prime * result + ((customizeOnInstantiate == null) ? 0 : customizeOnInstantiate.hashCode());
result = prime * result + (deploy ? 1231 : 1237);
result = prime * result + ((description == null) ? 0 : description.hashCode());
@ -186,8 +164,6 @@ public class InstantiateVAppTemplateOptions {
if (getClass() != obj.getClass())
return false;
InstantiateVAppTemplateOptions other = (InstantiateVAppTemplateOptions) obj;
if (block != other.block)
return false;
if (customizeOnInstantiate == null) {
if (other.customizeOnInstantiate != null)
return false;

View File

@ -24,6 +24,7 @@ import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.TaskInErrorStateException;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.TaskStatus;
@ -59,7 +60,7 @@ public class TaskSuccess implements Predicate<URI> {
return false;
logger.trace("%s: looking for status %s: currently: %s", task, TaskStatus.SUCCESS, task.getStatus());
if (task.getStatus() == TaskStatus.ERROR)
throw new RuntimeException("error on task: " + task.getHref() + " error: " + task.getError());
throw new TaskInErrorStateException(task);
return task.getStatus() == TaskStatus.SUCCESS;
}

View File

@ -35,6 +35,8 @@ import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.domain.internal.VAppImpl;
import org.jclouds.vcloud.domain.ovf.VCloudNetworkSection;
import org.jclouds.vcloud.xml.ovf.VCloudNetworkSectionHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@ -48,11 +50,14 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
protected final TaskHandler taskHandler;
protected final VmHandler vmHandler;
protected final VCloudNetworkSectionHandler networkSectionHandler;
@Inject
public VAppHandler(TaskHandler taskHandler, VmHandler vmHandler) {
public VAppHandler(TaskHandler taskHandler, VmHandler vmHandler,
VCloudNetworkSectionHandler networkSectionHandler) {
this.taskHandler = taskHandler;
this.vmHandler = vmHandler;
this.networkSectionHandler = networkSectionHandler;
}
protected StringBuilder currentText = new StringBuilder();
@ -66,11 +71,13 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
private boolean inChildren;
private boolean inTasks;
private boolean inNetworkSection;
protected Set<Vm> children = Sets.newLinkedHashSet();
private VCloudNetworkSection networkSection;
public VApp getResult() {
return new VAppImpl(template.getName(), template.getType(), template.getHref(), status, vdc, description, tasks,
ovfDescriptorUploaded, children);
ovfDescriptorUploaded, children, networkSection);
}
protected int depth = 0;
@ -84,12 +91,16 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
inChildren = true;
} else if (equalsOrSuffix(qName, "Tasks")) {
inTasks = true;
} else if (equalsOrSuffix(qName, "NetworkSection")) {
inNetworkSection = true;
}
}
if (inChildren) {
vmHandler.startElement(uri, localName, qName, attrs);
} else if (inTasks) {
taskHandler.startElement(uri, localName, qName, attrs);
} else if (inNetworkSection) {
networkSectionHandler.startElement(uri, localName, qName, attrs);
} else if (equalsOrSuffix(qName, "VApp")) {
template = newReferenceType(attributes);
if (attributes.containsKey("status"))
@ -111,12 +122,17 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
this.tasks.add(taskHandler.getResult());
} else if (equalsOrSuffix(qName, "Description")) {
description = SaxUtils.currentOrNull(currentText);
} else if (equalsOrSuffix(qName, "NetworkSection")) {
inNetworkSection = false;
this.networkSection = networkSectionHandler.getResult();
}
}
if (inChildren) {
vmHandler.endElement(uri, name, qName);
} else if (inTasks) {
taskHandler.endElement(uri, name, qName);
} else if (inNetworkSection) {
networkSectionHandler.endElement(uri, name, qName);
} else if (equalsOrSuffix(qName, "ovfDescriptorUploaded")) {
ovfDescriptorUploaded = Boolean.parseBoolean(SaxUtils.currentOrNull(currentText));
}
@ -124,11 +140,14 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
if (inTasks)
taskHandler.characters(ch, start, length);
if (inChildren)
else if (inChildren)
vmHandler.characters(ch, start, length);
else if (inNetworkSection)
networkSectionHandler.characters(ch, start, length);
else
currentText.append(ch, start, length);
}
}

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.vcloud.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import static org.jclouds.vcloud.util.Utils.newReferenceType;
import java.util.List;
@ -83,11 +84,11 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
Map<String, String> attributes = SaxUtils.cleanseAttributes(attrs);
if (qName.endsWith("Children")) {
if (equalsOrSuffix(qName, "Children")) {
inChildren = true;
} else if (qName.endsWith("Tasks")) {
} else if (equalsOrSuffix(qName, "Tasks")) {
inTasks = true;
} else if (qName.endsWith("NetworkSection")) {
} else if (equalsOrSuffix(qName, "NetworkSection")) {
inNetworkSection = true;
}
if (inChildren) {
@ -96,26 +97,26 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
taskHandler.startElement(uri, localName, qName, attrs);
} else if (inNetworkSection) {
networkSectionHandler.startElement(uri, localName, qName, attrs);
} else if (qName.equals("VAppTemplate")) {
} else if (equalsOrSuffix(qName, "VAppTemplate")) {
template = newReferenceType(attributes);
if (attributes.containsKey("status"))
this.status = Status.fromValue(Integer.parseInt(attributes.get("status")));
} else if (qName.equals("Link") && "up".equals(attributes.get("rel"))) {
} else if (equalsOrSuffix(qName, "Link") && "up".equals(attributes.get("rel"))) {
vdc = newReferenceType(attributes);
}
}
public void endElement(String uri, String name, String qName) {
if (qName.endsWith("Children")) {
if (equalsOrSuffix(qName, "Children")) {
inChildren = false;
Vm vm = vmHandler.getResult();
if (vm != null)
this.children.add(vmHandler.getResult());
} else if (qName.endsWith("Tasks")) {
} else if (equalsOrSuffix(qName, "Tasks")) {
inTasks = false;
this.tasks.add(taskHandler.getResult());
} else if (qName.endsWith("NetworkSection")) {
} else if (equalsOrSuffix(qName, "NetworkSection")) {
inNetworkSection = false;
this.networkSection = networkSectionHandler.getResult();
}
@ -125,11 +126,11 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
taskHandler.endElement(uri, name, qName);
} else if (inNetworkSection) {
networkSectionHandler.endElement(uri, name, qName);
} else if (qName.equals("Description")) {
} else if (equalsOrSuffix(qName, "Description")) {
description = currentOrNull();
} else if (qName.equals("VAppScopedLocalId")) {
} else if (equalsOrSuffix(qName, "VAppScopedLocalId")) {
vAppScopedLocalId = currentOrNull();
} else if (qName.equals("ovfDescriptorUploaded")) {
} else if (equalsOrSuffix(qName, "ovfDescriptorUploaded")) {
ovfDescriptorUploaded = Boolean.parseBoolean(currentOrNull());
}
currentText = new StringBuilder();

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.vcloud.xml.ovf;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Map;
import javax.inject.Inject;
@ -51,7 +53,7 @@ public class VCloudNetworkSectionHandler extends ParseSax.HandlerWithResult<VClo
public void startElement(String uri, String localName, String qName, Attributes attrs) {
Map<String, String> attributes = SaxUtils.cleanseAttributes(attrs);
if (qName.endsWith("NetworkSection")) {
if (equalsOrSuffix(qName, "NetworkSection")) {
this.net = Utils.newReferenceType(attributes);
}
networkSectionHandler.startElement(uri, localName, qName, attrs);

View File

@ -24,31 +24,35 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_FENCEMODE;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.util.Strings2;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudPropertiesBuilder;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.jclouds.vcloud.domain.network.FenceMode;
import org.jclouds.vcloud.domain.network.NetworkConfig;
import org.jclouds.vcloud.domain.ovf.VCloudNetworkSection;
import org.jclouds.vcloud.endpoints.Network;
import org.jclouds.vcloud.features.VAppTemplateClient;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
@ -63,22 +67,37 @@ import com.google.inject.name.Names;
*/
@Test(groups = "unit")
public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
Injector createInjector(URI vAppTemplate, VAppTemplate value) {
final VCloudClient client = createMock(VCloudClient.class);
final VAppTemplateClient tclient = createMock(VAppTemplateClient.class);
expect(client.getVAppTemplateClient()).andReturn(tclient).anyTimes();
expect(tclient.getVAppTemplate(vAppTemplate)).andReturn(value).anyTimes();
replay(client);
replay(tclient);
Injector createInjector(final URI vAppTemplate, final VAppTemplate value) {
return Guice.createInjector(new AbstractModule() {
@SuppressWarnings("unused")
@Provides
@Singleton
@Network
protected Function<VAppTemplate, String> templateToDefaultNetworkName() {
return Functions.forMap(ImmutableMap.of(value, "vAppNet-vApp Internal"));
}
@SuppressWarnings("unused")
@Provides
@Singleton
protected LoadingCache<URI, VAppTemplate> templateIdToVAppTemplate() {
return CacheBuilder.newBuilder().build(
CacheLoader.from(Functions.forMap(ImmutableMap.of(vAppTemplate, value))));
}
@Override
protected void configure() {
Properties props = new Properties();
Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties"));
bind(VCloudClient.class).toInstance(client);
}
@SuppressWarnings("unused")
@Provides
@Singleton
public FenceMode defaultFenceMode(@Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode) {
return FenceMode.fromValue(fenceMode);
}
@SuppressWarnings("unused")
@ -86,7 +105,8 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
@Provides
@Singleton
ReferenceType provideNetwork() {
return new ReferenceTypeImpl(null, null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1990"));
return new ReferenceTypeImpl(null, null, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/network/1990"));
}
});
}
@ -94,7 +114,6 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
public void testDefault() throws IOException {
URI templateUri = URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
VAppTemplate template = createMock(VAppTemplate.class);
VCloudNetworkSection net = createMock(VCloudNetworkSection.class);
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/instantiationparams.xml"));
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
@ -103,13 +122,7 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
.atLeastOnce();
request.setPayload(expected);
expect(template.getNetworkSection()).andReturn(net).atLeastOnce();
expect(net.getNetworks()).andReturn(
ImmutableSet.<org.jclouds.ovf.Network> of(new org.jclouds.ovf.Network("vAppNet-vApp Internal", null)));
replay(request);
replay(template);
replay(net);
replay(request, template);
BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance(
BindInstantiateVAppTemplateParamsToXmlPayload.class);
@ -119,31 +132,22 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
map.put("template", templateUri.toASCIIString());
binder.bindToRequest(request, map);
verify(request);
verify(template);
verify(net);
verify(request, template);
}
public void testDescription() throws IOException {
URI templateUri = URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
VAppTemplate template = createMock(VAppTemplate.class);
VCloudNetworkSection net = createMock(VCloudNetworkSection.class);
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/instantiationparams-description.xml"));
String expected = Strings2.toStringAndClose(getClass()
.getResourceAsStream("/instantiationparams-description.xml"));
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
expect(request.getArgs()).andReturn(
ImmutableList.<Object> of(new InstantiateVAppTemplateOptions().description("my foo"))).atLeastOnce();
request.setPayload(expected);
expect(template.getNetworkSection()).andReturn(net).atLeastOnce();
expect(net.getNetworks()).andReturn(
ImmutableSet.<org.jclouds.ovf.Network> of(new org.jclouds.ovf.Network("vAppNet-vApp Internal", null)));
replay(request);
replay(template);
replay(net);
replay(request, template);
BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance(
BindInstantiateVAppTemplateParamsToXmlPayload.class);
@ -153,23 +157,20 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
map.put("template", templateUri.toASCIIString());
binder.bindToRequest(request, map);
verify(request);
verify(template);
verify(net);
verify(request, template);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testWhenTemplateDoesntExist() throws IOException {
URI templateUri = URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
VAppTemplate template = null;
VAppTemplate template = createMock(VAppTemplate.class);
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/instantiationparams.xml"));
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
expect(request.getArgs()).andReturn(ImmutableList.<Object> of()).atLeastOnce();
request.setPayload(expected);
replay(request);
replay(request, template);
BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance(
BindInstantiateVAppTemplateParamsToXmlPayload.class);
@ -178,7 +179,7 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
map.put("name", "my-vapp");
map.put("template", templateUri.toASCIIString());
binder.bindToRequest(request, map);
verify(request);
verify(request, template);
}
@ -211,10 +212,10 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
public void testWithNetworkNameFenceMode() throws IOException {
URI templateUri = URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
VAppTemplate template = null;
VAppTemplate template = createMock(VAppTemplate.class);
InstantiateVAppTemplateOptions options = addNetworkConfig(new NetworkConfig("aloha",
URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), FenceMode.NAT_ROUTED));
InstantiateVAppTemplateOptions options = addNetworkConfig(new NetworkConfig("aloha", URI
.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), FenceMode.NAT_ROUTED));
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/instantiationparams-network.xml"));
@ -222,7 +223,7 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
expect(request.getArgs()).andReturn(ImmutableList.<Object> of(options)).atLeastOnce();
request.setPayload(expected);
replay(request);
replay(request, template);
BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance(
BindInstantiateVAppTemplateParamsToXmlPayload.class);
@ -232,6 +233,6 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
map.put("template", "https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
binder.bindToRequest(request, map);
verify(request);
verify(request, template);
}
}

View File

@ -18,22 +18,12 @@
*/
package org.jclouds.vcloud.compute;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.rest.RestContext;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VApp;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
@ -46,8 +36,18 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public VCloudComputeServiceLiveTest() {
provider = "vcloud";
// vcloud requires instantiate before deploy, which takes longer than 30 seconds
nonBlockDurationSeconds = 300;
}
@Override
public void setServiceDefaults() {
// extremely short names needed so that we don't get errors relating to
// guestCustomization.computerName being too long
group = "vcd";
}
@Override
public void testOptionToNotBlock() {
// start call has to block until deploy
}
@Override
@ -62,31 +62,4 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
"node userMetadata did not match %s %s", userMetadata, node);
}
@Override
public void testListNodes() throws Exception {
for (ComputeMetadata node : client.listNodes()) {
assert node.getProviderId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
NodeMetadata allData = client.getNodeMetadata(node.getId());
System.out.println(allData.getHardware());
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory(
setupRestProperties()).createContext(provider, identity, credential, ImmutableSet.<Module> of(),
setupProperties()).getProviderSpecificContext();
VApp vApp = tmContext.getApi().getVAppClient().findVAppInOrgVDCNamed(null, null, allData.getName());
assertEquals(vApp.getName(), allData.getName());
}
}
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
@Override
public void testGetNodesWithDetails() throws Exception {
super.testGetNodesWithDetails();
}
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
@Override
public void testDestroyNodes() {
super.testDestroyNodes();
}
}

View File

@ -0,0 +1,72 @@
/**
* 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 static org.testng.Assert.assertEquals;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
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.domain.VApp;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*/
@Test(singleThreaded = true, testName = "InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest")
public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOnExpectTest extends
BaseVCloudComputeServiceExpectTest {
// 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());
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());
assertEquals(appAndCreds.getNode().getName(), name);
assertEquals(appAndCreds.getCredentials(), LoginCredentials.builder().user("root").password("fromVApp").build());
}
}

View File

@ -43,6 +43,7 @@ public class CatalogClientLiveTest extends BaseVCloudClientLiveTest {
@Test
public void testFindCatalogIsWriteable() throws Exception {
assertEquals(getVCloudApi().getCatalogClient().findCatalogInOrgNamed(null, null).isReadOnly(), false);
// default catalog should be the public one, unless we are in vCloud 1.0.0 where public catalogs don't work
assertEquals(getVCloudApi().getCatalogClient().findCatalogInOrgNamed(null, null).isReadOnly(), buildVersion.startsWith("1.5"));
}
}

View File

@ -98,7 +98,7 @@ public class VmClientLiveTest extends BaseVCloudClientLiveTest {
public void testExtendedOptionsWithCustomizationScript() throws Exception {
String PARSE_VMTOOLSD = "vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'";
String group = prefix + "customize";
String group = prefix + "cus";
NodeMetadata node = null;
try {

View File

@ -32,6 +32,8 @@ import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.ovf.Envelope;
import org.jclouds.ovf.xml.EnvelopeHandlerTest;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
@ -44,6 +46,7 @@ import org.jclouds.vcloud.domain.AllocationModel;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.VCloudSession;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.domain.VDCStatus;
@ -53,15 +56,19 @@ import org.jclouds.vcloud.domain.internal.OrgImpl;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.jclouds.vcloud.domain.internal.VDCImpl;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.xml.VAppTemplateHandlerTest;
import org.testng.annotations.Test;
import com.google.common.base.Functions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code VCloudAsyncClient}
@ -183,6 +190,16 @@ public abstract class BaseVCloudAsyncClientTest<T> extends RestClientTest<T> {
bind(OrgCatalogItemSupplier.class).to(TestOrgCatalogItemSupplier.class);
}
@SuppressWarnings("unchecked")
@Override
protected void bindCacheLoaders() {
bind(new TypeLiteral<CacheLoader<URI, VAppTemplate>>() {
}).toInstance((CacheLoader) CacheLoader.from(Functions.constant(VAppTemplateHandlerTest.parseTemplate())));
bind(new TypeLiteral<CacheLoader<URI, Envelope>>() {
}).toInstance((CacheLoader) CacheLoader.from(Functions.constant(EnvelopeHandlerTest.parseEnvelope())));
}
@Override
protected Supplier<Map<String, Map<String, org.jclouds.vcloud.domain.VDC>>> provideOrgVDCSupplierCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, AtomicReference<AuthorizationException> authException,

View File

@ -42,7 +42,8 @@ import com.google.inject.Module;
*/
@Test(groups = "live", enabled = true, singleThreaded = true)
public abstract class BaseVCloudClientLiveTest extends BaseVersionedServiceLiveTest {
protected String prefix = System.getProperty("user.name");
// username is too long for name constraints
protected String prefix = "vcd";
protected ComputeService client;

View File

@ -71,6 +71,7 @@ public class VAppHandlerTest {
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439")));
assertEquals(result.getTasks(), ImmutableList.of());
assert result.isOvfDescriptorUploaded();
assert result.getNetworkSection() != null;
Vm vm = Iterables.getOnlyElement(result.getChildren());
VmHandlerTest.checkVm(vm);
}

View File

@ -54,10 +54,7 @@ import com.google.inject.Injector;
public class VAppTemplateHandlerTest {
public void testUbuntuTemplate() {
InputStream is = getClass().getResourceAsStream("/vAppTemplate.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
VAppTemplate result = factory.create(injector.getInstance(VAppTemplateHandler.class)).parse(is);
VAppTemplate result = parseTemplate();
assertEquals(result.getName(), "Ubuntu Template");
assertEquals(result.getHref(), URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vappTemplate-1201908921"));
@ -118,6 +115,14 @@ public class VAppTemplateHandlerTest {
}
public static VAppTemplate parseTemplate() {
InputStream is = VAppTemplateHandlerTest.class.getResourceAsStream("/vAppTemplate.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
VAppTemplate result = factory.create(injector.getInstance(VAppTemplateHandler.class)).parse(is);
return result;
}
public void testCopyingTemplate() {
InputStream is = getClass().getResourceAsStream("/vAppTemplate-copying.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
@ -148,4 +153,14 @@ public class VAppTemplateHandlerTest {
assertEquals(result.getNetworkSection(), null);
}
public void testVAppTemplateWithNewlinesAndNamespacedElements() {
InputStream is = getClass().getResourceAsStream("/vAppTemplate1.0-vcd15_withNewlines.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
factory.create(injector.getInstance(VAppTemplateHandler.class)).parse(is);
}
}

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<vcloud:VAppTemplate xmlns:vcloud="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" ovfDescriptorUploaded="true" status="8" name="Windows 2008 R2 Standard (base) with SP1" type="application/vnd.vmware.vcloud.vAppTempla
te+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf
/envelope/1/dsp8023_1.1.0.xsd http://www.vmware.com/vcloud/v1 http://109.233.49.135/api/v1.0/schema/master.xsd">
<vcloud:Link rel="catalogItem" type="application/vnd.vmware.vcloud.catalogItem+xml" href="https://vcd.stratogen.net/api/v1.0/catalogItem/16bdea08-f176-48ce-9fe8-fc2265fc1068"/>
<vcloud:Link rel="enable" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/action/enableDownload"/>
<vcloud:Link rel="disable" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/action/disableDownload"/>
<vcloud:Link rel="ovf" type="text/xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/ovf"/>
<vcloud:Link rel="down" type="application/vnd.vmware.vcloud.owner+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/owner"/>
<vcloud:Description>Windows 2008 R2 Standard Edition
Service Pack 1
Internet Explorer 9</vcloud:Description>
<vcloud:Children>
<vcloud:Vm name="Windows 2008 R2 Standard (Base) with SP1" type="application/vnd.vmware.vcloud.vm+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vm-2ac49c8b-5cd9-428d-86da-24cfe9144b94">
<vcloud:Link rel="up" type="application/vnd.vmware.vcloud.vAppTemplate+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80"/>
<vcloud:Description>Windows 2008 R2 Standard Edition
Service Pack 1
Internet Explorer 9</vcloud:Description>
<vcloud:NetworkConnectionSection type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vm-2ac49c8b-5cd9-428d-86da-24cfe9144b94/networkConnectionSection/" ovf:required="false">
<ovf:Info>Specifies the available VM network connections</ovf:Info>
<vcloud:PrimaryNetworkConnectionIndex>0</vcloud:PrimaryNetworkConnectionIndex>
<vcloud:NetworkConnection network="StratoGen Ext Net">
<vcloud:NetworkConnectionIndex>0</vcloud:NetworkConnectionIndex>
<vcloud:IpAddress>212.54.128.56</vcloud:IpAddress>
<vcloud:IsConnected>true</vcloud:IsConnected>
<vcloud:MACAddress>00:50:56:01:0d:3c</vcloud:MACAddress>
<vcloud:IpAddressAllocationMode>POOL</vcloud:IpAddressAllocationMode>
</vcloud:NetworkConnection>
</vcloud:NetworkConnectionSection>
<vcloud:GuestCustomizationSection type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vm-2ac49c8b-5cd9-428d-86da-24cfe9144b94/guestCustomizationSection/" ovf:required="false">
<ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
<vcloud:Enabled>true</vcloud:Enabled>
<vcloud:ChangeSid>true</vcloud:ChangeSid>
<vcloud:JoinDomainEnabled>false</vcloud:JoinDomainEnabled>
<vcloud:UseOrgSettings>false</vcloud:UseOrgSettings>
<vcloud:AdminPasswordEnabled>true</vcloud:AdminPasswordEnabled>
<vcloud:AdminPasswordAuto>true</vcloud:AdminPasswordAuto>
<vcloud:AdminPassword>$6fEPL93</vcloud:AdminPassword>
<vcloud:ResetPasswordRequired>false</vcloud:ResetPasswordRequired>
<vcloud:ComputerName>Win2008r2Stand</vcloud:ComputerName>
</vcloud:GuestCustomizationSection>
<vcloud:VAppScopedLocalId>ac2ce03d-0491-46f7-afc6-37ffe5b30f74</vcloud:VAppScopedLocalId>
</vcloud:Vm>
</vcloud:Children>
<ovf:NetworkSection vcloud:href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml">
<ovf:Info>The list of logical networks</ovf:Info>
<ovf:Network ovf:name="StratoGen Ext Net">
<ovf:Description/>
</ovf:Network>
</ovf:NetworkSection>
<vcloud:NetworkConfigSection type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/networkConfigSection/" ovf:required="false">
<ovf:Info>The configuration parameters for logical networks</ovf:Info>
<vcloud:NetworkConfig networkName="StratoGen Ext Net">
<vcloud:Description/>
<vcloud:Configuration>
<vcloud:IpScope>
<vcloud:IsInherited>true</vcloud:IsInherited>
<vcloud:Gateway>212.54.128.1</vcloud:Gateway>
<vcloud:Netmask>255.255.255.0</vcloud:Netmask>
<vcloud:Dns1>109.233.48.141</vcloud:Dns1>
<vcloud:Dns2>109.233.48.142</vcloud:Dns2>
<vcloud:IpRanges>
<vcloud:IpRange>
<vcloud:StartAddress>212.54.128.4</vcloud:StartAddress>
<vcloud:EndAddress>212.54.128.220</vcloud:EndAddress>
</vcloud:IpRange>
</vcloud:IpRanges>
</vcloud:IpScope>
<vcloud:FenceMode>bridged</vcloud:FenceMode>
<vcloud:Features>
<vcloud:DhcpService>
<vcloud:IsEnabled>false</vcloud:IsEnabled>
<vcloud:DefaultLeaseTime>3600</vcloud:DefaultLeaseTime>
<vcloud:MaxLeaseTime>7200</vcloud:MaxLeaseTime>
<vcloud:IpRange>
<vcloud:StartAddress>212.54.128.201</vcloud:StartAddress>
<vcloud:EndAddress>212.54.128.254</vcloud:EndAddress>
</vcloud:IpRange>
</vcloud:DhcpService>
<vcloud:FirewallService>
<vcloud:IsEnabled>true</vcloud:IsEnabled>
</vcloud:FirewallService>
<vcloud:NatService>
<vcloud:IsEnabled>true</vcloud:IsEnabled>
<vcloud:NatType>ipTranslation</vcloud:NatType>
<vcloud:Policy>allowTraffic</vcloud:Policy>
<vcloud:NatRule>
<vcloud:OneToOneVmRule>
<vcloud:MappingMode>automatic</vcloud:MappingMode>
<vcloud:VAppScopedVmId>ac2ce03d-0491-46f7-afc6-37ffe5b30f74</vcloud:VAppScopedVmId>
<vcloud:VmNicId>0</vcloud:VmNicId>
</vcloud:OneToOneVmRule>
</vcloud:NatRule>
</vcloud:NatService>
</vcloud:Features>
</vcloud:Configuration>
<vcloud:IsDeployed>false</vcloud:IsDeployed>
</vcloud:NetworkConfig>
</vcloud:NetworkConfigSection>
<vcloud:LeaseSettingsSection type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/leaseSettingsSection/" ovf:required="false">
<ovf:Info>Lease settings section</ovf:Info>
<vcloud:Link rel="edit" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/leaseSettingsSection/"/>
<vcloud:StorageLeaseInSeconds>0</vcloud:StorageLeaseInSeconds>
</vcloud:LeaseSettingsSection>
<vcloud:CustomizationSection type="application/vnd.vmware.vcloud.customizationSection+xml" href="https://vcd.stratogen.net/api/v1.0/vAppTemplate/vappTemplate-f8ca27ba-c6ee-44bd-91a9-416f464cba80/customizationSection/" ovf:required="false">
<ovf:Info>VApp template customization section</ovf:Info>
<vcloud:CustomizeOnInstantiate>true</vcloud:CustomizeOnInstantiate>
</vcloud:CustomizationSection>
</vcloud:VAppTemplate>