mirror of https://github.com/apache/jclouds.git
Issue 290: added guest customization support
This commit is contained in:
parent
e5bd9bbfb8
commit
36dec74379
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
*
|
||||
* 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.bluelock;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.vcloud.VCloudGuestCustomizationLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.BlueLockVCloudDirectorGuestCustomizationLiveTest")
|
||||
public class BlueLockVCloudDirectorGuestCustomizationLiveTest extends VCloudGuestCustomizationLiveTest {
|
||||
|
||||
@Override
|
||||
protected void setupCredentials() {
|
||||
provider = "bluelock-vclouddirector";
|
||||
identity = checkNotNull(System.getProperty("bluelock-vclouddirector.identity"),
|
||||
"bluelock-vclouddirector.identity");
|
||||
credential = checkNotNull(System.getProperty("bluelock-vclouddirector.credential"),
|
||||
"bluelock-vclouddirector.credential");
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package org.jclouds.vcloud;
|
||||
|
||||
import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML;
|
||||
import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML;
|
||||
import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
|
||||
import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML;
|
||||
import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML;
|
||||
|
@ -34,11 +35,13 @@ import javax.ws.rs.Consumes;
|
|||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.predicates.validators.DnsNameValidator;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Endpoint;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
|
@ -52,8 +55,10 @@ import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
|||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||
import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload;
|
||||
import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload;
|
||||
import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload;
|
||||
import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload;
|
||||
import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload;
|
||||
import org.jclouds.vcloud.domain.GuestCustomizationSection;
|
||||
import org.jclouds.vcloud.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
|
@ -79,8 +84,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* Provides access to VCloud resources via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
|
||||
* />
|
||||
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequestFilters(SetVCloudTokenCookie.class)
|
||||
|
@ -183,6 +187,18 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
|
|||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends Vm> getVm(@EndpointParam URI vm);
|
||||
|
||||
/**
|
||||
* @see VCloudClient#updateGuestCustomizationOfVm
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(TASK_XML)
|
||||
@Produces(GUESTCUSTOMIZATIONSECTION_XML)
|
||||
@Path("/guestCustomizationSection")
|
||||
@XMLResponseParser(TaskHandler.class)
|
||||
ListenableFuture<? extends Task> updateGuestCustomizationOfVm(
|
||||
@EndpointParam URI vm,
|
||||
@BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection);
|
||||
|
||||
/**
|
||||
* @see VCloudClient#deployVAppOrVm
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.vcloud.domain.GuestCustomizationSection;
|
||||
import org.jclouds.vcloud.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
|
@ -40,16 +41,14 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
|||
* Provides access to VCloud resources via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @see <a
|
||||
* href="http://communities.vmware.com/community/developer/forums/vcloudapi"
|
||||
* />
|
||||
* @see <a href="http://communities.vmware.com/community/developer/forums/vcloudapi" />
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
|
||||
public interface VCloudClient extends CommonVCloudClient {
|
||||
/**
|
||||
* The response to a login request includes a list of the organizations to
|
||||
* which the authenticated user has access.
|
||||
* The response to a login request includes a list of the organizations to which the
|
||||
* authenticated user has access.
|
||||
*
|
||||
* @return organizations indexed by name
|
||||
*/
|
||||
|
@ -64,9 +63,19 @@ public interface VCloudClient extends CommonVCloudClient {
|
|||
OvfEnvelope getOvfEnvelopeForVAppTemplate(URI vAppTemplate);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Modify the Guest Customization Section of a Virtual Machine
|
||||
*
|
||||
* @param vm
|
||||
* uri to modify
|
||||
* @param updated
|
||||
* guestCustomizationSection
|
||||
* @return task in progress
|
||||
*/
|
||||
Task updateGuestCustomizationOfVm(URI vm, GuestCustomizationSection guestCustomizationSection);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param orgName
|
||||
* organization name, or null for the default
|
||||
|
@ -76,8 +85,7 @@ public interface VCloudClient extends CommonVCloudClient {
|
|||
* item you wish to lookup
|
||||
*
|
||||
* @throws NoSuchElementException
|
||||
* 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,
|
||||
String itemName);
|
||||
|
@ -89,109 +97,97 @@ public interface VCloudClient extends CommonVCloudClient {
|
|||
Vm getVm(URI vm);
|
||||
|
||||
/**
|
||||
* To deploy a vApp, the client makes a request to its action/deploy URL.
|
||||
* Deploying a vApp automatically deploys all of the virtual machines it
|
||||
* contains. To deploy a virtual machine, the client makes a request to its
|
||||
* action/deploy URL.
|
||||
* To deploy a vApp, the client makes a request to its action/deploy URL. Deploying a vApp
|
||||
* automatically deploys all of the virtual machines it contains. To deploy a virtual machine,
|
||||
* the client makes a request to its action/deploy URL.
|
||||
* <p/>
|
||||
* Deploying a Vm implicitly deploys the parent vApp if that vApp is not
|
||||
* already deployed.
|
||||
* Deploying a Vm implicitly deploys the parent vApp if that vApp is not already deployed.
|
||||
*/
|
||||
Task deployVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on
|
||||
* state
|
||||
* like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on state
|
||||
*
|
||||
*/
|
||||
Task deployAndPowerOnVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* Undeploying a vApp powers off or suspends any running virtual machines it
|
||||
* contains, then frees the resources reserved for the vApp and sets the
|
||||
* vApp’s deploy attribute to a value of false to indicate that it is not
|
||||
* deployed.
|
||||
* Undeploying a vApp powers off or suspends any running virtual machines it contains, then frees
|
||||
* the resources reserved for the vApp and sets the vApp’s deploy attribute to a value of false
|
||||
* to indicate that it is not deployed.
|
||||
* <p/>
|
||||
* Undeploying a virtual machine powers off or suspends the virtual machine,
|
||||
* then frees the resources reserved for it and sets the its deploy attribute
|
||||
* to a value of false to indicate that it is not deployed. This operation
|
||||
* has no effect on the containing vApp.
|
||||
* Undeploying a virtual machine powers off or suspends the virtual machine, then frees the
|
||||
* resources reserved for it and sets the its deploy attribute to a value of false to indicate
|
||||
* that it is not deployed. This operation has no effect on the containing vApp.
|
||||
* <h4>NOTE</h4>
|
||||
* Using this method will simply power off the vms. In order to save their
|
||||
* state, use {@link #undeployAndSaveStateOfVAppOrVm}
|
||||
* Using this method will simply power off the vms. In order to save their state, use
|
||||
* {@link #undeployAndSaveStateOfVAppOrVm}
|
||||
*
|
||||
*/
|
||||
Task undeployVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines
|
||||
* are suspended and their suspend state saved
|
||||
* like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines are suspended and
|
||||
* their suspend state saved
|
||||
*
|
||||
*/
|
||||
Task undeployAndSaveStateOfVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A powerOn request to a vApp URL powers on all of the virtual machines in
|
||||
* the vApp, as specified in the vApp’s StartupSection field.
|
||||
* A powerOn request to a vApp URL powers on all of the virtual machines in the vApp, as
|
||||
* specified in the vApp’s StartupSection field.
|
||||
* <p/>
|
||||
* A powerOn request to a virtual machine URL powers on the specified virtual
|
||||
* machine and forces deployment of the parent vApp.
|
||||
* A powerOn request to a virtual machine URL powers on the specified virtual machine and forces
|
||||
* deployment of the parent vApp.
|
||||
* <p/>
|
||||
* <h4>NOTE</h4> A powerOn request to a vApp or virtual machine that is
|
||||
* undeployed forces deployment.
|
||||
* <h4>NOTE</h4> A powerOn request to a vApp or virtual machine that is undeployed forces
|
||||
* deployment.
|
||||
*/
|
||||
Task powerOnVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A powerOff request to a vApp URL powers off all of the virtual machines in
|
||||
* the vApp, as specified in its StartupSection field.
|
||||
* A powerOff request to a vApp URL powers off all of the virtual machines in the vApp, as
|
||||
* specified in its StartupSection field.
|
||||
* <p/>
|
||||
* A powerOff request to a virtual machine URL powers off the specified
|
||||
* virtual machine.
|
||||
* A powerOff request to a virtual machine URL powers off the specified virtual machine.
|
||||
*/
|
||||
Task powerOffVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A shutdown request to a vApp URL shuts down all of the virtual machines in
|
||||
* the vApp, as specified in its StartupSection field.
|
||||
* A shutdown request to a vApp URL shuts down all of the virtual machines in the vApp, as
|
||||
* specified in its StartupSection field.
|
||||
* <p/>
|
||||
* A shutdown request to a virtual machine URL shuts down the specified
|
||||
* virtual machine.
|
||||
* A shutdown request to a virtual machine URL shuts down the specified virtual machine.
|
||||
* <p/>
|
||||
* <h4>NOTE</h4Because this request sends a signal to the guest OS, the
|
||||
* vCloud API cannot track the progress or verify the result of the requested
|
||||
* operation. Hence, void is returned
|
||||
* <h4>NOTE</h4Because this request sends a signal to the guest OS, the vCloud API cannot track
|
||||
* the progress or verify the result of the requested operation. Hence, void is returned
|
||||
*/
|
||||
void shutdownVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A reset request to a vApp URL resets all of the virtual machines in the
|
||||
* vApp, as specified in its StartupSection field.
|
||||
* A reset request to a vApp URL resets all of the virtual machines in the vApp, as specified in
|
||||
* its StartupSection field.
|
||||
* <p/>
|
||||
* A reset request to a virtual machine URL resets the specified virtual
|
||||
* machine.
|
||||
* A reset request to a virtual machine URL resets the specified virtual machine.
|
||||
*/
|
||||
Task resetVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A reboot request to a vApp URL reboots all of the virtual machines in the
|
||||
* vApp, as specified in its StartupSection field.
|
||||
* A reboot request to a vApp URL reboots all of the virtual machines in the vApp, as specified
|
||||
* in its StartupSection field.
|
||||
* <p/>
|
||||
* A reboot request to a virtual machine URL reboots the specified virtual
|
||||
* machine.
|
||||
* A reboot request to a virtual machine URL reboots the specified virtual machine.
|
||||
* <p/>
|
||||
* <h4>NOTE</h4> Because this request sends a signal to the guest OS, the
|
||||
* vCloud API cannot track the progress or verify the result of the requested
|
||||
* operation. Hence, void is returned
|
||||
* <h4>NOTE</h4> Because this request sends a signal to the guest OS, the vCloud API cannot track
|
||||
* the progress or verify the result of the requested operation. Hence, void is returned
|
||||
*/
|
||||
void rebootVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
/**
|
||||
* A suspend request to a vApp URL suspends all of the virtual machines in
|
||||
* the vApp, as specified in its StartupSection field.
|
||||
* A suspend request to a vApp URL suspends all of the virtual machines in the vApp, as specified
|
||||
* in its StartupSection field.
|
||||
* <p/>
|
||||
* A suspend request to a virtual machine URL suspends the specified virtual
|
||||
* machine.
|
||||
* A suspend request to a virtual machine URL suspends the specified virtual machine.
|
||||
*/
|
||||
Task suspendVAppOrVm(URI vAppOrVmId);
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
*
|
||||
* 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.GuestCustomizationSection;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.Inject;
|
||||
import com.jamesmurty.utils.XMLBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class BindGuestCustomizationSectionToXmlPayload extends BindToStringPayload {
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final String ns;
|
||||
protected final String schema;
|
||||
|
||||
@Inject
|
||||
public BindGuestCustomizationSectionToXmlPayload(BindToStringPayload stringBinder,
|
||||
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
|
||||
this.ns = ns;
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
public void bindToRequest(HttpRequest request, Object payload) {
|
||||
checkArgument(checkNotNull(payload, "GuestCustomizationSection") instanceof GuestCustomizationSection,
|
||||
"this binder is only valid for GuestCustomizationSection!");
|
||||
GuestCustomizationSection guest = GuestCustomizationSection.class.cast(payload);
|
||||
XMLBuilder guestCustomizationSection;
|
||||
try {
|
||||
guestCustomizationSection = XMLBuilder.create("GuestCustomizationSection").a("xmlns", ns).a("xmlns:ovf",
|
||||
"http://schemas.dmtf.org/ovf/envelope/1").a("type", guest.getType()).a("href",
|
||||
guest.getHref().toASCIIString()).a("ovf:required", "false");
|
||||
guestCustomizationSection.e("ovf:Info").t(guest.getInfo());
|
||||
|
||||
if (guest.isEnabled() != null)
|
||||
guestCustomizationSection.e("Enabled").t(guest.isEnabled().toString());
|
||||
if (guest.shouldChangeSid() != null)
|
||||
guestCustomizationSection.e("ChangeSid").t(guest.shouldChangeSid().toString());
|
||||
if (guest.getVirtualMachineId() != null)
|
||||
guestCustomizationSection.e("VirtualMachineId").t(guest.getVirtualMachineId().toString());
|
||||
if (guest.isJoinDomainEnabled() != null)
|
||||
guestCustomizationSection.e("JoinDomainEnabled").t(guest.isJoinDomainEnabled().toString());
|
||||
if (guest.shouldUseOrgSettings() != null)
|
||||
guestCustomizationSection.e("UseOrgSettings").t(guest.shouldUseOrgSettings().toString());
|
||||
if (guest.getDomainName() != null)
|
||||
guestCustomizationSection.e("DomainName").t(guest.getDomainName().toString());
|
||||
if (guest.getDomainUserName() != null)
|
||||
guestCustomizationSection.e("DomainUserName").t(guest.getDomainUserName().toString());
|
||||
if (guest.getDomainUserPassword() != null)
|
||||
guestCustomizationSection.e("DomainUserPassword").t(guest.getDomainUserPassword().toString());
|
||||
if (guest.isAdminPasswordEnabled() != null)
|
||||
guestCustomizationSection.e("AdminPasswordEnabled").t(guest.isAdminPasswordEnabled().toString());
|
||||
if (guest.isAdminPasswordAuto() != null)
|
||||
guestCustomizationSection.e("AdminPasswordAuto").t(guest.isAdminPasswordAuto().toString());
|
||||
// if (guest.getAdminPassword() != null)
|
||||
// guestCustomizationSection.e("AdminPassword").t(guest.getAdminPassword().toString());
|
||||
if (guest.isResetPasswordRequired() != null)
|
||||
guestCustomizationSection.e("ResetPasswordRequired").t(guest.isResetPasswordRequired().toString());
|
||||
if (guest.getCustomizationScript() != null)
|
||||
guestCustomizationSection.e("CustomizationScript").t(guest.getCustomizationScript());
|
||||
if (guest.getComputerName() != null)
|
||||
guestCustomizationSection.e("ComputerName").t(guest.getComputerName().toString());
|
||||
if (guest.getEdit() != null)
|
||||
guestCustomizationSection.e("Link").a("rel", "edit").a("type", guest.getType()).a("href",
|
||||
guest.getHref().toASCIIString());
|
||||
|
||||
Properties outputProperties = new Properties();
|
||||
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
super.bindToRequest(request, guestCustomizationSection.asString(outputProperties));
|
||||
request.getPayload().setContentType(guest.getType());
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ import java.util.Map;
|
|||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
@ -45,11 +46,13 @@ import org.jclouds.rest.binders.BindToStringPayload;
|
|||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||
import org.jclouds.vcloud.domain.Vm;
|
||||
import org.jclouds.vcloud.domain.network.FenceMode;
|
||||
import org.jclouds.vcloud.domain.network.NetworkConfig;
|
||||
import org.jclouds.vcloud.endpoints.Network;
|
||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -73,18 +76,20 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
protected final URI defaultNetwork;
|
||||
protected final FenceMode defaultFenceMode;
|
||||
protected final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate;
|
||||
protected final VCloudClient client;
|
||||
|
||||
@Inject
|
||||
public BindInstantiateVAppTemplateParamsToXmlPayload(DefaultNetworkNameInTemplate defaultNetworkNameInTemplate,
|
||||
BindToStringPayload stringBinder, @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns,
|
||||
@Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema, @Network URI network,
|
||||
@Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode) {
|
||||
@Named(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) String fenceMode, VCloudClient client) {
|
||||
this.defaultNetworkNameInTemplate = defaultNetworkNameInTemplate;
|
||||
this.ns = ns;
|
||||
this.schema = schema;
|
||||
this.stringBinder = stringBinder;
|
||||
this.defaultNetwork = network;
|
||||
this.defaultFenceMode = FenceMode.fromValue(fenceMode);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -98,11 +103,12 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
|
||||
boolean deploy = true;
|
||||
boolean powerOn = true;
|
||||
Boolean customizeOnInstantiate = null;
|
||||
|
||||
Set<? extends NetworkConfig> networkConfig = null;
|
||||
|
||||
NetworknetworkConfigDecorator networknetworkConfigDecorator = new NetworknetworkConfigDecorator(template,
|
||||
defaultNetwork, defaultFenceMode, defaultNetworkNameInTemplate);
|
||||
NetworkConfigDecorator networknetworkConfigDecorator = new NetworkConfigDecorator(template, defaultNetwork,
|
||||
defaultFenceMode, defaultNetworkNameInTemplate);
|
||||
|
||||
InstantiateVAppTemplateOptions options = findOptionsInArgsOrNull(gRequest);
|
||||
|
||||
|
@ -110,16 +116,17 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
if (options.getNetworkConfig().size() > 0)
|
||||
networkConfig = Sets.newLinkedHashSet(Iterables.transform(options.getNetworkConfig(),
|
||||
networknetworkConfigDecorator));
|
||||
|
||||
deploy = ifNullDefaultTo(options.shouldDeploy(), deploy);
|
||||
powerOn = ifNullDefaultTo(options.shouldPowerOn(), powerOn);
|
||||
customizeOnInstantiate = options.shouldCustomizeOnInstantiate();
|
||||
}
|
||||
|
||||
if (networkConfig == null)
|
||||
networkConfig = ImmutableSet.of(networknetworkConfigDecorator.apply(null));
|
||||
|
||||
try {
|
||||
stringBinder.bindToRequest(request, generateXml(name, deploy, powerOn, template, networkConfig));
|
||||
stringBinder.bindToRequest(request, generateXml(name, deploy, powerOn, template, networkConfig,
|
||||
customizeOnInstantiate));
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (FactoryConfigurationError e) {
|
||||
|
@ -130,13 +137,25 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
|
||||
}
|
||||
|
||||
protected static final class NetworknetworkConfigDecorator implements Function<NetworkConfig, NetworkConfig> {
|
||||
@VisibleForTesting
|
||||
Set<? extends Vm> ifCustomizationScriptIsSetGetVmsInTemplate(String customizationScript, final URI template) {
|
||||
Set<? extends Vm> vms = Sets.newLinkedHashSet();
|
||||
if (customizationScript != null) {
|
||||
VAppTemplate vAppTemplate = client.getVAppTemplate(template);
|
||||
checkArgument(vAppTemplate != null, "vAppTemplate %s not found!", template);
|
||||
vms = vAppTemplate.getChildren();
|
||||
checkArgument(vms.size() > 0, "no vms found in vAppTemplate %s", vAppTemplate);
|
||||
}
|
||||
return vms;
|
||||
}
|
||||
|
||||
protected static final class NetworkConfigDecorator implements Function<NetworkConfig, NetworkConfig> {
|
||||
private final URI template;
|
||||
private final URI defaultNetwork;
|
||||
private final FenceMode defaultFenceMode;
|
||||
private final DefaultNetworkNameInTemplate defaultNetworkNameInTemplate;
|
||||
|
||||
protected NetworknetworkConfigDecorator(URI template, URI defaultNetwork, FenceMode defaultFenceMode,
|
||||
protected NetworkConfigDecorator(URI template, URI defaultNetwork, FenceMode defaultFenceMode,
|
||||
DefaultNetworkNameInTemplate defaultNetworkNameInTemplate) {
|
||||
this.template = checkNotNull(template, "template");
|
||||
this.defaultNetwork = checkNotNull(defaultNetwork, "defaultNetwork");
|
||||
|
@ -180,17 +199,15 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
networkName = Iterables.get(networks, 0).getName();
|
||||
return networkName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String generateXml(String name, boolean deploy, boolean powerOn, URI template,
|
||||
Iterable<? extends NetworkConfig> networkConfig) throws ParserConfigurationException,
|
||||
FactoryConfigurationError, TransformerException {
|
||||
Iterable<? extends NetworkConfig> networkConfig, @Nullable Boolean customizeOnInstantiate)
|
||||
throws ParserConfigurationException, FactoryConfigurationError, TransformerException {
|
||||
XMLBuilder rootBuilder = buildRoot(name).a("deploy", deploy + "").a("powerOn", powerOn + "");
|
||||
|
||||
XMLBuilder instantiationParamsBuilder = rootBuilder.e("InstantiationParams");
|
||||
addNetworkConfig(instantiationParamsBuilder, networkConfig);
|
||||
|
||||
addCustomizationConfig(instantiationParamsBuilder, customizeOnInstantiate);
|
||||
rootBuilder.e("Source").a("href", template.toASCIIString());
|
||||
rootBuilder.e("AllEULAsAccepted").t("true");
|
||||
|
||||
|
@ -199,6 +216,14 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder
|
|||
return rootBuilder.asString(outputProperties);
|
||||
}
|
||||
|
||||
protected void addCustomizationConfig(XMLBuilder instantiationParamsBuilder, Boolean customizeOnInstantiate) {
|
||||
if (customizeOnInstantiate != null) {
|
||||
// XMLBuilder customizationSectionBuilder = instantiationParamsBuilder.e("CustomizationSection");
|
||||
// customizationSectionBuilder.e("ovf:Info").t("VApp template customization section");
|
||||
// customizationSectionBuilder.e("CustomizeOnInstantiate").t(customizeOnInstantiate.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected void addNetworkConfig(XMLBuilder instantiationParamsBuilder,
|
||||
Iterable<? extends NetworkConfig> networkConfig) {
|
||||
XMLBuilder networkConfigBuilder = instantiationParamsBuilder.e("NetworkConfigSection");
|
||||
|
|
|
@ -24,7 +24,9 @@ import java.util.Set;
|
|||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
|
@ -36,6 +38,8 @@ import org.jclouds.rest.internal.RestContextImpl;
|
|||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.functions.ImagesInOrg;
|
||||
import org.jclouds.vcloud.compute.functions.SizesInOrg;
|
||||
import org.jclouds.vcloud.compute.internal.VCloudTemplateBuilderImpl;
|
||||
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
|
||||
import org.jclouds.vcloud.compute.strategy.GetLoginCredentialsFromGuestConfiguration;
|
||||
import org.jclouds.vcloud.compute.strategy.VCloudAddNodeWithTagStrategy;
|
||||
import org.jclouds.vcloud.compute.strategy.VCloudDestroyNodeStrategy;
|
||||
|
@ -62,6 +66,8 @@ public class VCloudComputeServiceContextModule extends CommonVCloudComputeServic
|
|||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(TemplateOptions.class).to(VCloudTemplateOptions.class);
|
||||
bind(TemplateBuilder.class).to(VCloudTemplateBuilderImpl.class);
|
||||
bind(RebootNodeStrategy.class).to(VCloudRebootNodeStrategy.class);
|
||||
bind(GetNodeMetadataStrategy.class).to(VCloudGetNodeMetadataStrategy.class);
|
||||
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||
|
|
|
@ -19,70 +19,38 @@
|
|||
|
||||
package org.jclouds.vcloud.compute.functions;
|
||||
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Maps.newHashMap;
|
||||
import static org.jclouds.vcloud.predicates.VCloudPredicates.resourceType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.compute.internal.VCloudExpressComputeClientImpl;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.Vm;
|
||||
import org.jclouds.vcloud.domain.ovf.ResourceAllocation;
|
||||
import org.jclouds.vcloud.domain.ovf.ResourceType;
|
||||
import org.jclouds.vcloud.domain.ovf.VCloudHardDisk;
|
||||
import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Configures the {@link VCloudComputeServiceContext}; requires
|
||||
* {@link VCloudExpressComputeClientImpl} bound.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class GetExtraFromVApp implements Function<VApp, Map<String, String>> {
|
||||
private final GetExtraFromVm getExtraFromVm;
|
||||
|
||||
@Inject
|
||||
GetExtraFromVApp(GetExtraFromVm getExtraFromVm) {
|
||||
this.getExtraFromVm = getExtraFromVm;
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public Map<String, String> apply(VApp vApp) {
|
||||
Map<String, String> extra = newHashMap();
|
||||
try {
|
||||
// TODO make this work with composite vApps
|
||||
Vm vm = Iterables.get(vApp.getChildren(), 0);
|
||||
extra.put("memory/mb", find(vm.getVirtualHardwareSection().getResourceAllocations(), resourceType(ResourceType.MEMORY))
|
||||
.getVirtualQuantity()
|
||||
+ "");
|
||||
extra.put("processor/count", find(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.PROCESSOR)).getVirtualQuantity()
|
||||
+ "");
|
||||
for (ResourceAllocation disk : filter(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.DISK_DRIVE))) {
|
||||
if (disk instanceof VCloudHardDisk) {
|
||||
VCloudHardDisk vDisk = VCloudHardDisk.class.cast(disk);
|
||||
extra.put(String.format("disk_drive/%s/mb", disk.getAddressOnParent()), vDisk.getCapacity() + "");
|
||||
} else {
|
||||
extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), disk.getVirtualQuantity() + "");
|
||||
}
|
||||
}
|
||||
for (ResourceAllocation net : filter(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.ETHERNET_ADAPTER))) {
|
||||
if (net instanceof VCloudNetworkAdapter) {
|
||||
VCloudNetworkAdapter vNet = VCloudNetworkAdapter.class.cast(net);
|
||||
extra.put(String.format("network/%s/ip", net.getAddressOnParent()), vNet.getIpAddress());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "error getting extra data for vApp: %s", vApp);
|
||||
}
|
||||
return extra;
|
||||
return vApp.getChildren().size() == 0 ? ImmutableMap.<String, String> of() : getExtraFromVm.apply(Iterables.get(
|
||||
vApp.getChildren(), 0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* 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.compute.functions;
|
||||
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Maps.newHashMap;
|
||||
import static org.jclouds.vcloud.predicates.VCloudPredicates.resourceType;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.domain.Vm;
|
||||
import org.jclouds.vcloud.domain.ovf.ResourceAllocation;
|
||||
import org.jclouds.vcloud.domain.ovf.ResourceType;
|
||||
import org.jclouds.vcloud.domain.ovf.VCloudHardDisk;
|
||||
import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class GetExtraFromVm implements Function<Vm, Map<String, String>> {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
public Map<String, String> apply(Vm vm) {
|
||||
Map<String, String> extra = newHashMap();
|
||||
try {
|
||||
extra.put("memory/mb", find(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.MEMORY)).getVirtualQuantity()
|
||||
+ "");
|
||||
extra.put("processor/count", find(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.PROCESSOR)).getVirtualQuantity()
|
||||
+ "");
|
||||
for (ResourceAllocation disk : filter(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.DISK_DRIVE))) {
|
||||
if (disk instanceof VCloudHardDisk) {
|
||||
VCloudHardDisk vDisk = VCloudHardDisk.class.cast(disk);
|
||||
extra.put(String.format("disk_drive/%s/mb", disk.getAddressOnParent()), vDisk.getCapacity() + "");
|
||||
} else {
|
||||
extra.put(String.format("disk_drive/%s/kb", disk.getAddressOnParent()), disk.getVirtualQuantity() + "");
|
||||
}
|
||||
}
|
||||
for (ResourceAllocation net : filter(vm.getVirtualHardwareSection().getResourceAllocations(),
|
||||
resourceType(ResourceType.ETHERNET_ADAPTER))) {
|
||||
if (net instanceof VCloudNetworkAdapter) {
|
||||
VCloudNetworkAdapter vNet = VCloudNetworkAdapter.class.cast(net);
|
||||
extra.put(String.format("network/%s/ip", net.getAddressOnParent()), vNet.getIpAddress());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "error getting extra data for vm: %s", vm);
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
*
|
||||
* 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.compute.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VCloudTemplateBuilderImpl extends TemplateBuilderImpl {
|
||||
|
||||
@Inject
|
||||
protected VCloudTemplateBuilderImpl(Supplier<Set<? extends Location>> locations,
|
||||
Supplier<Set<? extends Image>> images, Supplier<Set<? extends Size>> sizes,
|
||||
Supplier<Location> defaultLocation, Provider<TemplateOptions> optionsProvider,
|
||||
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
|
||||
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void copyTemplateOptions(TemplateOptions from, TemplateOptions to) {
|
||||
super.copyTemplateOptions(from, to);
|
||||
if (from instanceof VCloudTemplateOptions) {
|
||||
VCloudTemplateOptions eFrom = VCloudTemplateOptions.class.cast(from);
|
||||
VCloudTemplateOptions eTo = VCloudTemplateOptions.class.cast(to);
|
||||
if (eFrom.getCustomizationScript() != null)
|
||||
eTo.customizationScript(eFrom.getCustomizationScript());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/**
|
||||
*
|
||||
* 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.compute.options;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.util.Utils;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on the "vcloud"
|
||||
* provider. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a VCloudTemplateOptions object is to statically
|
||||
* import VCloudTemplateOptions.* and invoke a static creation method followed by an instance
|
||||
* mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.compute.options.VCloudTemplateOptions.Builder.*;
|
||||
* <p/>
|
||||
* ComputeService client = // get connection
|
||||
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
|
||||
* Set<? extends NodeMetadata> set = client.runNodesWithTag(tag, 2, templateBuilder.build());
|
||||
* <code>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VCloudTemplateOptions extends TemplateOptions {
|
||||
|
||||
private String customizationScript = null;
|
||||
|
||||
public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions();
|
||||
|
||||
/**
|
||||
* Specifies the customizationScript used to run instances with
|
||||
*/
|
||||
public VCloudTemplateOptions customizationScript(String customizationScript) {
|
||||
Utils.checkNotEmpty(customizationScript, "customizationScript must be non-empty");
|
||||
this.customizationScript = customizationScript;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see VCloudTemplateOptions#customizationScript
|
||||
*/
|
||||
public static VCloudTemplateOptions customizationScript(String customizationScript) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript));
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
/**
|
||||
* @see TemplateOptions#inboundPorts
|
||||
*/
|
||||
public static VCloudTemplateOptions inboundPorts(int... ports) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.inboundPorts(ports));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#port
|
||||
*/
|
||||
public static VCloudTemplateOptions blockOnPort(int port, int seconds) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.blockOnPort(port, seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript
|
||||
*/
|
||||
public static VCloudTemplateOptions runScript(Payload script) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey
|
||||
*/
|
||||
public static VCloudTemplateOptions installPrivateKey(Payload rsaKey) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.installPrivateKey(rsaKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey
|
||||
*/
|
||||
public static VCloudTemplateOptions authorizePublicKey(Payload rsaKey) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withDetails
|
||||
*/
|
||||
public static VCloudTemplateOptions withDetails() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.withMetadata());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return customizationScript on the vms
|
||||
*/
|
||||
public String getCustomizationScript() {
|
||||
return customizationScript;
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#blockOnPort
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions blockOnPort(int port, int seconds) {
|
||||
return VCloudTemplateOptions.class.cast(super.blockOnPort(port, seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* special thing is that we do assume if you are passing groups that you have everything you need
|
||||
* already defined. for example, our option inboundPorts normally creates ingress rules
|
||||
* accordingly but if we notice you've specified securityGroups, we do not mess with rules at all
|
||||
*
|
||||
* @see TemplateOptions#inboundPorts
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions inboundPorts(int... ports) {
|
||||
return VCloudTemplateOptions.class.cast(super.inboundPorts(ports));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public VCloudTemplateOptions authorizePublicKey(String publicKey) {
|
||||
return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#authorizePublicKey(Payload)
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions authorizePublicKey(Payload publicKey) {
|
||||
return VCloudTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey(String)
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public VCloudTemplateOptions installPrivateKey(String privateKey) {
|
||||
return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#installPrivateKey(Payload)
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions installPrivateKey(Payload privateKey) {
|
||||
return VCloudTemplateOptions.class.cast(super.installPrivateKey(privateKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript(Payload)
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions runScript(Payload script) {
|
||||
return VCloudTemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#runScript(byte[])
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public VCloudTemplateOptions runScript(byte[] script) {
|
||||
return VCloudTemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions withMetadata() {
|
||||
return VCloudTemplateOptions.class.cast(super.withMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
VCloudTemplateOptions other = (VCloudTemplateOptions) obj;
|
||||
if (customizationScript == null) {
|
||||
if (other.customizationScript != null)
|
||||
return false;
|
||||
} else if (!customizationScript.equals(other.customizationScript))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[customizationScript=" + customizationScript + ", inboundPorts=" + Arrays.toString(inboundPorts)
|
||||
+ ", privateKey=" + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript="
|
||||
+ (script != null) + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata
|
||||
+ "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -35,11 +35,15 @@ import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
|||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
|
||||
import org.jclouds.vcloud.domain.GuestCustomizationSection;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.Vm;
|
||||
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -66,6 +70,17 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
public NodeMetadata execute(String tag, String name, Template template) {
|
||||
InstantiateVAppTemplateOptions options = processorCount(Double.valueOf(template.getSize().getCores()).intValue())
|
||||
.memory(template.getSize().getRam()).disk(template.getSize().getDisk() * 1024 * 1024l);
|
||||
|
||||
String customizationScript = null;
|
||||
if (template.getOptions() instanceof VCloudTemplateOptions) {
|
||||
customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript();
|
||||
if (customizationScript != null) {
|
||||
options.customizeOnInstantiate(false);
|
||||
options.deploy(false);
|
||||
options.powerOn(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!template.getOptions().shouldBlockUntilRunning())
|
||||
options.block(false);
|
||||
|
||||
|
@ -78,6 +93,35 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
|||
logger.debug("<< instantiated VApp(%s)", vAppResponse.getName());
|
||||
|
||||
Task task = vAppResponse.getTasks().get(0);
|
||||
|
||||
if (customizationScript == null) {
|
||||
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
|
||||
} else {
|
||||
if (!successTester.apply(task.getHref())) {
|
||||
throw new RuntimeException(String
|
||||
.format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task));
|
||||
}
|
||||
Vm vm = Iterables.get(client.getVApp(vAppResponse.getHref()).getChildren(), 0);
|
||||
GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection();
|
||||
// guestConfiguration
|
||||
// .setCustomizationScript(guestConfiguration.getCustomizationScript() != null ?
|
||||
// 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());
|
||||
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private NodeMetadata blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse,
|
||||
Task task) {
|
||||
if (options.shouldBlock()) {
|
||||
if (!successTester.apply(task.getHref())) {
|
||||
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on", vAppResponse
|
||||
|
|
|
@ -21,30 +21,39 @@ package org.jclouds.vcloud.domain;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
|
||||
/**
|
||||
* The GuestCustomization of a Vm contains customization parameters for the guest
|
||||
* operating system of the virtual machine.
|
||||
* The GuestCustomization of a Vm contains customization parameters for the guest operating system
|
||||
* of the virtual machine.
|
||||
*/
|
||||
public class GuestCustomizationSection {
|
||||
protected final String type;
|
||||
protected final URI href;
|
||||
protected final String info;
|
||||
protected final Boolean enabled;
|
||||
protected final Boolean changeSid;
|
||||
protected final String virtualMachineId;
|
||||
protected final Boolean joinDomainEnabled;
|
||||
protected final Boolean useOrgSettings;
|
||||
protected final String domainName;
|
||||
protected final String domainUserName;
|
||||
protected final String domainUserPassword;
|
||||
protected final Boolean adminPasswordEnabled;
|
||||
protected final Boolean adminPasswordAuto;
|
||||
protected final String adminPassword;
|
||||
protected final Boolean resetPasswordRequired;
|
||||
protected final String customizationScript;
|
||||
protected final String computerName;
|
||||
protected String info;
|
||||
protected Boolean enabled;
|
||||
protected Boolean changeSid;
|
||||
protected String virtualMachineId;
|
||||
protected Boolean joinDomainEnabled;
|
||||
protected Boolean useOrgSettings;
|
||||
protected String domainName;
|
||||
protected String domainUserName;
|
||||
protected String domainUserPassword;
|
||||
protected Boolean adminPasswordEnabled;
|
||||
protected Boolean adminPasswordAuto;
|
||||
protected String adminPassword;
|
||||
protected Boolean resetPasswordRequired;
|
||||
protected String customizationScript;
|
||||
protected String computerName;
|
||||
protected final ReferenceType edit;
|
||||
|
||||
public GuestCustomizationSection(URI href) {
|
||||
this.href = href;
|
||||
this.type = VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML;
|
||||
this.info = "Specifies Guest OS Customization Settings";
|
||||
this.edit = null;
|
||||
}
|
||||
|
||||
public GuestCustomizationSection(String type, URI href, String info, Boolean enabled, Boolean changeSid,
|
||||
String virtualMachineId, Boolean joinDomainEnabled, Boolean useOrgSettings, String domainName,
|
||||
String domainUserName, String domainUserPassword, Boolean adminPasswordEnabled, Boolean adminPasswordAuto,
|
||||
|
@ -223,7 +232,7 @@ public class GuestCustomizationSection {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((adminPassword == null) ? 0 : adminPassword.hashCode());
|
||||
result = prime * result + ((adminPasswordAuto == null) ? 0 : adminPasswordAuto.hashCode());
|
||||
|
@ -347,4 +356,88 @@ public class GuestCustomizationSection {
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Boolean getChangeSid() {
|
||||
return changeSid;
|
||||
}
|
||||
|
||||
public void setChangeSid(Boolean changeSid) {
|
||||
this.changeSid = changeSid;
|
||||
}
|
||||
|
||||
public Boolean getJoinDomainEnabled() {
|
||||
return joinDomainEnabled;
|
||||
}
|
||||
|
||||
public void setJoinDomainEnabled(Boolean joinDomainEnabled) {
|
||||
this.joinDomainEnabled = joinDomainEnabled;
|
||||
}
|
||||
|
||||
public Boolean shouldUseOrgSettings() {
|
||||
return useOrgSettings;
|
||||
}
|
||||
|
||||
public void setUseOrgSettings(Boolean useOrgSettings) {
|
||||
this.useOrgSettings = useOrgSettings;
|
||||
}
|
||||
|
||||
public Boolean getAdminPasswordEnabled() {
|
||||
return adminPasswordEnabled;
|
||||
}
|
||||
|
||||
public void setAdminPasswordEnabled(Boolean adminPasswordEnabled) {
|
||||
this.adminPasswordEnabled = adminPasswordEnabled;
|
||||
}
|
||||
|
||||
public Boolean getAdminPasswordAuto() {
|
||||
return adminPasswordAuto;
|
||||
}
|
||||
|
||||
public void setAdminPasswordAuto(Boolean adminPasswordAuto) {
|
||||
this.adminPasswordAuto = adminPasswordAuto;
|
||||
}
|
||||
|
||||
public Boolean getResetPasswordRequired() {
|
||||
return resetPasswordRequired;
|
||||
}
|
||||
|
||||
public void setResetPasswordRequired(Boolean resetPasswordRequired) {
|
||||
this.resetPasswordRequired = resetPasswordRequired;
|
||||
}
|
||||
|
||||
public void setInfo(String info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void setVirtualMachineId(String virtualMachineId) {
|
||||
this.virtualMachineId = virtualMachineId;
|
||||
}
|
||||
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public void setDomainUserName(String domainUserName) {
|
||||
this.domainUserName = domainUserName;
|
||||
}
|
||||
|
||||
public void setDomainUserPassword(String domainUserPassword) {
|
||||
this.domainUserPassword = domainUserPassword;
|
||||
}
|
||||
|
||||
public void setAdminPassword(String adminPassword) {
|
||||
this.adminPassword = adminPassword;
|
||||
}
|
||||
|
||||
public void setCustomizationScript(String customizationScript) {
|
||||
this.customizationScript = customizationScript;
|
||||
}
|
||||
|
||||
public void setComputerName(String computerName) {
|
||||
this.computerName = computerName;
|
||||
}
|
||||
}
|
|
@ -26,8 +26,6 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.vcloud.domain.network.NetworkConfig;
|
||||
|
||||
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
|
@ -38,6 +36,7 @@ import com.google.common.collect.Sets;
|
|||
public class InstantiateVAppTemplateOptions {
|
||||
private Set<NetworkConfig> networkConfig = Sets.newLinkedHashSet();
|
||||
|
||||
private Boolean customizeOnInstantiate;
|
||||
private String cpuCount;
|
||||
private String memorySizeMegabytes;
|
||||
private String diskSizeKilobytes;
|
||||
|
@ -82,6 +81,15 @@ public class InstantiateVAppTemplateOptions {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, then customization is executed for all children that include a
|
||||
* GuestCustomizationSection.
|
||||
*/
|
||||
public InstantiateVAppTemplateOptions customizeOnInstantiate(boolean customizeOnInstantiate) {
|
||||
this.customizeOnInstantiate = customizeOnInstantiate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstantiateVAppTemplateOptions processorCount(int cpuCount) {
|
||||
checkArgument(cpuCount >= 1, "cpuCount must be positive");
|
||||
this.cpuCount = cpuCount + "";
|
||||
|
@ -126,6 +134,10 @@ public class InstantiateVAppTemplateOptions {
|
|||
return cpuCount;
|
||||
}
|
||||
|
||||
public Boolean shouldCustomizeOnInstantiate() {
|
||||
return customizeOnInstantiate;
|
||||
}
|
||||
|
||||
public String getMemorySizeMegabytes() {
|
||||
return memorySizeMegabytes;
|
||||
}
|
||||
|
@ -168,6 +180,14 @@ public class InstantiateVAppTemplateOptions {
|
|||
return options.processorCount(cpuCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InstantiateVAppTemplateOptions#customizeOnInstantiate
|
||||
*/
|
||||
public static InstantiateVAppTemplateOptions customizeOnInstantiate(Boolean customizeOnInstantiate) {
|
||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||
return options.customizeOnInstantiate(customizeOnInstantiate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InstantiateVAppTemplateOptions#memory(int)
|
||||
*/
|
||||
|
@ -197,7 +217,9 @@ public class InstantiateVAppTemplateOptions {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "InstantiateVAppTemplateOptions [cpuCount=" + cpuCount + ", memorySizeMegabytes=" + memorySizeMegabytes
|
||||
+ ", diskSizeKilobytes=" + diskSizeKilobytes + ", networkConfig=" + networkConfig + "]";
|
||||
+ ", diskSizeKilobytes=" + diskSizeKilobytes + ", networkConfig=" + networkConfig
|
||||
+ ", customizeOnInstantiate=" + customizeOnInstantiate + ", deploy=" + (deploy) + ", powerOn="
|
||||
+ (powerOn) + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -206,10 +228,11 @@ public class InstantiateVAppTemplateOptions {
|
|||
int result = 1;
|
||||
result = prime * result + (block ? 1231 : 1237);
|
||||
result = prime * result + ((cpuCount == null) ? 0 : cpuCount.hashCode());
|
||||
result = prime * result + ((customizeOnInstantiate == null) ? 0 : customizeOnInstantiate.hashCode());
|
||||
result = prime * result + (deploy ? 1231 : 1237);
|
||||
result = prime * result + ((diskSizeKilobytes == null) ? 0 : diskSizeKilobytes.hashCode());
|
||||
result = prime * result + ((networkConfig == null) ? 0 : networkConfig.hashCode());
|
||||
result = prime * result + ((memorySizeMegabytes == null) ? 0 : memorySizeMegabytes.hashCode());
|
||||
result = prime * result + ((networkConfig == null) ? 0 : networkConfig.hashCode());
|
||||
result = prime * result + (powerOn ? 1231 : 1237);
|
||||
return result;
|
||||
}
|
||||
|
@ -230,6 +253,11 @@ public class InstantiateVAppTemplateOptions {
|
|||
return false;
|
||||
} else if (!cpuCount.equals(other.cpuCount))
|
||||
return false;
|
||||
if (customizeOnInstantiate == null) {
|
||||
if (other.customizeOnInstantiate != null)
|
||||
return false;
|
||||
} else if (!customizeOnInstantiate.equals(other.customizeOnInstantiate))
|
||||
return false;
|
||||
if (deploy != other.deploy)
|
||||
return false;
|
||||
if (diskSizeKilobytes == null) {
|
||||
|
@ -237,16 +265,16 @@ public class InstantiateVAppTemplateOptions {
|
|||
return false;
|
||||
} else if (!diskSizeKilobytes.equals(other.diskSizeKilobytes))
|
||||
return false;
|
||||
if (networkConfig == null) {
|
||||
if (other.networkConfig != null)
|
||||
return false;
|
||||
} else if (!networkConfig.equals(other.networkConfig))
|
||||
return false;
|
||||
if (memorySizeMegabytes == null) {
|
||||
if (other.memorySizeMegabytes != null)
|
||||
return false;
|
||||
} else if (!memorySizeMegabytes.equals(other.memorySizeMegabytes))
|
||||
return false;
|
||||
if (networkConfig == null) {
|
||||
if (other.networkConfig != null)
|
||||
return false;
|
||||
} else if (!networkConfig.equals(other.networkConfig))
|
||||
return false;
|
||||
if (powerOn != other.powerOn)
|
||||
return false;
|
||||
return true;
|
||||
|
|
|
@ -118,6 +118,9 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult
|
|||
this.resetPasswordRequired = Boolean.parseBoolean(currentOrNull());
|
||||
} else if (qName.endsWith("CustomizationScript")) {
|
||||
this.customizationScript = currentOrNull();
|
||||
if (this.customizationScript != null)
|
||||
customizationScript = customizationScript.replace("<", "<").replace(">", ">").replace(""", "\"")
|
||||
.replace("'", "'").replace(" ", "\r\n").replace(" ", "\n").replace("&", "&");
|
||||
} else if (qName.endsWith("ComputerName")) {
|
||||
this.computerName = currentOrNull();
|
||||
} else if (qName.endsWith("Name")) {
|
||||
|
|
|
@ -51,6 +51,7 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
|||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.jclouds.vcloud.config.VCloudRestClientModule;
|
||||
import org.jclouds.vcloud.domain.GuestCustomizationSection;
|
||||
import org.jclouds.vcloud.domain.Org;
|
||||
import org.jclouds.vcloud.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
|
@ -97,6 +98,28 @@ import domain.VCloudVersionsAsyncClient;
|
|||
*/
|
||||
@Test(groups = "unit", testName = "vcloud.VCloudAsyncClientTest")
|
||||
public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
||||
public void testUpdateGuestConfiguration() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = VCloudAsyncClient.class.getMethod("updateGuestCustomizationOfVm", URI.class,
|
||||
GuestCustomizationSection.class);
|
||||
GuestCustomizationSection guest = new GuestCustomizationSection(URI
|
||||
.create("http://vcloud.example.com/api/v1.0/vApp/vm-12/guestCustomizationSection"));
|
||||
guest.setCustomizationScript("cat > /tmp/foo.txt<<EOF\nI love candy\nEOF");
|
||||
HttpRequest request = processor.createRequest(method,
|
||||
URI.create("http://vcloud.example.com/api/v1.0/vApp/vm-12"), guest);
|
||||
|
||||
assertRequestLineEquals(request,
|
||||
"PUT http://vcloud.example.com/api/v1.0/vApp/vm-12/guestCustomizationSection HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
|
||||
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
|
||||
"/guestCustomizationSection.xml")), "application/vnd.vmware.vcloud.guestCustomizationSection+xml",
|
||||
false);
|
||||
|
||||
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||
assertSaxResponseParserClassEquals(method, TaskHandler.class);
|
||||
assertExceptionParserClassEquals(method, null);
|
||||
|
||||
checkFilters(request);
|
||||
}
|
||||
|
||||
public void testInstantiateVAppTemplateInVDCURIOptions() throws SecurityException, NoSuchMethodException,
|
||||
IOException {
|
||||
|
@ -127,11 +150,11 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
IOException {
|
||||
Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class,
|
||||
String.class, InstantiateVAppTemplateOptions[].class);
|
||||
processor
|
||||
.createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(
|
||||
512).disk(1024).addNetworkConfig(
|
||||
new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"), null)));
|
||||
processor.createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(512)
|
||||
.disk(1024).addNetworkConfig(
|
||||
new NetworkConfig(null, URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1991"),
|
||||
null)));
|
||||
}
|
||||
|
||||
public void testCloneVAppInVDC() throws SecurityException, NoSuchMethodException, IOException {
|
||||
|
@ -159,8 +182,8 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
CloneVAppOptions[].class);
|
||||
HttpRequest request = processor.createRequest(method, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", new CloneVAppOptions()
|
||||
.deploy().powerOn().withDescription("The description of the new vApp"));
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server",
|
||||
new CloneVAppOptions().deploy().powerOn().withDescription("The description of the new vApp"));
|
||||
|
||||
assertRequestLineEquals(request,
|
||||
"POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1");
|
||||
|
@ -807,17 +830,42 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
protected Supplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>> provideOrgVDCSupplierCache(
|
||||
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) {
|
||||
|
||||
return Suppliers.<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>> ofInstance(ImmutableMap
|
||||
.<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>> of("org",
|
||||
return Suppliers
|
||||
.<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>> ofInstance(ImmutableMap
|
||||
.<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>> of(
|
||||
"org",
|
||||
|
||||
ImmutableMap.<String, org.jclouds.vcloud.domain.VDC> of("vdc", new VDCImpl("vdc", null, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), null, null, "description", null,
|
||||
null, null, null, null, ImmutableMap.<String, ReferenceType> of("vapp", new ReferenceTypeImpl(
|
||||
"vapp", "application/vnd.vmware.vcloud.vApp+xml", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), "network",
|
||||
new ReferenceTypeImpl("network", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), null, 0, 0, 0,
|
||||
false))));
|
||||
ImmutableMap
|
||||
.<String, org.jclouds.vcloud.domain.VDC> of(
|
||||
"vdc",
|
||||
new VDCImpl(
|
||||
"vdc",
|
||||
null,
|
||||
URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"),
|
||||
null,
|
||||
null,
|
||||
"description",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
ImmutableMap
|
||||
.<String, ReferenceType> of(
|
||||
"vapp",
|
||||
new ReferenceTypeImpl(
|
||||
"vapp",
|
||||
"application/vnd.vmware.vcloud.vApp+xml",
|
||||
URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")),
|
||||
"network",
|
||||
new ReferenceTypeImpl(
|
||||
"network",
|
||||
"application/vnd.vmware.vcloud.vAppTemplate+xml",
|
||||
URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))),
|
||||
null, 0, 0, 0, false))));
|
||||
|
||||
}
|
||||
|
||||
|
@ -832,14 +880,17 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
public Map<String, Org> get() {
|
||||
return ImmutableMap.<String, Org> of("org", new OrgImpl("org", null, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap
|
||||
.<String, ReferenceType> of("catalog", new ReferenceTypeImpl("catalog", VCloudMediaType.CATALOG_XML,
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap
|
||||
.<String, ReferenceType> of("catalog", new ReferenceTypeImpl("catalog",
|
||||
VCloudMediaType.CATALOG_XML, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap
|
||||
.<String, ReferenceType> of("vdc", new ReferenceTypeImpl("vdc", VCloudMediaType.VDC_XML, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap
|
||||
.<String, ReferenceType> of("network", new ReferenceTypeImpl("network", VCloudMediaType.NETWORK_XML,
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), new ReferenceTypeImpl(
|
||||
"tasksList", VCloudMediaType.TASKSLIST_XML, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList.<Task> of()));
|
||||
.<String, ReferenceType> of("network", new ReferenceTypeImpl("network",
|
||||
VCloudMediaType.NETWORK_XML, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))),
|
||||
new ReferenceTypeImpl("tasksList", VCloudMediaType.TASKSLIST_XML, URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList
|
||||
.<Task> of()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,11 +906,12 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
return ImmutableMap.<String, Map<String, ? extends org.jclouds.vcloud.domain.Catalog>> of("org",
|
||||
|
||||
ImmutableMap.<String, org.jclouds.vcloud.domain.Catalog> of("catalog", new CatalogImpl("catalog", "type",
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", ImmutableMap
|
||||
.<String, ReferenceType> of("item", new ReferenceTypeImpl("item",
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description",
|
||||
ImmutableMap.<String, ReferenceType> of("item", new ReferenceTypeImpl("item",
|
||||
"application/vnd.vmware.vcloud.catalogItem+xml", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), "template",
|
||||
new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")),
|
||||
"template", new ReferenceTypeImpl("template",
|
||||
"application/vnd.vmware.vcloud.vAppTemplate+xml", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))),
|
||||
ImmutableList.<Task> of(), true)));
|
||||
}
|
||||
|
@ -873,13 +925,25 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
|
|||
|
||||
@Override
|
||||
public Map<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>> get() {
|
||||
return ImmutableMap.<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>> of(
|
||||
"org", ImmutableMap.<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>> of(
|
||||
"catalog", ImmutableMap.<String, org.jclouds.vcloud.domain.CatalogItem> of("template",
|
||||
new CatalogItemImpl("template", URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), "description",
|
||||
new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml",
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")),
|
||||
return ImmutableMap
|
||||
.<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>> of(
|
||||
"org",
|
||||
ImmutableMap
|
||||
.<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>> of(
|
||||
"catalog",
|
||||
ImmutableMap
|
||||
.<String, org.jclouds.vcloud.domain.CatalogItem> of(
|
||||
"template",
|
||||
new CatalogItemImpl(
|
||||
"template",
|
||||
URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"),
|
||||
"description",
|
||||
new ReferenceTypeImpl(
|
||||
"template",
|
||||
"application/vnd.vmware.vcloud.vAppTemplate+xml",
|
||||
URI
|
||||
.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")),
|
||||
ImmutableMap.<String, String> of()))));
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
*
|
||||
* 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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.ExecResponse;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.jclouds.ssh.SshClient.Factory;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.VCloudGuestCustomizationLiveTest")
|
||||
public class VCloudGuestCustomizationLiveTest {
|
||||
|
||||
protected String identity;
|
||||
protected String provider;
|
||||
protected String credential;
|
||||
protected ComputeServiceContext context;
|
||||
protected ComputeService client;
|
||||
protected RetryablePredicate<IPSocket> socketTester;
|
||||
protected Factory sshFactory;
|
||||
|
||||
protected void setupCredentials() {
|
||||
provider = "vcloud";
|
||||
identity = checkNotNull(System.getProperty("vcloud.identity"), "vcloud.identity");
|
||||
credential = checkNotNull(System.getProperty("vcloud.credential"), "vcloud.credential");
|
||||
}
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() {
|
||||
setupCredentials();
|
||||
Properties props = new Properties();
|
||||
props.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
props.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||
context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet
|
||||
.<Module> of(new Log4JLoggingModule()), props);
|
||||
|
||||
client = context.getComputeService();
|
||||
|
||||
Injector injector = createSshClientInjector();
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
}
|
||||
|
||||
protected Injector createSshClientInjector() {
|
||||
return Guice.createInjector(getSshModule());
|
||||
}
|
||||
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtendedOptionsWithCustomizationScript() throws Exception {
|
||||
|
||||
String tag = "customize";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
options.as(VCloudTemplateOptions.class).customizationScript("cat > /root/foo.txt<<EOF\nI love candy\nEOF\n");
|
||||
|
||||
String nodeId = null;
|
||||
try {
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
|
||||
|
||||
NodeMetadata node = Iterables.get(nodes, 0);
|
||||
nodeId = node.getId();
|
||||
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22);
|
||||
socketTester.apply(socket);
|
||||
|
||||
SshClient ssh = sshFactory.create(socket, node.getCredentials().identity, node.getCredentials().credential);
|
||||
try {
|
||||
ssh.connect();
|
||||
|
||||
System.out
|
||||
.println(ssh
|
||||
.exec("vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'|base64 -d"));
|
||||
|
||||
ExecResponse hello = ssh.exec("cat /root/foo.txt");
|
||||
assertEquals(hello.getOutput().trim(), "I love candy");
|
||||
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
ssh.disconnect();
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (nodeId != null)
|
||||
client.destroyNode(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@ import static org.easymock.classextension.EasyMock.createMock;
|
|||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.easymock.classextension.EasyMock.verify;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.customizeOnInstantiate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -196,6 +197,46 @@ public class BindInstantiateVAppTemplateParamsToXmlPayloadTest {
|
|||
|
||||
binder.bindToRequest(request, map);
|
||||
verify(request);
|
||||
}
|
||||
|
||||
public void testWithCustomization() 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);
|
||||
InstantiateVAppTemplateOptions options = customizeOnInstantiate(true);
|
||||
|
||||
String expected = Utils
|
||||
.toStringAndClose(getClass().getResourceAsStream("/instantiationparams-customization.xml"));
|
||||
|
||||
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
|
||||
expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes();
|
||||
expect(request.getArgs()).andReturn(new Object[] { options }).atLeastOnce();
|
||||
request.setPayload(expected);
|
||||
|
||||
expect(template.getNetworkSection()).andReturn(net).atLeastOnce();
|
||||
expect(net.getNetworks())
|
||||
.andReturn(
|
||||
ImmutableSet
|
||||
.<org.jclouds.vcloud.domain.ovf.network.Network> of(new org.jclouds.vcloud.domain.ovf.network.Network(
|
||||
"vAppNet-vApp Internal", null)));
|
||||
|
||||
replay(request);
|
||||
replay(template);
|
||||
replay(net);
|
||||
|
||||
BindInstantiateVAppTemplateParamsToXmlPayload binder = createInjector(templateUri, template).getInstance(
|
||||
BindInstantiateVAppTemplateParamsToXmlPayload.class);
|
||||
|
||||
Map<String, String> map = Maps.newHashMap();
|
||||
map.put("name", "my-vapp");
|
||||
map.put("template", "https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3");
|
||||
|
||||
binder.bindToRequest(request, map);
|
||||
|
||||
verify(request);
|
||||
verify(template);
|
||||
verify(net);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,5 +76,4 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
System.out.println(allData.getExtra());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
*
|
||||
* 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.compute.options;
|
||||
|
||||
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.authorizePublicKey;
|
||||
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.blockOnPort;
|
||||
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.installPrivateKey;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.util.Utils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests possible uses of VCloudTemplateOptions and VCloudTemplateOptions.Builder.*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VCloudTemplateOptionsTest {
|
||||
|
||||
public void testAs() {
|
||||
TemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.as(VCloudTemplateOptions.class), options);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testcustomizationScriptBadFormat() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.customizationScript("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testcustomizationScript() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.customizationScript("mykeypair");
|
||||
assertEquals(options.getCustomizationScript(), "mykeypair");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullcustomizationScript() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.getCustomizationScript(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testcustomizationScriptStatic() {
|
||||
VCloudTemplateOptions options = customizationScript("mykeypair");
|
||||
assertEquals(options.getCustomizationScript(), "mykeypair");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testcustomizationScriptNPE() {
|
||||
customizationScript(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinstallPrivateKey() throws IOException {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.installPrivateKey(Payloads.newPayload("-----BEGIN RSA PRIVATE KEY-----"));
|
||||
assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullinstallPrivateKey() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.getPrivateKey(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinstallPrivateKeyStatic() throws IOException {
|
||||
VCloudTemplateOptions options = installPrivateKey(Payloads.newPayload("-----BEGIN RSA PRIVATE KEY-----"));
|
||||
assertEquals(Utils.toStringAndClose(options.getPrivateKey().getInput()), "-----BEGIN RSA PRIVATE KEY-----");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testinstallPrivateKeyNPE() {
|
||||
installPrivateKey(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testauthorizePublicKey() throws IOException {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.authorizePublicKey(Payloads.newPayload("ssh-rsa"));
|
||||
assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullauthorizePublicKey() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.getPublicKey(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testauthorizePublicKeyStatic() throws IOException {
|
||||
VCloudTemplateOptions options = authorizePublicKey(Payloads.newPayload("ssh-rsa"));
|
||||
assertEquals(Utils.toStringAndClose(options.getPublicKey().getInput()), "ssh-rsa");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class)
|
||||
public void testauthorizePublicKeyNPE() {
|
||||
authorizePublicKey(null);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testblockOnPortBadFormat() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.blockOnPort(-1, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testblockOnPort() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullblockOnPort() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.getPort(), -1);
|
||||
assertEquals(options.getSeconds(), -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testblockOnPortStatic() {
|
||||
VCloudTemplateOptions options = blockOnPort(22, 30);
|
||||
assertEquals(options.getPort(), 22);
|
||||
assertEquals(options.getSeconds(), 30);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||
public void testinboundPortsBadFormat() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.inboundPorts(-1, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinboundPorts() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
options.inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
assertEquals(options.getInboundPorts()[1], 30);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultOpen22() {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testinboundPortsStatic() {
|
||||
VCloudTemplateOptions options = inboundPorts(22, 30);
|
||||
assertEquals(options.getInboundPorts()[0], 22);
|
||||
assertEquals(options.getInboundPorts()[1], 30);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
package org.jclouds.vcloud.options;
|
||||
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.addNetworkConfig;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.customizeOnInstantiate;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.disk;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.memory;
|
||||
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
|
||||
|
@ -77,6 +78,19 @@ public class InstantiateVAppTemplateOptionsTest {
|
|||
assertEquals(options.getCpuCount(), "3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomizeOnInstantiate() {
|
||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||
options.customizeOnInstantiate(true);
|
||||
assertEquals(options.shouldCustomizeOnInstantiate(), new Boolean(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomizeOnInstantiateStatic() {
|
||||
InstantiateVAppTemplateOptions options = customizeOnInstantiate(true);
|
||||
assertEquals(options.shouldCustomizeOnInstantiate(), new Boolean(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRam() {
|
||||
InstantiateVAppTemplateOptions options = new InstantiateVAppTemplateOptions();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<GuestCustomizationSection xmlns="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" href="http://vcloud.example.com/api/v1.0/vApp/vm-12/guestCustomizationSection" ovf:required="false" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"><ovf:Info>Specifies Guest OS Customization Settings</ovf:Info><CustomizationScript>cat > /tmp/foo.txt<<EOF
|
||||
I love candy
|
||||
EOF</CustomizationScript></GuestCustomizationSection>
|
|
@ -0,0 +1 @@
|
|||
<InstantiateVAppTemplateParams xmlns="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" deploy="true" name="my-vapp" powerOn="true"><InstantiationParams><NetworkConfigSection><ovf:Info>Configuration parameters for logical networks</ovf:Info><NetworkConfig networkName="vAppNet-vApp Internal"><Configuration><ParentNetwork href="https://vcenterprise.bluelock.com/api/v1.0/network/1990"/><FenceMode>bridged</FenceMode></Configuration></NetworkConfig></NetworkConfigSection></InstantiationParams><Source href="https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"/><AllEULAsAccepted>true</AllEULAsAccepted></InstantiateVAppTemplateParams>
|
Loading…
Reference in New Issue