Issue 498:[vcloud] expose IpAddressAllocationMode to compute service

This commit is contained in:
Adrian Cole 2011-03-05 16:55:59 -05:00
parent 7eef59db02
commit fb663fceed
9 changed files with 486 additions and 72 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.vcloud;
import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML; import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML;
import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML; import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML;
import static org.jclouds.vcloud.VCloudMediaType.NETWORKCONNECTIONSECTION_XML;
import static org.jclouds.vcloud.VCloudMediaType.TASK_XML; import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML; import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML;
import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML; import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML;
@ -47,9 +48,9 @@ import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamValidators;
import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.PayloadParams; import org.jclouds.rest.annotations.PayloadParams;
import org.jclouds.rest.annotations.ParamValidators;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -59,8 +60,10 @@ import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload; import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload;
import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload; import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindNetworkConnectionSectionToXmlPayload;
import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload;
import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -140,9 +143,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppTemplateHandler.class) @XMLResponseParser(VAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VAppTemplate> findVAppTemplateInOrgCatalogNamed( ListenableFuture<? extends VAppTemplate> findVAppTemplateInOrgCatalogNamed(
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName, @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName, @Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName); @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName);
/** /**
* @see VCloudClient#instantiateVAppTemplateInVDC * @see VCloudClient#instantiateVAppTemplateInVDC
@ -154,9 +157,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppHandler.class) @XMLResponseParser(VAppHandler.class)
@MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class) @MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class)
ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@EndpointParam URI vdc, ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@EndpointParam URI vdc,
@PayloadParam("template") URI template, @PayloadParam("template") URI template,
@PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, @PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
InstantiateVAppTemplateOptions... options); InstantiateVAppTemplateOptions... options);
/** /**
* @see VCloudClient#cloneVAppInVDC * @see VCloudClient#cloneVAppInVDC
@ -168,8 +171,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(TaskHandler.class) @XMLResponseParser(TaskHandler.class)
@MapBinder(BindCloneVAppParamsToXmlPayload.class) @MapBinder(BindCloneVAppParamsToXmlPayload.class)
ListenableFuture<? extends Task> cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone, ListenableFuture<? extends Task> cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone,
@PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, @PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, CloneVAppOptions... options);
CloneVAppOptions... options);
/** /**
* @see VCloudClient#captureVAppInVDC * @see VCloudClient#captureVAppInVDC
@ -181,9 +183,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppTemplateHandler.class) @XMLResponseParser(VAppTemplateHandler.class)
@MapBinder(BindCaptureVAppParamsToXmlPayload.class) @MapBinder(BindCaptureVAppParamsToXmlPayload.class)
ListenableFuture<? extends VAppTemplate> captureVAppInVDC(@EndpointParam URI vdc, ListenableFuture<? extends VAppTemplate> captureVAppInVDC(@EndpointParam URI vdc,
@PayloadParam("vApp") URI toCapture, @PayloadParam("vApp") URI toCapture,
@PayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName, @PayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName,
CaptureVAppOptions... options); CaptureVAppOptions... options);
/** /**
* @see VCloudClient#findVAppInOrgVDCNamed * @see VCloudClient#findVAppInOrgVDCNamed
@ -193,9 +195,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppHandler.class) @XMLResponseParser(VAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VApp> findVAppInOrgVDCNamed( ListenableFuture<? extends VApp> findVAppInOrgVDCNamed(
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName, @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName, @Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName); @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName);
/** /**
* @see VCloudClient#getVApp * @see VCloudClient#getVApp
@ -224,8 +226,19 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@Path("/guestCustomizationSection") @Path("/guestCustomizationSection")
@XMLResponseParser(TaskHandler.class) @XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> updateGuestCustomizationOfVm( ListenableFuture<? extends Task> updateGuestCustomizationOfVm(
@EndpointParam URI vm, @EndpointParam URI vm,
@BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection); @BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection);
/**
* @see VCloudClient#updateNetworkConnectionOfVm
*/
@PUT
@Consumes(TASK_XML)
@Produces(NETWORKCONNECTIONSECTION_XML)
@Path("/networkConnectionSection")
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> updateNetworkConnectionOfVm(@EndpointParam URI vm,
@BinderParam(BindNetworkConnectionSectionToXmlPayload.class) NetworkConnectionSection networkConnectionSection);
/** /**
* @see VCloudClient#deployVAppOrVm * @see VCloudClient#deployVAppOrVm

View File

@ -29,6 +29,7 @@ import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -48,14 +49,15 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
*/ */
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface VCloudClient extends CommonVCloudClient { public interface VCloudClient extends CommonVCloudClient {
/** /**
* Get a Screen Thumbnail for a Virtual Machine * Get a Screen Thumbnail for a Virtual Machine
* *
* @param vm to snapshot * @param vm
* to snapshot
*/ */
InputStream getThumbnailOfVm(URI vm); InputStream getThumbnailOfVm(URI vm);
/** /**
* The response to a login request includes a list of the organizations to which the * The response to a login request includes a list of the organizations to which the
* authenticated user has access. * authenticated user has access.
@ -68,11 +70,9 @@ public interface VCloudClient extends CommonVCloudClient {
Task cloneVAppInVDC(URI vDC, URI toClone, String newName, CloneVAppOptions... options); Task cloneVAppInVDC(URI vDC, URI toClone, String newName, CloneVAppOptions... options);
/** /**
* The captureVApp request creates a vApp template from an instantiated vApp. * The captureVApp request creates a vApp template from an instantiated vApp. <h4>Note</h4>
* <h4>Note</h4> * Before it can be captured, a vApp must be undeployed
* Before it can be captured, a vApp must be undeployed
* *
* @param vDC * @param vDC
* @param toClone * @param toClone
@ -97,6 +97,17 @@ public interface VCloudClient extends CommonVCloudClient {
*/ */
Task updateGuestCustomizationOfVm(URI vm, GuestCustomizationSection guestCustomizationSection); Task updateGuestCustomizationOfVm(URI vm, GuestCustomizationSection guestCustomizationSection);
/**
* Modify the Network Connection Section of a Virtual Machine
*
* @param vm
* uri to modify
* @param updated
* networkConnectionSection
* @return task in progress
*/
Task updateNetworkConnectionOfVm(URI vm, NetworkConnectionSection guestCustomizationSection);
/** /**
* returns the vapp template corresponding to a catalog item in the catalog associated with the * returns the vapp template corresponding to a catalog item in the catalog associated with the
* specified name. Note that the org and catalog parameters can be null to choose default. * specified name. Note that the org and catalog parameters can be null to choose default.
@ -112,7 +123,7 @@ public interface VCloudClient extends CommonVCloudClient {
* if you specified an org, catalog, or catalog item name that isn't present * if you specified an org, catalog, or catalog item name that isn't present
*/ */
VAppTemplate findVAppTemplateInOrgCatalogNamed(@Nullable String orgName, @Nullable String catalogName, VAppTemplate findVAppTemplateInOrgCatalogNamed(@Nullable String orgName, @Nullable String catalogName,
String itemName); String itemName);
VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName); VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName);

View File

@ -0,0 +1,109 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.vcloud.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
import java.util.Properties;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class BindNetworkConnectionSectionToXmlPayload extends BindToStringPayload {
@Resource
protected Logger logger = Logger.NULL;
protected final String ns;
protected final String schema;
@Inject
public BindNetworkConnectionSectionToXmlPayload(BindToStringPayload stringBinder,
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
this.ns = ns;
this.schema = schema;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
checkArgument(checkNotNull(payload, "NetworkConnectionSection") instanceof NetworkConnectionSection,
"this binder is only valid for NetworkConnectionSection!");
NetworkConnectionSection net = NetworkConnectionSection.class.cast(payload);
XMLBuilder networkConnectionSection;
try {
networkConnectionSection = XMLBuilder.create("NetworkConnectionSection").a("xmlns", ns)
.a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1").a("type", net.getType())
.a("href", net.getHref().toASCIIString()).a("ovf:required", "false");
networkConnectionSection.e("ovf:Info").t(net.getInfo());
if (net.getPrimaryNetworkConnectionIndex() != null)
networkConnectionSection.e("PrimaryNetworkConnectionIndex").t(
net.getPrimaryNetworkConnectionIndex().toString());
for (NetworkConnection networkConnection : net.getConnections()) {
XMLBuilder networkConnectionSectionChild = networkConnectionSection.e("NetworkConnection").a("network",
networkConnection.getNetwork());
networkConnectionSectionChild.e("NetworkConnectionIndex").t(
networkConnection.getNetworkConnectionIndex() + "");
if (networkConnection.getExternalIpAddress() != null)
networkConnectionSectionChild.e("ExternalIpAddress").t(networkConnection.getExternalIpAddress());
if (networkConnection.getIpAddress() != null)
networkConnectionSectionChild.e("IpAddress").t(networkConnection.getIpAddress());
networkConnectionSectionChild.e("IsConnected").t(networkConnection.isConnected() + "");
if (networkConnection.getMACAddress() != null)
networkConnectionSectionChild.e("MACAddress").t(networkConnection.getMACAddress());
if (networkConnection.getIpAddressAllocationMode() != null)
networkConnectionSectionChild.e("IpAddressAllocationMode").t(
networkConnection.getIpAddressAllocationMode().toString());
}
if (net.getEdit() != null)
networkConnectionSection.e("Link").a("rel", "edit").a("type", net.getType())
.a("href", net.getHref().toASCIIString());
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
request = super.bindToRequest(request, networkConnectionSection.asString(outputProperties));
request.getPayload().getContentMetadata().setContentType(net.getType());
} catch (Exception e) {
Throwables.propagate(e);
}
return request;
}
}

View File

@ -24,6 +24,7 @@ import java.util.Arrays;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.util.Preconditions2; import org.jclouds.util.Preconditions2;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
/** /**
* Contains options supported in the {@code ComputeService#runNode} operation on the "vcloud" * Contains options supported in the {@code ComputeService#runNode} operation on the "vcloud"
@ -45,6 +46,7 @@ import org.jclouds.util.Preconditions2;
public class VCloudTemplateOptions extends TemplateOptions { public class VCloudTemplateOptions extends TemplateOptions {
private String customizationScript = null; private String customizationScript = null;
private IpAddressAllocationMode ipAddressAllocationMode = null;
public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions(); public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions();
@ -57,8 +59,15 @@ public class VCloudTemplateOptions extends TemplateOptions {
return this; return this;
} }
public static class Builder { /**
* Specifies the ipAddressAllocationMode used to for network interfaces on the VMs
*/
public VCloudTemplateOptions ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
this.ipAddressAllocationMode = ipAddressAllocationMode;
return this;
}
public static class Builder {
/** /**
* @see VCloudTemplateOptions#customizationScript * @see VCloudTemplateOptions#customizationScript
*/ */
@ -67,6 +76,14 @@ public class VCloudTemplateOptions extends TemplateOptions {
return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript)); return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript));
} }
/**
* @see VCloudTemplateOptions#ipAddressAllocationMode
*/
public static VCloudTemplateOptions ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
VCloudTemplateOptions options = new VCloudTemplateOptions();
return VCloudTemplateOptions.class.cast(options.ipAddressAllocationMode(ipAddressAllocationMode));
}
// methods that only facilitate returning the correct object type // methods that only facilitate returning the correct object type
/** /**
* @see TemplateOptions#inboundPorts * @see TemplateOptions#inboundPorts
@ -125,6 +142,13 @@ public class VCloudTemplateOptions extends TemplateOptions {
return customizationScript; return customizationScript;
} }
/**
* @return ipAddressAllocationMode on the vms
*/
public IpAddressAllocationMode getIpAddressAllocationMode() {
return ipAddressAllocationMode;
}
// methods that only facilitate returning the correct object type // methods that only facilitate returning the correct object type
/** /**
@ -212,6 +236,7 @@ public class VCloudTemplateOptions extends TemplateOptions {
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode()); result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode());
result = prime * result + ((ipAddressAllocationMode == null) ? 0 : ipAddressAllocationMode.hashCode());
return result; return result;
} }
@ -229,15 +254,17 @@ public class VCloudTemplateOptions extends TemplateOptions {
return false; return false;
} else if (!customizationScript.equals(other.customizationScript)) } else if (!customizationScript.equals(other.customizationScript))
return false; return false;
if (ipAddressAllocationMode != other.ipAddressAllocationMode)
return false;
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "[customizationScript=" + customizationScript + ", inboundPorts=" + Arrays.toString(inboundPorts) return "[customizationScript=" + (customizationScript != null) + ", ipAddressAllocationMode="
+ ", privateKey=" + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + ipAddressAllocationMode + ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
+ (script != null) + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null)
+ "]"; + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + "]";
} }
} }

View File

@ -38,11 +38,16 @@ import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions; import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.GuestCustomizationSection; import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection.Builder;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -50,7 +55,8 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn implements CreateNodeWithGroupEncodedIntoName { public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn implements
CreateNodeWithGroupEncodedIntoName {
@Resource @Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@ -60,8 +66,8 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
protected final Predicate<URI> successTester; protected final Predicate<URI> successTester;
@Inject @Inject
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate<URI> successTester, VCloudClient client, protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate<URI> successTester,
GetNodeMetadataStrategy getNode) { VCloudClient client, GetNodeMetadataStrategy getNode) {
this.client = client; this.client = client;
this.successTester = successTester; this.successTester = successTester;
this.getNode = getNode; this.getNode = getNode;
@ -70,13 +76,15 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
@Override @Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { public NodeMetadata createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
InstantiateVAppTemplateOptions options = processorCount((int) getCores(template.getHardware())).memory( InstantiateVAppTemplateOptions options = processorCount((int) getCores(template.getHardware())).memory(
template.getHardware().getRam()).disk( template.getHardware().getRam()).disk(
(long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l)); (long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l));
String customizationScript = null; String customizationScript = null;
IpAddressAllocationMode ipAddressAllocationMode = null;
if (template.getOptions() instanceof VCloudTemplateOptions) { if (template.getOptions() instanceof VCloudTemplateOptions) {
customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript(); customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript();
if (customizationScript != null) { ipAddressAllocationMode = VCloudTemplateOptions.class.cast(template.getOptions()).getIpAddressAllocationMode();
if (customizationScript != null || ipAddressAllocationMode != null) {
options.customizeOnInstantiate(false); options.customizeOnInstantiate(false);
options.deploy(false); options.deploy(false);
options.powerOn(false); options.powerOn(false);
@ -96,39 +104,64 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
Task task = vAppResponse.getTasks().get(0); Task task = vAppResponse.getTasks().get(0);
if (customizationScript == null) { if (customizationScript == null && ipAddressAllocationMode == null) {
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task); return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
} else { } else {
if (!successTester.apply(task.getHref())) { if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String throw new RuntimeException(
.format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task)); String.format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task));
} }
Vm vm = Iterables.get(client.getVApp(vAppResponse.getHref()).getChildren(), 0); Vm vm = Iterables.get(client.getVApp(vAppResponse.getHref()).getChildren(), 0);
GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection(); if (customizationScript != null)
// guestConfiguration updateVmWithCustomizationScript(vm, customizationScript);
// .setCustomizationScript(guestConfiguration.getCustomizationScript() if (ipAddressAllocationMode != null)
// != null ? updateVmWithIpAddressAllocationMode(vm, ipAddressAllocationMode);
// guestConfiguration
// .getCustomizationScript()
// + "\n" + customizationScript : customizationScript);
guestConfiguration.setCustomizationScript(customizationScript);
task = client.updateGuestCustomizationOfVm(vm.getHref(), guestConfiguration);
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateGuestCustomizationOfVm", vm
.getName(), task));
}
task = client.deployAndPowerOnVAppOrVm(vAppResponse.getHref()); task = client.deployAndPowerOnVAppOrVm(vAppResponse.getHref());
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task); return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
} }
} }
public void updateVmWithCustomizationScript(Vm vm, String customizationScript) {
Task task;
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.setCustomizationScript(customizationScript);
task = client.updateGuestCustomizationOfVm(vm.getHref(), guestConfiguration);
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateGuestCustomizationOfVm", vm.getName(),
task));
}
}
public void updateVmWithIpAddressAllocationMode(Vm vm, final IpAddressAllocationMode ipAddressAllocationMode) {
Task task;
NetworkConnectionSection net = vm.getNetworkConnectionSection();
Builder builder = net.toBuilder();
builder.connections(Iterables.transform(net.getConnections(),
new Function<NetworkConnection, NetworkConnection>() {
@Override
public NetworkConnection apply(NetworkConnection arg0) {
return arg0.toBuilder().connected(true).ipAddressAllocationMode(ipAddressAllocationMode).build();
}
}));
task = client.updateNetworkConnectionOfVm(vm.getHref(), builder.build());
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateNetworkConnectionOfVm", vm.getName(),
task));
}
}
private NodeMetadata blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse, private NodeMetadata blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse,
Task task) { Task task) {
if (options.shouldBlock()) { if (options.shouldBlock()) {
if (!successTester.apply(task.getHref())) { if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on", vAppResponse throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on",
.getName(), task)); vAppResponse.getName(), task));
} }
logger.debug("<< ready vApp(%s)", vAppResponse.getName()); logger.debug("<< ready vApp(%s)", vAppResponse.getName());
} }

View File

@ -29,6 +29,67 @@ import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class NetworkConnection { public class NetworkConnection {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String network;
private int networkConnectionIndex;
private String ipAddress;
private String externalIpAddress;
private boolean connected;
private String MACAddress;
private IpAddressAllocationMode ipAddressAllocationMode;
public Builder network(String network) {
this.network = network;
return this;
}
public Builder networkConnectionIndex(int networkConnectionIndex) {
this.networkConnectionIndex = networkConnectionIndex;
return this;
}
public Builder ipAddress(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public Builder externalIpAddress(String externalIpAddress) {
this.externalIpAddress = externalIpAddress;
return this;
}
public Builder connected(boolean connected) {
this.connected = connected;
return this;
}
public Builder MACAddress(String MACAddress) {
this.MACAddress = MACAddress;
return this;
}
public Builder ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
this.ipAddressAllocationMode = ipAddressAllocationMode;
return this;
}
public NetworkConnection build() {
return new NetworkConnection(network, networkConnectionIndex, ipAddress, externalIpAddress, connected,
MACAddress, ipAddressAllocationMode);
}
public static Builder fromNetworkConnection(NetworkConnection in) {
return new Builder().network(in.getNetwork()).networkConnectionIndex(in.getNetworkConnectionIndex())
.ipAddress(in.getIpAddress()).externalIpAddress(in.getExternalIpAddress()).connected(in.isConnected())
.MACAddress(in.getMACAddress()).ipAddressAllocationMode(in.getIpAddressAllocationMode());
}
}
private final String network; private final String network;
private final int networkConnectionIndex; private final int networkConnectionIndex;
@Nullable @Nullable
@ -41,8 +102,8 @@ public class NetworkConnection {
private final IpAddressAllocationMode ipAddressAllocationMode; private final IpAddressAllocationMode ipAddressAllocationMode;
public NetworkConnection(String network, int networkConnectionIndex, @Nullable String ipAddress, public NetworkConnection(String network, int networkConnectionIndex, @Nullable String ipAddress,
@Nullable String externalIpAddress, boolean connected, @Nullable String MACAddress, @Nullable String externalIpAddress, boolean connected, @Nullable String MACAddress,
IpAddressAllocationMode ipAddressAllocationMode) { IpAddressAllocationMode ipAddressAllocationMode) {
this.network = network; this.network = network;
this.networkConnectionIndex = networkConnectionIndex; this.networkConnectionIndex = networkConnectionIndex;
this.ipAddress = ipAddress; this.ipAddress = ipAddress;
@ -162,11 +223,15 @@ public class NetworkConnection {
return true; return true;
} }
public Builder toBuilder() {
return Builder.fromNetworkConnection(this);
}
@Override @Override
public String toString() { public String toString() {
return "[network=" + network + ", connected=" + connected + ", ipAddress=" + ipAddress + ", externalIpAddress=" return "[network=" + network + ", connected=" + connected + ", ipAddress=" + ipAddress + ", externalIpAddress="
+ externalIpAddress + ", networkConnectionIndex=" + networkConnectionIndex + externalIpAddress + ", networkConnectionIndex=" + networkConnectionIndex + ", ipAddressAllocationMode="
+ ", ipAddressAllocationMode=" + ipAddressAllocationMode + ", MACAddress=" + MACAddress + "]"; + ipAddressAllocationMode + ", MACAddress=" + MACAddress + "]";
} }
} }

View File

@ -24,8 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/** /**
* The NetworkConnectionSection element specifies how a Vm is connected to a vApp network. It * The NetworkConnectionSection element specifies how a Vm is connected to a vApp network. It
@ -36,20 +35,73 @@ import com.google.common.collect.Sets;
* values specified in the NetworkConnectionSection override those specified in the NetworkSection. * values specified in the NetworkConnectionSection override those specified in the NetworkSection.
*/ */
public class NetworkConnectionSection { public class NetworkConnectionSection {
public static Builder builder() {
return new Builder();
}
public static class Builder {
protected String type;
protected URI href;
protected String info;
protected Integer primaryNetworkConnectionIndex;
protected Set<NetworkConnection> connections = ImmutableSet.of();
protected ReferenceType edit;
public Builder type(String type) {
this.type = type;
return this;
}
public Builder href(URI href) {
this.href = href;
return this;
}
public Builder info(String info) {
this.info = info;
return this;
}
public Builder primaryNetworkConnectionIndex(Integer primaryNetworkConnectionIndex) {
this.primaryNetworkConnectionIndex = primaryNetworkConnectionIndex;
return this;
}
public Builder connections(Iterable<? extends NetworkConnection> connections) {
this.connections = ImmutableSet.copyOf(checkNotNull(connections, "connections"));
return this;
}
public Builder edit(ReferenceType edit) {
this.edit = edit;
return this;
}
public NetworkConnectionSection build() {
return new NetworkConnectionSection(type, href, info, primaryNetworkConnectionIndex, connections, edit);
}
public static Builder fromNetworkConnectionSection(NetworkConnectionSection in) {
return new Builder().type(in.getType()).href(in.getHref()).info(in.getInfo())
.primaryNetworkConnectionIndex(in.getPrimaryNetworkConnectionIndex()).connections(in.getConnections())
.edit(in.getEdit());
}
}
protected final String type; protected final String type;
protected final URI href; protected final URI href;
protected final String info; protected final String info;
protected final Integer primaryNetworkConnectionIndex; protected final Integer primaryNetworkConnectionIndex;
protected final Set<NetworkConnection> connections = Sets.newLinkedHashSet(); protected final Set<NetworkConnection> connections;
protected final ReferenceType edit; protected final ReferenceType edit;
public NetworkConnectionSection(String type, URI href, String info, Integer primaryNetworkConnectionIndex, public NetworkConnectionSection(String type, URI href, String info, Integer primaryNetworkConnectionIndex,
Iterable<NetworkConnection> connections, ReferenceType edit) { Iterable<NetworkConnection> connections, ReferenceType edit) {
this.type = type; this.type = type;
this.href = href; this.href = href;
this.info = info; this.info = info;
this.primaryNetworkConnectionIndex = primaryNetworkConnectionIndex; this.primaryNetworkConnectionIndex = primaryNetworkConnectionIndex;
Iterables.addAll(this.connections, checkNotNull(connections, "connections")); this.connections = ImmutableSet.copyOf(checkNotNull(connections, "connections"));
this.edit = edit; this.edit = edit;
} }
@ -109,7 +161,7 @@ public class NetworkConnectionSection {
result = prime * result + ((href == null) ? 0 : href.hashCode()); result = prime * result + ((href == null) ? 0 : href.hashCode());
result = prime * result + ((info == null) ? 0 : info.hashCode()); result = prime * result + ((info == null) ? 0 : info.hashCode());
result = prime * result result = prime * result
+ ((primaryNetworkConnectionIndex == null) ? 0 : primaryNetworkConnectionIndex.hashCode()); + ((primaryNetworkConnectionIndex == null) ? 0 : primaryNetworkConnectionIndex.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode());
return result; return result;
} }
@ -156,10 +208,14 @@ public class NetworkConnectionSection {
return true; return true;
} }
public Builder toBuilder() {
return Builder.fromNetworkConnectionSection(this);
}
@Override @Override
public String toString() { public String toString() {
return "[href=" + href + ", connections=" + connections + ", primaryNetworkConnectionIndex=" return "[href=" + href + ", connections=" + connections + ", primaryNetworkConnectionIndex="
+ primaryNetworkConnectionIndex + "]"; + primaryNetworkConnectionIndex + "]";
} }
} }

View File

@ -0,0 +1,86 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.vcloud.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.vcloud.VCloudPropertiesBuilder;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
/**
* Tests behavior of {@code BindNetworkConnectionSectionToXmlPayload}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class BindNetworkConnectionSectionToXmlPayloadTest {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Properties props = new Properties();
Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties"));
}
});
public void testWithIpAllocationModeNONE() throws IOException {
@SuppressWarnings("rawtypes")
HttpRequest request = new HttpRequest.Builder().endpoint(URI.create("http://localhost/key")).method("GET")
.build();
BindNetworkConnectionSectionToXmlPayload binder = injector
.getInstance(BindNetworkConnectionSectionToXmlPayload.class);
binder.bindToRequest(
request,
NetworkConnectionSection
.builder()
.type("application/vnd.vmware.vcloud.networkConnectionSection+xml")
.info("Specifies the available VM network connections")
.href(URI.create("https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/"))
.connections(
ImmutableSet.<NetworkConnection> of(NetworkConnection.builder().network("none")
.ipAddressAllocationMode(IpAddressAllocationMode.NONE).build())).build());
assertEquals(request.getPayload().getContentMetadata().getContentType(),
"application/vnd.vmware.vcloud.networkConnectionSection+xml");
assertEquals(
request.getPayload().getRawContent(),
"<NetworkConnectionSection xmlns=\"http://www.vmware.com/vcloud/v1\" xmlns:ovf=\"http://schemas.dmtf.org/ovf/envelope/1\" href=\"https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/\" ovf:required=\"false\" type=\"application/vnd.vmware.vcloud.networkConnectionSection+xml\"><ovf:Info>Specifies the available VM network connections</ovf:Info><NetworkConnection network=\"none\"><NetworkConnectionIndex>0</NetworkConnectionIndex><IsConnected>false</IsConnected><IpAddressAllocationMode>NONE</IpAddressAllocationMode></NetworkConnection></NetworkConnectionSection>");
}
}

View File

@ -24,12 +24,14 @@ import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.b
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.customizationScript; import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.customizationScript;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.inboundPorts; import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.inboundPorts;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.installPrivateKey; import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.installPrivateKey;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.ipAddressAllocationMode;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.io.Payloads; import org.jclouds.io.Payloads;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -38,6 +40,18 @@ import org.testng.annotations.Test;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class VCloudTemplateOptionsTest { public class VCloudTemplateOptionsTest {
@Test
public void testipAddressAllocationMode() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
options.ipAddressAllocationMode(IpAddressAllocationMode.NONE);
assertEquals(options.getIpAddressAllocationMode(), IpAddressAllocationMode.NONE);
}
@Test
public void testipAddressAllocationModeStatic() {
VCloudTemplateOptions options = ipAddressAllocationMode(IpAddressAllocationMode.NONE);
assertEquals(options.getIpAddressAllocationMode(), IpAddressAllocationMode.NONE);
}
public void testAs() { public void testAs() {
TemplateOptions options = new VCloudTemplateOptions(); TemplateOptions options = new VCloudTemplateOptions();
@ -50,6 +64,12 @@ public class VCloudTemplateOptionsTest {
options.customizationScript(""); options.customizationScript("");
} }
@Test
public void testNullcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
assertEquals(options.getCustomizationScript(), null);
}
@Test @Test
public void testcustomizationScript() { public void testcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions(); VCloudTemplateOptions options = new VCloudTemplateOptions();
@ -57,12 +77,6 @@ public class VCloudTemplateOptionsTest {
assertEquals(options.getCustomizationScript(), "mykeypair"); assertEquals(options.getCustomizationScript(), "mykeypair");
} }
@Test
public void testNullcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
assertEquals(options.getCustomizationScript(), null);
}
@Test @Test
public void testcustomizationScriptStatic() { public void testcustomizationScriptStatic() {
VCloudTemplateOptions options = customizationScript("mykeypair"); VCloudTemplateOptions options = customizationScript("mykeypair");