Issue 355: shell for nova 1.1 based on cloudservers

This commit is contained in:
Adrian Cole 2011-04-05 00:14:18 -07:00
parent b9f0cbcb89
commit 1cfbdf00f3
90 changed files with 7918 additions and 94 deletions

View File

@ -83,8 +83,8 @@ eucalyptus.propertiesbuilder=org.jclouds.eucalyptus.EucalyptusPropertiesBuilder
eucalyptus-partnercloud-ec2.contextbuilder=org.jclouds.epc.EucalyptusPartnerCloudContextBuilder
eucalyptus-partnercloud-ec2.propertiesbuilder=org.jclouds.epc.EucalyptusPartnerCloudPropertiesBuilder
nova-ec2.contextbuilder=org.jclouds.ec2.EC2ContextBuilder
nova-ec2.propertiesbuilder=org.jclouds.nova.ec2.NovaEC2PropertiesBuilder
nova.contextbuilder=org.jclouds.openstack.nova.NovaContextBuilder
nova.propertiesbuilder=org.jclouds.openstack.nova.NovaPropertiesBuilder
cloudservers-uk.contextbuilder=org.jclouds.cloudservers.CloudServersContextBuilder
cloudservers-uk.propertiesbuilder=org.jclouds.rackspace.cloudservers.CloudServersUKPropertiesBuilder

View File

@ -1,53 +0,0 @@
/**
*
* 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.nova.ec2.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "NovaEC2ComputeServiceLiveTest")
public class NovaEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
public NovaEC2ComputeServiceLiveTest() {
provider = "nova-ec2";
}
@Override
protected void assertDefaultWorks() {
Template defaultTemplate = client.templateBuilder().build();
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(defaultTemplate.getLocation().getId(), "nova");
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
}
}

View File

@ -30,33 +30,38 @@
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.api</groupId>
<artifactId>nova-ec2</artifactId>
<name>jclouds OpenStack Nova EC2 api</name>
<description>EC2 implementation based on OpenStack Nova</description>
<artifactId>nova</artifactId>
<name>jcloud nova api</name>
<description>jclouds components to access an implementation of OpenStack Nova</description>
<properties>
<test.nova-ec2.endpoint>TODO</test.nova-ec2.endpoint>
<test.nova-ec2.apiversion>2010-06-15</test.nova-ec2.apiversion>
<test.nova-ec2.identity>FIXME</test.nova-ec2.identity>
<test.nova-ec2.credential>FIXME</test.nova-ec2.credential>
<test.nova.endpoint>https://auth.api.rackspacecloud.com</test.nova.endpoint>
<test.nova.apiversion>1.1</test.nova.apiversion>
<test.nova.identity>FIXME</test.nova.identity>
<test.nova.credential>FIXME</test.nova.credential>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>ec2</artifactId>
<groupId>org.jclouds.common</groupId>
<artifactId>openstack-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
<artifactId>ec2</artifactId>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<groupId>org.jclouds.common</groupId>
<artifactId>openstack-common</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
@ -111,20 +116,24 @@
<configuration>
<systemProperties>
<property>
<name>test.nova-ec2.endpoint</name>
<value>${test.nova-ec2.endpoint}</value>
<name>test.nova.endpoint</name>
<value>${test.nova.endpoint}</value>
</property>
<property>
<name>test.nova-ec2.apiversion</name>
<value>${test.nova-ec2.apiversion}</value>
<name>test.nova.apiversion</name>
<value>${test.nova.apiversion}</value>
</property>
<property>
<name>test.nova-ec2.identity</name>
<value>${test.nova-ec2.identity}</value>
<name>test.nova.identity</name>
<value>${test.nova.identity}</value>
</property>
<property>
<name>test.nova-ec2.credential</name>
<value>${test.nova-ec2.credential}</value>
<name>test.nova.credential</name>
<value>${test.nova.credential}</value>
</property>
<property>
<name>test.initializer</name>
<value>${test.initializer}</value>
</property>
</systemProperties>
</configuration>

View File

@ -0,0 +1,378 @@
/**
*
* 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.openstack.nova;
import java.util.Set;
import java.util.concurrent.ExecutionException;
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.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.nova.binders.BindBackupScheduleToJsonPayload;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.RebootType;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.SharedIpGroup;
import org.jclouds.openstack.nova.options.CreateServerOptions;
import org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions;
import org.jclouds.openstack.nova.options.ListOptions;
import org.jclouds.openstack.nova.options.RebuildServerOptions;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.openstack.filters.AddTimestampQuery;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.Payload;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to OpenStack Nova via their REST API.
* <p/>
* All commands return a ListenableFuture of the result from OpenStack Nova. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as documented in
* {@link ListenableFuture#get()}.
*
* @see NovaClient
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
* @author Adrian Cole
*/
@SkipEncoding({ '/', '=' })
@RequestFilters({ AuthenticateRequest.class, AddTimestampQuery.class })
@Endpoint(ServerManagement.class)
public interface NovaAsyncClient {
/**
* @see NovaClient#listServers
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<Server>> listServers(ListOptions... options);
/**
* @see NovaClient#getServer
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/servers/{id}")
ListenableFuture<Server> getServer(@PathParam("id") int id);
/**
* @see NovaClient#deleteServer
*/
@DELETE
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/servers/{id}")
ListenableFuture<Boolean> deleteServer(@PathParam("id") int id);
/**
* @see NovaClient#rebootServer
*/
@POST
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/action")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D")
ListenableFuture<Void> rebootServer(@PathParam("id") int id, @PayloadParam("type") RebootType rebootType);
/**
* @see NovaClient#resizeServer
*/
@POST
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/action")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D")
ListenableFuture<Void> resizeServer(@PathParam("id") int id, @PayloadParam("flavorId") int flavorId);
/**
* @see NovaClient#confirmResizeServer
*/
@POST
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/action")
@Produces(MediaType.APPLICATION_JSON)
@Payload("{\"confirmResize\":null}")
ListenableFuture<Void> confirmResizeServer(@PathParam("id") int id);
/**
* @see NovaClient#revertResizeServer
*/
@POST
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/action")
@Produces(MediaType.APPLICATION_JSON)
@Payload("{\"revertResize\":null}")
ListenableFuture<Void> revertResizeServer(@PathParam("id") int id);
/**
* @see NovaClient#createServer
*/
@POST
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers")
@MapBinder(CreateServerOptions.class)
ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageId") int imageId,
@PayloadParam("flavorId") int flavorId, CreateServerOptions... options);
/**
* @see NovaClient#rebuildServer
*/
@POST
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/action")
@MapBinder(RebuildServerOptions.class)
ListenableFuture<Void> rebuildServer(@PathParam("id") int id, RebuildServerOptions... options);
/**
* @see NovaClient#shareIp
*/
@PUT
@Path("/servers/{id}/ips/public/{address}")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"shareIp\":%7B\"sharedIpGroupId\":{sharedIpGroupId},\"configureServer\":{configureServer}%7D%7D")
ListenableFuture<Void> shareIp(@PathParam("address") String addressToShare,
@PathParam("id") int serverToTosignBindressTo, @PayloadParam("sharedIpGroupId") int sharedIpGroup,
@PayloadParam("configureServer") boolean configureServer);
/**
* @see NovaClient#unshareIp
*/
@DELETE
@Path("/servers/{id}/ips/public/{address}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> unshareIp(@PathParam("address") String addressToShare,
@PathParam("id") int serverToTosignBindressTo);
/**
* @see NovaClient#changeAdminPass
*/
@PUT
@Path("/servers/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"server\":%7B\"adminPass\":\"{adminPass}\"%7D%7D")
ListenableFuture<Void> changeAdminPass(@PathParam("id") int id, @PayloadParam("adminPass") String adminPass);
/**
* @see NovaClient#renameServer
*/
@PUT
@Path("/servers/{id}")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D")
ListenableFuture<Void> renameServer(@PathParam("id") int id, @PayloadParam("name") String newName);
/**
* @see NovaClient#listFlavors
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/flavors")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<Flavor>> listFlavors(ListOptions... options);
/**
* @see NovaClient#getFlavor
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/flavors/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Flavor> getFlavor(@PathParam("id") int id);
/**
* @see NovaClient#listImages
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/images")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<Image>> listImages(ListOptions... options);
/**
* @see NovaClient#getImage
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@QueryParams(keys = "format", values = "json")
@Path("/images/{id}")
ListenableFuture<Image> getImage(@PathParam("id") int id);
/**
* @see NovaClient#deleteImage
*/
@DELETE
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/images/{id}")
ListenableFuture<Boolean> deleteImage(@PathParam("id") int id);
/**
* @see NovaClient#createImageFromServer
*/
@POST
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/images")
@Produces(MediaType.APPLICATION_JSON)
@Payload("%7B\"image\":%7B\"serverId\":{serverId},\"name\":\"{name}\"%7D%7D")
ListenableFuture<Image> createImageFromServer(@PayloadParam("name") String imageName,
@PayloadParam("serverId") int serverId);
/**
* @see NovaClient#listSharedIpGroups
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/shared_ip_groups")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<SharedIpGroup>> listSharedIpGroups(ListOptions... options);
/**
* @see NovaClient#getSharedIpGroup
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/shared_ip_groups/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<SharedIpGroup> getSharedIpGroup(@PathParam("id") int id);
/**
* @see NovaClient#createSharedIpGroup
*/
@POST
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/shared_ip_groups")
@MapBinder(CreateSharedIpGroupOptions.class)
ListenableFuture<SharedIpGroup> createSharedIpGroup(@PayloadParam("name") String name,
CreateSharedIpGroupOptions... options);
/**
* @see NovaClient#deleteSharedIpGroup
*/
@DELETE
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/shared_ip_groups/{id}")
ListenableFuture<Boolean> deleteSharedIpGroup(@PathParam("id") int id);
/**
* @see NovaClient#listBackupSchedule
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/backup_schedule")
ListenableFuture<BackupSchedule> getBackupSchedule(@PathParam("id") int serverId);
/**
* @see NovaClient#deleteBackupSchedule
*/
@DELETE
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
@Path("/servers/{id}/backup_schedule")
ListenableFuture<Boolean> deleteBackupSchedule(@PathParam("id") int serverId);
/**
* @see NovaClient#replaceBackupSchedule
*/
@POST
@ExceptionParser(ReturnFalseOn404.class)
@Path("/servers/{id}/backup_schedule")
ListenableFuture<Void> replaceBackupSchedule(@PathParam("id") int id,
@BinderParam(BindBackupScheduleToJsonPayload.class) BackupSchedule backupSchedule);
/**
* @see NovaClient#listAddresses
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/ips")
ListenableFuture<Addresses> getAddresses(@PathParam("id") int serverId);
/**
* @see NovaClient#listPublicAddresses
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/ips/public")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<String>> listPublicAddresses(@PathParam("id") int serverId);
/**
* @see NovaClient#listPrivateAddresses
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/servers/{id}/ips/private")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<String>> listPrivateAddresses(@PathParam("id") int serverId);
}

View File

@ -0,0 +1,380 @@
/**
*
* 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.openstack.nova;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.PathParam;
import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.RebootType;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.SharedIpGroup;
import org.jclouds.openstack.nova.options.CreateServerOptions;
import org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions;
import org.jclouds.openstack.nova.options.ListOptions;
import org.jclouds.openstack.nova.options.RebuildServerOptions;
import org.jclouds.rest.ResourceNotFoundException;
import java.util.concurrent.Future;
/**
* Provides access to OpenStack Nova via their REST API.
* <p/>
* All commands return a Future of the result from OpenStack Nova. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as documented in
* {@link Future#get()}.
*
* @see NovaAsyncClient
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface NovaClient {
/**
*
* List all servers (IDs and names only)
*
* This operation provides a list of servers associated with your identity. Servers that have been
* deleted are not included in this list.
* <p/>
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
* withDetails()}
*/
Set<Server> listServers(ListOptions... options);
/**
*
* This operation returns details of the specified server.
*
* @return null, if the server is not found
* @see Server
*/
Server getServer(@PathParam("id") int id);
/**
*
* This operation deletes a cloud server instance from the system.
* <p/>
* Note: When a server is deleted, all images created from that server are also removed.
*
* @return false if the server is not found
* @see Server
*/
boolean deleteServer(@PathParam("id") int id);
/**
* The reboot function allows for either a soft or hard reboot of a server.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - REBOOT - ACTIVE (soft reboot)
* <p/>
* ACTIVE - HARD_REBOOT - ACTIVE (hard reboot)
*
* @param rebootType
* With a soft reboot, the operating system is signaled to restart, which allows for a
* graceful shutdown of all processes. A hard reboot is the equivalent of power cycling
* the server.
*/
void rebootServer(int id, RebootType rebootType);
/**
* The resize function converts an existing server to a different flavor, in essence, scaling the
* server up or down. The original server is saved for a period of time to allow rollback if
* there is a problem. All resizes should be tested and explicitly confirmed, at which time the
* original server is removed. All resizes are automatically confirmed after 24 hours if they are
* not confirmed or reverted.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - QUEUE_RESIZE - PREP_RESIZE - VERIFY_RESIZE
* <p/>
* ACTIVE - QUEUE_RESIZE - ACTIVE (on error)
*/
void resizeServer(int id, int flavorId);
/**
* The resize function converts an existing server to a different flavor, in essence, scaling the
* server up or down. The original server is saved for a period of time to allow rollback if
* there is a problem. All resizes should be tested and explicitly confirmed, at which time the
* original server is removed. All resizes are automatically confirmed after 24 hours if they are
* not confirmed or reverted.
* <p/>
* Status Transition:
* <p/>
* VERIFY_RESIZE - ACTIVE
*/
void confirmResizeServer(int id);
/**
* The resize function converts an existing server to a different flavor, in essence, scaling the
* server up or down. The original server is saved for a period of time to allow rollback if
* there is a problem. All resizes should be tested and explicitly reverted, at which time the
* original server is removed. All resizes are automatically reverted after 24 hours if they are
* not reverted or reverted.
* <p/>
* Status Transition:
* <p/>
* VERIFY_RESIZE - ACTIVE
*/
void revertResizeServer(int id);
/**
* This operation asynchronously provisions a new server. The progress of this operation depends
* on several factors including location of the requested image, network i/o, host load, and the
* selected flavor. The progress of the request can be checked by performing a GET on /server/id,
* which will return a progress attribute (0-100% completion). A password will be randomly
* generated for you and returned in the response object. For security reasons, it will not be
* returned in subsequent GET calls against a given server ID.
*
* @param options
* - used to specify extra files, metadata, or ip parameters during server creation.
*/
Server createServer(String name, int imageId, int flavorId, CreateServerOptions... options);
/**
* The rebuild function removes all data on the server and replaces it with the specified image.
* Server ID and IP addresses remain the same.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - REBUILD - ACTIVE
* <p/>
* ACTIVE - REBUILD - ERROR (on error)
* <p/>
*
* @param options
* - imageId is an optional argument. If it is not specified, the server is rebuilt
* with the original imageId.
*/
void rebuildServer(int id, RebuildServerOptions... options);
/**
* /** This operation allows you share an IP address to the specified server
* <p/>
* This operation shares an IP from an existing server in the specified shared IP group to
* another specified server in the same group. The operation modifies cloud network restrictions
* to allow IP traffic for the given IP to/from the server specified.
*
* <p/>
* Status Transition: ACTIVE - SHARE_IP - ACTIVE (if configureServer is true) ACTIVE -
* SHARE_IP_NO_CONFIG - ACTIVE
*
* @param configureServer
* <p/>
* if set to true, the server is configured with the new address, though the address is
* not enabled. Note that configuring the server does require a reboot.
* <p/>
* If set to false, does not bind the IP to the server itself. A heartbeat facility
* (e.g. keepalived) can then be used within the servers to perform health checks and
* manage IP failover.
*/
void shareIp(String addressToShare, int serverToTosignBindressTo, int sharedIpGroup,
boolean configureServer);
/**
* This operation removes a shared IP address from the specified server.
* <p/>
* Status Transition: ACTIVE - DELETE_IP - ACTIVE
*
* @param addressToShare
* @param serverToTosignBindressTo
* @return
*/
void unshareIp(String addressToShare, int serverToTosignBindressTo);
/**
* This operation allows you to change the administrative password.
* <p/>
* Status Transition: ACTIVE - PASSWORD - ACTIVE
*
*/
void changeAdminPass(int id, String adminPass);
/**
* This operation allows you to update the name of the server. This operation changes the name of
* the server in the OpenStack Nova system and does not change the server host name itself.
* <p/>
* Status Transition: ACTIVE - PASSWORD - ACTIVE
*
*/
void renameServer(int id, String newName);
/**
*
* List available flavors (IDs and names only)
*
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
* withDetails()}
*/
Set<Flavor> listFlavors(ListOptions... options);
/**
*
* This operation returns details of the specified flavor.
*
* @return null, if the flavor is not found
* @see Flavor
*/
Flavor getFlavor(int id);
/**
*
* List available images (IDs and names only)
*
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
* withDetails()}
*/
Set<Image> listImages(ListOptions... options);
/**
*
* This operation returns details of the specified image.
*
* @return null, if the image is not found
*
* @see Image
*/
Image getImage(int id);
/**
*
* This operation deletes an image from the system.
* <p/>
* Note: Images are immediately removed. Currently, there are no state transitions to track the
* delete operation.
*
* @return false if the image is not found
* @see Image
*/
boolean deleteImage(int id);
/**
*
* This operation creates a new image for the given server ID. Once complete, a new image will be
* available that can be used to rebuild or create servers. Specifying the same image name as an
* existing custom image replaces the image. The image creation status can be queried by
* performing a GET on /images/id and examining the status and progress attributes.
*
* Status Transition:
* <p/>
* QUEUED - PREPARING - SAVING - ACTIVE
* <p/>
* QUEUED - PREPARING - SAVING - FAILED (on error)
* <p/>
* Note: At present, image creation is an asynchronous operation, so coordinating the creation
* with data quiescence, etc. is currently not possible.
*
* @throws ResourceNotFoundException
* if the server is not found
* @see Image
*/
Image createImageFromServer(String imageName, int serverId);
/**
*
* List shared IP groups (IDs and names only)
*
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
* withDetails()}
*/
Set<SharedIpGroup> listSharedIpGroups(ListOptions... options);
/**
*
* This operation returns details of the specified shared IP group.
*
* @return null, if the shared ip group is not found
*
* @see SharedIpGroup
*/
SharedIpGroup getSharedIpGroup(int id);
/**
* This operation creates a new shared IP group. Please note, all responses to requests for
* shared_ip_groups return an array of servers. However, on a create request, the shared IP group
* can be created empty or can be initially populated with a single server. Use
* {@link CreateSharedIpGroupOptions} to specify an server.
*/
SharedIpGroup createSharedIpGroup(String name, CreateSharedIpGroupOptions... options);
/**
* This operation deletes the specified shared IP group. This operation will ONLY succeed if 1)
* there are no active servers in the group (i.e. they have all been terminated) or 2) no servers
* in the group are actively sharing IPs.
*
* @return false if the shared ip group is not found
* @see SharedIpGroup
*/
boolean deleteSharedIpGroup(int id);
/**
* List the backup schedule for the specified server
*
* @throws ResourceNotFoundException
* , if the server doesn't exist
*/
BackupSchedule getBackupSchedule(int serverId);
/**
* Delete backup schedule for the specified server.
* <p/>
* Web Hosting #119571 currently disables the schedule, not deletes it.
*
* @return false if the schedule is not found
*/
boolean deleteBackupSchedule(int serverId);
/**
* Enable/update the backup schedule for the specified server
*
*/
void replaceBackupSchedule(int id, BackupSchedule backupSchedule);
/**
* List all server addresses
*
* returns empty set if the server doesn't exist
*/
Addresses getAddresses(int serverId);
/**
* List all public server addresses
*
* returns empty set if the server doesn't exist
*/
Set<String> listPublicAddresses(int serverId);
/**
* List all private server addresses
*
* returns empty set if the server doesn't exist
*/
Set<String> listPrivateAddresses(int serverId);
}

View File

@ -0,0 +1,64 @@
/**
*
* 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.openstack.nova;
import java.util.List;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.openstack.nova.compute.config.NovaComputeServiceContextModule;
import org.jclouds.openstack.nova.config.NovaRestClientModule;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Creates {@link NovaComputeServiceContext} or {@link Injector} instances based on the most
* commonly requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see NovaComputeServiceContext
*/
public class NovaContextBuilder extends
ComputeServiceContextBuilder<NovaClient, NovaAsyncClient> {
public NovaContextBuilder(Properties props) {
super(NovaClient.class, NovaAsyncClient.class, props);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new NovaComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new NovaRestClientModule());
}
}

View File

@ -0,0 +1,41 @@
/**
*
* 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.openstack.nova;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Represents a component related to Rackspace OpenStack Nova.
*
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
* @author Adrian Cole
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface ServerManagement {
}

View File

@ -0,0 +1,54 @@
/**
*
* 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.openstack.nova.binders;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class BindBackupScheduleToJsonPayload extends BindToJsonPayload {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
throw new IllegalStateException(
"Replace Backup Schedule needs an BackupSchedule object, not a Map");
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
checkArgument(toBind instanceof BackupSchedule,
"this binder is only valid for BackupSchedules!");
return super.bindToRequest(request, ImmutableMap.of("backupSchedule", toBind));
}
}

View File

@ -0,0 +1,77 @@
/**
*
* 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.openstack.nova.compute.config;
import org.jclouds.compute.config.BindComputeStrategiesByClass;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.openstack.nova.compute.strategy.NovaCreateNodeWithGroupEncodedIntoName;
import org.jclouds.openstack.nova.compute.strategy.NovaDestroyNodeStrategy;
import org.jclouds.openstack.nova.compute.strategy.NovaGetNodeMetadataStrategy;
import org.jclouds.openstack.nova.compute.strategy.NovaListNodesStrategy;
import org.jclouds.openstack.nova.compute.strategy.NovaLifeCycleStrategy;
/**
*
* @author Adrian Cole
*
*/
public class NovaBindComputeStrategiesByClass extends BindComputeStrategiesByClass {
@Override
protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() {
return NovaCreateNodeWithGroupEncodedIntoName.class;
}
@Override
protected Class<? extends DestroyNodeStrategy> defineDestroyNodeStrategy() {
return NovaDestroyNodeStrategy.class;
}
@Override
protected Class<? extends GetNodeMetadataStrategy> defineGetNodeMetadataStrategy() {
return NovaGetNodeMetadataStrategy.class;
}
@Override
protected Class<? extends ListNodesStrategy> defineListNodesStrategy() {
return NovaListNodesStrategy.class;
}
@Override
protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() {
return NovaLifeCycleStrategy.class;
}
@Override
protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() {
return NovaLifeCycleStrategy.class;
}
@Override
protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() {
return NovaLifeCycleStrategy.class;
}
}

View File

@ -0,0 +1,54 @@
/**
*
* 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.openstack.nova.compute.config;
import java.util.Set;
import org.jclouds.openstack.nova.compute.suppliers.NovaHardwareSupplier;
import org.jclouds.openstack.nova.compute.suppliers.NovaImageSupplier;
import org.jclouds.compute.config.BindComputeSuppliersByClass;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.JustProvider;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*
*/
public class NovaBindComputeSuppliersByClass extends BindComputeSuppliersByClass {
@Override
protected Class<? extends Supplier<Set<? extends Hardware>>> defineHardwareSupplier() {
return NovaHardwareSupplier.class;
}
@Override
protected Class<? extends Supplier<Set<? extends Image>>> defineImageSupplier() {
return NovaImageSupplier.class;
}
@Override
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return JustProvider.class;
}
}

View File

@ -17,31 +17,25 @@
* ====================================================================
*/
package org.jclouds.nova.ec2;
package org.jclouds.openstack.nova.compute.config;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import java.util.Properties;
import org.jclouds.ec2.EC2PropertiesBuilder;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.internal.BaseComputeService;
/**
* Builds properties used in NovaEC2 Clients
* Configures the {@link NovaComputeServiceContext}; requires {@link BaseComputeService}
* bound.
*
* @author Adrian Cole
*/
public class NovaEC2PropertiesBuilder extends EC2PropertiesBuilder {
public class NovaComputeServiceContextModule extends BaseComputeServiceContextModule {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ENDPOINT, "YOU_MUST_SET_" + PROPERTY_ENDPOINT);
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*");
return properties;
}
public NovaEC2PropertiesBuilder(Properties properties) {
super(properties);
protected void configure() {
install(new NovaComputeServiceDependenciesModule());
install(new NovaBindComputeStrategiesByClass());
install(new NovaBindComputeSuppliersByClass());
super.configure();
}
}

View File

@ -0,0 +1,117 @@
/**
*
* 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.openstack.nova.compute.config;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.openstack.nova.NovaAsyncClient;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.compute.functions.NovaImageToImage;
import org.jclouds.openstack.nova.compute.functions.NovaImageToOperatingSystem;
import org.jclouds.openstack.nova.compute.functions.FlavorToHardware;
import org.jclouds.openstack.nova.compute.functions.ServerToNodeMetadata;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.RestContextImpl;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
/**
* Configures the {@link NovaComputeServiceContext}; requires {@link BaseComputeService}
* bound.
*
* @author Adrian Cole
*/
public class NovaComputeServiceDependenciesModule extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
}).to(ServerToNodeMetadata.class);
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.domain.Image, Image>>() {
}).to(NovaImageToImage.class);
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.domain.Image, OperatingSystem>>() {
}).to(NovaImageToOperatingSystem.class);
bind(new TypeLiteral<Function<Flavor, Hardware>>() {
}).to(FlavorToHardware.class);
bind(new TypeLiteral<ComputeServiceContext>() {
}).to(new TypeLiteral<ComputeServiceContextImpl<NovaClient, NovaAsyncClient>>() {
}).in(Scopes.SINGLETON);
bind(new TypeLiteral<RestContext<NovaClient, NovaAsyncClient>>() {
}).to(new TypeLiteral<RestContextImpl<NovaClient, NovaAsyncClient>>() {
}).in(Scopes.SINGLETON);
}
@VisibleForTesting
public static final Map<ServerStatus, NodeState> serverToNodeState = ImmutableMap
.<ServerStatus, NodeState> builder().put(ServerStatus.ACTIVE, NodeState.RUNNING)//
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)//
.put(ServerStatus.DELETED, NodeState.TERMINATED)//
.put(ServerStatus.QUEUE_RESIZE, NodeState.PENDING)//
.put(ServerStatus.PREP_RESIZE, NodeState.PENDING)//
.put(ServerStatus.RESIZE, NodeState.PENDING)//
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)//
.put(ServerStatus.QUEUE_MOVE, NodeState.PENDING)//
.put(ServerStatus.PREP_MOVE, NodeState.PENDING)//
.put(ServerStatus.MOVE, NodeState.PENDING)//
.put(ServerStatus.VERIFY_MOVE, NodeState.PENDING)//
.put(ServerStatus.RESCUE, NodeState.PENDING)//
.put(ServerStatus.ERROR, NodeState.ERROR)//
.put(ServerStatus.BUILD, NodeState.PENDING)//
.put(ServerStatus.RESTORING, NodeState.PENDING)//
.put(ServerStatus.PASSWORD, NodeState.PENDING)//
.put(ServerStatus.REBUILD, NodeState.PENDING)//
.put(ServerStatus.DELETE_IP, NodeState.PENDING)//
.put(ServerStatus.SHARE_IP_NO_CONFIG, NodeState.PENDING)//
.put(ServerStatus.SHARE_IP, NodeState.PENDING)//
.put(ServerStatus.REBOOT, NodeState.PENDING)//
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)//
.put(ServerStatus.UNKNOWN, NodeState.UNRECOGNIZED)//
.put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
@Singleton
@Provides
Map<ServerStatus, NodeState> provideServerToNodeState() {
return serverToNodeState;
}
}

View File

@ -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.openstack.nova.compute.functions;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.openstack.nova.domain.Flavor;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Singleton
public class FlavorToHardware implements Function<Flavor, Hardware> {
public Hardware apply(Flavor from) {
return new HardwareBuilder().ids(from.getId() + "").name(from.getName())
.processors(ImmutableList.of(new Processor(from.getDisk() / 10.0, 1.0))).ram(from.getRam())
.volumes(ImmutableList.<Volume> of(new VolumeImpl((float) from.getDisk(), true, true))).build();
}
}

View File

@ -0,0 +1,56 @@
/**
*
* 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.openstack.nova.compute.functions;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.domain.Credentials;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*/
@Singleton
public class NovaImageToImage implements Function<org.jclouds.openstack.nova.domain.Image, Image> {
private final Function<org.jclouds.openstack.nova.domain.Image, OperatingSystem> imageToOs;
@Inject
NovaImageToImage(Function<org.jclouds.openstack.nova.domain.Image, OperatingSystem> imageToOs) {
this.imageToOs = imageToOs;
}
public Image apply(org.jclouds.openstack.nova.domain.Image from) {
ImageBuilder builder = new ImageBuilder();
builder.ids(from.getId() + "");
builder.name(from.getName());
builder.description(from.getName());
builder.version(from.getUpdated().getTime() + "");
builder.operatingSystem(imageToOs.apply(from));
builder.defaultCredentials(new Credentials("root", null));
Image image = builder.build();
return image;
}
}

View File

@ -0,0 +1,92 @@
/**
*
* 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.openstack.nova.compute.functions;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*/
@Singleton
public class NovaImageToOperatingSystem implements
Function<org.jclouds.openstack.nova.domain.Image, OperatingSystem> {
public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
// Windows Server 2008 R2 x64
public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])");
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Map<OsFamily, Map<String, String>> osVersionMap;
@Inject
public NovaImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap) {
this.osVersionMap = osVersionMap;
}
public OperatingSystem apply(final org.jclouds.openstack.nova.domain.Image from) {
OsFamily osFamily = null;
String osName = null;
String osArch = null;
String osVersion = null;
String osDescription = from.getName();
boolean is64Bit = true;
if (from.getName().indexOf("Red Hat EL") != -1) {
osFamily = OsFamily.RHEL;
} else if (from.getName().indexOf("Oracle EL") != -1) {
osFamily = OsFamily.OEL;
} else if (from.getName().indexOf("Windows") != -1) {
osFamily = OsFamily.WINDOWS;
Matcher matcher = WINDOWS_PATTERN.matcher(from.getName());
if (matcher.find()) {
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
is64Bit = matcher.group(2).equals("x64");
}
} else {
Matcher matcher = DEFAULT_PATTERN.matcher(from.getName());
if (matcher.find()) {
try {
osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase());
} catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", matcher.group(2));
}
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap);
}
}
return new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
}
}

View File

@ -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.openstack.nova.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
@Singleton
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
protected final Supplier<Location> location;
protected final Map<String, Credentials> credentialStore;
protected final Map<ServerStatus, NodeState> serverToNodeState;
protected final Supplier<Set<? extends Image>> images;
protected final Supplier<Set<? extends Hardware>> hardwares;
private static class FindImageForServer implements Predicate<Image> {
private final Server instance;
private FindImageForServer(Server instance) {
this.instance = instance;
}
@Override
public boolean apply(Image input) {
return input.getProviderId().equals(instance.getImageId() + "");
}
}
private static class FindHardwareForServer implements Predicate<Hardware> {
private final Server instance;
private FindHardwareForServer(Server instance) {
this.instance = instance;
}
@Override
public boolean apply(Hardware input) {
return input.getProviderId().equals(instance.getFlavorId() + "");
}
}
@Inject
ServerToNodeMetadata(Map<ServerStatus, NodeState> serverStateToNodeState, Map<String, Credentials> credentialStore,
@Memoized Supplier<Set<? extends Image>> images, Supplier<Location> location,
@Memoized Supplier<Set<? extends Hardware>> hardwares) {
this.serverToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.images = checkNotNull(images, "images");
this.location = checkNotNull(location, "location");
this.hardwares = checkNotNull(hardwares, "hardwares");
}
@Override
public NodeMetadata apply(Server from) {
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.ids(from.getId() + "");
builder.name(from.getName());
builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description(
from.getHostId()).parent(location.get()).build());
builder.userMetadata(from.getMetadata());
builder.group(parseGroupFromName(from.getName()));
builder.imageId(from.getImageId() + "");
builder.operatingSystem(parseOperatingSystem(from));
builder.hardware(parseHardware(from));
builder.state(serverToNodeState.get(from.getStatus()));
builder.publicAddresses(from.getAddresses().getPublicAddresses());
builder.privateAddresses(from.getAddresses().getPrivateAddresses());
builder.credentials(credentialStore.get("node#" + from.getId()));
return builder.build();
}
protected Hardware parseHardware(Server from) {
try {
return Iterables.find(hardwares.get(), new FindHardwareForServer(from));
} catch (NoSuchElementException e) {
logger.warn("could not find a matching hardware for server %s", from);
}
return null;
}
protected OperatingSystem parseOperatingSystem(Server from) {
try {
return Iterables.find(images.get(), new FindImageForServer(from)).getOperatingSystem();
} catch (NoSuchElementException e) {
logger.warn("could not find a matching image for server %s in location %s", from, location);
}
return null;
}
}

View File

@ -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.openstack.nova.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.domain.Credentials;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Server;
import com.google.common.base.Function;
/**
* @author Adrian Cole
*/
@Singleton
public class NovaCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName {
protected final NovaClient client;
protected final Map<String, Credentials> credentialStore;
protected final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected NovaCreateNodeWithGroupEncodedIntoName(NovaClient client, Map<String, Credentials> credentialStore,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = checkNotNull(client, "client");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.serverToNodeMetadata = checkNotNull(serverToNodeMetadata, "serverToNodeMetadata");
}
@Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer
.parseInt(template.getHardware().getProviderId()));
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
return serverToNodeMetadata.apply(from);
}
}

View File

@ -0,0 +1,52 @@
/**
*
* 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.openstack.nova.compute.strategy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.openstack.nova.NovaClient;
/**
* @author Adrian Cole
*/
@Singleton
public class NovaDestroyNodeStrategy implements DestroyNodeStrategy {
private final NovaClient client;
private final GetNodeMetadataStrategy getNode;
@Inject
protected NovaDestroyNodeStrategy(NovaClient client, GetNodeMetadataStrategy getNode) {
this.client = client;
this.getNode = getNode;
}
@Override
public NodeMetadata destroyNode(String id) {
int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place
client.deleteServer(serverId);
return getNode.getNode(id);
}
}

View File

@ -0,0 +1,54 @@
/**
*
* 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.openstack.nova.compute.strategy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Server;
import com.google.common.base.Function;
/**
* @author Adrian Cole
*/
@Singleton
public class NovaGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final NovaClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected NovaGetNodeMetadataStrategy(NovaClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public NodeMetadata getNode(String id) {
int serverId = Integer.parseInt(id);
Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server);
}
}

View File

@ -0,0 +1,65 @@
/**
*
* 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.openstack.nova.compute.strategy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.RebootType;
/**
* @author Adrian Cole
*/
@Singleton
public class NovaLifeCycleStrategy implements RebootNodeStrategy, SuspendNodeStrategy, ResumeNodeStrategy {
private final NovaClient client;
private final GetNodeMetadataStrategy getNode;
@Inject
protected NovaLifeCycleStrategy(NovaClient client, GetNodeMetadataStrategy getNode) {
this.client = client;
this.getNode = getNode;
}
@Override
public NodeMetadata rebootNode(String id) {
int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place
client.rebootServer(serverId, RebootType.HARD);
return getNode.getNode(id);
}
@Override
public NodeMetadata suspendNode(String id) {
throw new UnsupportedOperationException("suspend not supported");
}
@Override
public NodeMetadata resumeNode(String id) {
throw new UnsupportedOperationException("resume not supported");
}
}

View File

@ -0,0 +1,62 @@
/**
*
* 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.openstack.nova.compute.strategy;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.options.ListOptions;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
@Singleton
public class NovaListNodesStrategy implements ListNodesStrategy {
private final NovaClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected NovaListNodesStrategy(NovaClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public Iterable<? extends ComputeMetadata> listNodes() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.listServers(ListOptions.Builder.withDetails()),
serverToNodeMetadata), filter);
}
}

View File

@ -0,0 +1,68 @@
/**
*
* 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.openstack.nova.compute.suppliers;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Flavor;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
*
* @author Adrian Cole
*/
@Singleton
public class NovaHardwareSupplier implements Supplier<Set<? extends Hardware>> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final NovaClient sync;
private final Function<Flavor, Hardware> flavorToHardware;
@Inject
NovaHardwareSupplier(NovaClient sync, Function<Flavor, Hardware> flavorToHardware) {
this.sync = sync;
this.flavorToHardware = flavorToHardware;
}
@Override
public Set<? extends Hardware> get() {
final Set<Hardware> hardware;
logger.debug(">> providing hardware");
hardware = Sets.newLinkedHashSet(Iterables.transform(sync.listFlavors(withDetails()), flavorToHardware));
logger.debug("<< hardware(%d)", hardware.size());
return hardware;
}
}

View File

@ -0,0 +1,71 @@
/**
*
* 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.openstack.nova.compute.suppliers;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.NovaClient;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
*
* @author Adrian Cole
*/
@Singleton
public class NovaImageSupplier implements Supplier<Set<? extends Image>> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
protected final NovaClient sync;
protected final Function<org.jclouds.openstack.nova.domain.Image, Image> cloudServersImageToImage;
@Inject
NovaImageSupplier(NovaClient sync,
Function<org.jclouds.openstack.nova.domain.Image, Image> cloudServersImageToImage) {
this.sync = sync;
this.cloudServersImageToImage = cloudServersImageToImage;
}
@Override
public Set<? extends Image> get() {
Set<Image> images;
logger.debug(">> providing images");
images = Sets.<Image> newLinkedHashSet(Iterables.transform(sync.listImages(withDetails()),
cloudServersImageToImage));
logger.debug("<< images(%d)", images.size());
return images;
}
}

View File

@ -0,0 +1,85 @@
/**
*
* 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.openstack.nova.config;
import java.net.URI;
import javax.inject.Singleton;
import org.jclouds.openstack.nova.NovaAsyncClient;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.ServerManagement;
import org.jclouds.openstack.nova.handlers.ParseNovaErrorFromHttpResponse;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
@ConfiguresRestClient
@RequiresHttp
public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsyncClient> {
private final OpenStackAuthenticationModule module;
public NovaRestClientModule(OpenStackAuthenticationModule module) {
super(NovaClient.class, NovaAsyncClient.class);
this.module = module;
}
public NovaRestClientModule() {
this(new OpenStackAuthenticationModule());
}
@Override
protected void configure() {
install(module);
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseNovaErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseNovaErrorFromHttpResponse.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseNovaErrorFromHttpResponse.class);
}
@Provides
@Singleton
@ServerManagement
protected URI provideServerUrl(AuthenticationResponse response) {
return response.getServices().get(AuthHeaders.SERVER_MANAGEMENT_URL);
}
}

View File

@ -0,0 +1,48 @@
/**
*
* 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.openstack.nova.domain;
/**
*
* @author Adrian Cole
*/
public class AbsoluteLimit {
protected String name;
protected int value;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,28 @@
/**
*
* 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.openstack.nova.domain;
/**
*
* @author Adrian Cole
*/
public enum Action {
CONFIRM_RESIZE, REBOOT, REBUILD, RESIZE, REVERT_RESIZE
}

View File

@ -0,0 +1,99 @@
/**
*
* 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.openstack.nova.domain;
import java.util.Set;
import com.google.common.collect.Sets;
import com.google.gson.annotations.SerializedName;
/**
*
* @author Adrian Cole
*/
public class Addresses {
@SerializedName("public")
private Set<String> publicAddresses = Sets.newLinkedHashSet();
@SerializedName("private")
private Set<String> privateAddresses = Sets.newLinkedHashSet();
public Addresses() {
}
public Addresses(Set<String> publicAddresses, Set<String> privateAddresses) {
this.publicAddresses = publicAddresses;
this.privateAddresses = privateAddresses;
}
public void setPublicAddresses(Set<String> publicAddresses) {
this.publicAddresses = publicAddresses;
}
public Set<String> getPublicAddresses() {
return publicAddresses;
}
public void setPrivateAddresses(Set<String> privateAddresses) {
this.privateAddresses = privateAddresses;
}
public Set<String> getPrivateAddresses() {
return privateAddresses;
}
@Override
public String toString() {
return "Addresses [privateAddresses=" + privateAddresses + ", publicAddresses="
+ publicAddresses + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Addresses other = (Addresses) obj;
if (privateAddresses == null) {
if (other.privateAddresses != null)
return false;
} else if (!privateAddresses.equals(other.privateAddresses))
return false;
if (publicAddresses == null) {
if (other.publicAddresses != null)
return false;
} else if (!publicAddresses.equals(other.publicAddresses))
return false;
return true;
}
}

View File

@ -0,0 +1,105 @@
/**
*
* 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.openstack.nova.domain;
/**
* A backup schedule can be defined to create server images at regular intervals (daily and weekly).
* Backup schedules are configurable per server.
*
* @author Adrian Cole
*/
public class BackupSchedule {
protected DailyBackup daily = DailyBackup.DISABLED;
protected boolean enabled;
protected WeeklyBackup weekly = WeeklyBackup.DISABLED;
public BackupSchedule() {
}
public BackupSchedule(WeeklyBackup weekly, DailyBackup daily, boolean enabled) {
this.weekly = weekly;
this.daily = daily;
this.enabled = enabled;
}
public DailyBackup getDaily() {
return daily;
}
public void setDaily(DailyBackup value) {
this.daily = value;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean value) {
this.enabled = value;
}
public WeeklyBackup getWeekly() {
return weekly;
}
public void setWeekly(WeeklyBackup value) {
this.weekly = value;
}
@Override
public String toString() {
return "[daily=" + daily + ", enabled=" + enabled + ", weekly=" + weekly + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((daily == null) ? 0 : daily.hashCode());
result = prime * result + (enabled ? 1231 : 1237);
result = prime * result + ((weekly == null) ? 0 : weekly.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BackupSchedule other = (BackupSchedule) obj;
if (daily == null) {
if (other.daily != null)
return false;
} else if (!daily.equals(other.daily))
return false;
if (enabled != other.enabled)
return false;
if (weekly == null) {
if (other.weekly != null)
return false;
} else if (!weekly.equals(other.weekly))
return false;
return true;
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.domain;
public enum DailyBackup {
DISABLED, H_0000_0200, H_0200_0400, H_0400_0600, H_0600_0800, H_0800_1000, H_1000_1200, H_1200_1400, H_1400_1600, H_1600_1800, H_1800_2000, H_2000_2200, H_2200_0000, UNRECOGNIZED;
public String value() {
return name();
}
public static DailyBackup fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,121 @@
/**
*
* 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.openstack.nova.domain;
/**
*
* A flavor is an available hardware configuration for a server. Each flavor has a unique
* combination of disk space and memory capacity.
*
* @author Adrian Cole
*/
public class Flavor {
public Flavor() {
}
@Override
public String toString() {
return "Flavor [disk=" + disk + ", id=" + id + ", name=" + name + ", ram=" + ram + "]";
}
public Flavor(int id, String name) {
this.id = id;
this.name = name;
}
private int id;
private String name;
private Integer disk;
private Integer ram;
public Integer getDisk() {
return disk;
}
public void setDisk(Integer value) {
this.disk = value;
}
public int getId() {
return id;
}
public void setId(int value) {
this.id = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public Integer getRam() {
return ram;
}
public void setRam(Integer value) {
this.ram = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((disk == null) ? 0 : disk.hashCode());
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((ram == null) ? 0 : ram.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Flavor other = (Flavor) obj;
if (disk == null) {
if (other.disk != null)
return false;
} else if (!disk.equals(other.disk))
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (ram == null) {
if (other.ram != null)
return false;
} else if (!ram.equals(other.ram))
return false;
return true;
}
}

View File

@ -0,0 +1,146 @@
/**
*
* 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.openstack.nova.domain;
import java.util.Date;
/**
* An image is a collection of files used to create or rebuild a server. Rackspace provides a number
* of pre-built OS images by default. You may also create custom images from cloud servers you have
* launched. These custom images are useful for backup purposes or for producing gold server images
* if you plan to deploy a particular server configuration frequently.
*
* @author Adrian Cole
*/
public class Image {
private Date created;
private int id;
private String name;
private Integer progress;
private Integer serverId;
private ImageStatus status;
private Date updated;
public Image() {
}
public Image(int id, String name) {
this.id = id;
this.name = name;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getCreated() {
return created;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public Integer getProgress() {
return progress;
}
public void setServerId(Integer serverId) {
this.serverId = serverId;
}
public Integer getServerId() {
return serverId;
}
public void setStatus(ImageStatus status) {
this.status = status;
}
public ImageStatus getStatus() {
return status;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
public Date getUpdated() {
return updated;
}
/**
* note that this ignores the create time
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((serverId == null) ? 0 : serverId.hashCode());
return result;
}
/**
* note that this ignores the serverid and create time.
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Image other = (Image) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Image [created=" + created + ", id=" + id + ", name=" + name + ", serverId="
+ serverId + "]";
}
}

View File

@ -0,0 +1,46 @@
/**
*
* 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.openstack.nova.domain;
/**
* In-flight images will have the status attribute set to SAVING and the conditional progress
* element (0- 100% completion) will also be returned. Other possible values for the status
* attribute include: UNKNOWN, PREPARING, ACTIVE QUEUED, FAILED. Images with an ACTIVE status are
* available for install.
*
* @author Adrian Cole
*/
public enum ImageStatus {
UNRECOGNIZED, UNKNOWN, ACTIVE, SAVING, PREPARING, QUEUED, FAILED;
public String value() {
return name();
}
public static ImageStatus fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,47 @@
/**
*
* 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.openstack.nova.domain;
import java.util.List;
import com.google.common.collect.Lists;
public class Limits {
private List<RateLimit> rate = Lists.newArrayList();
private List<AbsoluteLimit> absolute = Lists.newArrayList();
public void setRate(List<RateLimit> rate) {
this.rate = rate;
}
public List<RateLimit> getRate() {
return rate;
}
public void setAbsolute(List<AbsoluteLimit> absolute) {
this.absolute = absolute;
}
public List<AbsoluteLimit> getAbsolute() {
return absolute;
}
}

View File

@ -0,0 +1,90 @@
/**
*
* 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.openstack.nova.domain;
import javax.ws.rs.HttpMethod;
/**
*
* RateLimit.
* <p/>
* we specify rate limits in terms of both a human readable wild-card URI and a machine processable
* regular expression. The regular expression boundary matcher '^' takes affect after the root URI
* path. For example, the regular expression ^/servers would match the bolded portion of the
* following URI: https://servers.api.rackspacecloud.com/v1.0/3542812 /servers .
* <p/>
* Rate limits are applied in order relative to the verb, going from least to most specific. For
* example, although the threshold for POST to /servers is 25 per day, one cannot POST to /servers
* more than 10 times within a single minute because the rate limits for any POST is 10/min. In the
* event you exceed the thresholds established for your identity, a 413 Rate Control HTTP response
* will be returned with a Reply-After header to notify the client when theyagain.
*
* @author Adrian Cole
*/
public class RateLimit {
private final String uri;
private final String regex;
private final int remaining;
private final long resetTime;
private final RateLimitUnit unit;
private final int value;
private final HttpMethod verb;
public RateLimit(String uri, String regex, int remaining, long resetTime, RateLimitUnit unit,
int value, HttpMethod verb) {
this.uri = uri;
this.regex = regex;
this.remaining = remaining;
this.resetTime = resetTime;
this.unit = unit;
this.value = value;
this.verb = verb;
}
public String getUri() {
return uri;
}
public String getRegex() {
return regex;
}
public int getRemaining() {
return remaining;
}
public long getResetTime() {
return resetTime;
}
public RateLimitUnit getUnit() {
return unit;
}
public int getValue() {
return value;
}
public HttpMethod getVerb() {
return verb;
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.domain;
public enum RateLimitUnit {
MINUTE, HOUR, DAY, UNRECOGNIZED;
public String value() {
return name();
}
public static RateLimitUnit fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.domain;
/**
*
* @author Adrian Cole
*/
public enum RebootType {
HARD, SOFT;
public String value() {
return name();
}
public static RebootType fromValue(String v) {
return valueOf(v);
}
}

View File

@ -0,0 +1,230 @@
/**
*
* 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.openstack.nova.domain;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* A server is a virtual machine instance in the OpenStack Nova system. Flavor and image are
* requisite elements when creating a server.
*
* @author Adrian Cole
*/
public class Server {
private int id;
private String name;
private Map<String, String> metadata = Maps.newHashMap();
private Addresses addresses;
private String adminPass;
private Integer flavorId;
private String hostId;
private Integer imageId;
private Integer sharedIpGroupId;
private Integer progress;
private ServerStatus status;
public Server() {
}
public Server(int id, String name) {
this.id = id;
this.name = name;
}
public void setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
}
public Map<String, String> getMetadata() {
return metadata;
}
public void setAddresses(Addresses addresses) {
this.addresses = addresses;
}
public Addresses getAddresses() {
return addresses;
}
public void setAdminPass(String adminPass) {
this.adminPass = adminPass;
}
public String getAdminPass() {
return adminPass;
}
public void setFlavorId(Integer flavorId) {
this.flavorId = flavorId;
}
public Integer getFlavorId() {
return flavorId;
}
public void setHostId(String hostId) {
this.hostId = hostId;
}
/**
* The OpenStack Nova provisioning algorithm has an anti-affinity property that attempts to spread
* out customer VMs across hosts. Under certain situations, VMs from the same customer may be
* placed on the same host. hostId represents the host your cloud server runs on and can be used
* to determine this scenario if it's relevant to your application.
* <p/>
* Note: hostId is unique PER ACCOUNT and is not globally unique.
*/
public String getHostId() {
return hostId;
}
public int getId() {
return id;
}
public void setImageId(Integer imageId) {
this.imageId = imageId;
}
public Integer getImageId() {
return imageId;
}
public String getName() {
return name;
}
public void setProgress(Integer progress) {
this.progress = progress;
}
public Integer getProgress() {
return progress;
}
public void setSharedIpGroupId(Integer sharedIpGroupId) {
this.sharedIpGroupId = sharedIpGroupId;
}
public Integer getSharedIpGroupId() {
return sharedIpGroupId;
}
public void setStatus(ServerStatus status) {
this.status = status;
}
/**
* Servers contain a status attribute that can be used as an indication of the current server
* state. Servers with an ACTIVE status are available for use.
*/
public ServerStatus getStatus() {
return status;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
result = prime * result + ((adminPass == null) ? 0 : adminPass.hashCode());
result = prime * result + ((flavorId == null) ? 0 : flavorId.hashCode());
result = prime * result + ((hostId == null) ? 0 : hostId.hashCode());
result = prime * result + id;
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sharedIpGroupId == null) ? 0 : sharedIpGroupId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Server other = (Server) obj;
if (addresses == null) {
if (other.addresses != null)
return false;
} else if (!addresses.equals(other.addresses))
return false;
if (adminPass == null) {
if (other.adminPass != null)
return false;
} else if (!adminPass.equals(other.adminPass))
return false;
if (flavorId == null) {
if (other.flavorId != null)
return false;
} else if (!flavorId.equals(other.flavorId))
return false;
if (hostId == null) {
if (other.hostId != null)
return false;
} else if (!hostId.equals(other.hostId))
return false;
if (id != other.id)
return false;
if (imageId == null) {
if (other.imageId != null)
return false;
} else if (!imageId.equals(other.imageId))
return false;
if (metadata == null) {
if (other.metadata != null)
return false;
} else if (!metadata.equals(other.metadata))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sharedIpGroupId == null) {
if (other.sharedIpGroupId != null)
return false;
} else if (!sharedIpGroupId.equals(other.sharedIpGroupId))
return false;
return true;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Server [addresses=" + addresses + ", adminPass=" + adminPass + ", flavorId="
+ flavorId + ", hostId=" + hostId + ", id=" + id + ", imageId=" + imageId
+ ", metadata=" + metadata + ", name=" + name + ", sharedIpGroupId="
+ sharedIpGroupId + "]";
}
}

View File

@ -0,0 +1,55 @@
/**
*
* 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.openstack.nova.domain;
/**
*
* Servers contain a status attribute that can be used as an indication of the current server state.
* Servers with an ACTIVE status are available for use.
* <p/>
* <h2>Note</h2>
* When the system changes a server's status from BUILD to ACTIVE the system will not be immediately
* available. The 'ACTIVE' label is really misleading in the fact that it just means the system
* doesn't have any activity going on related to it's configuration.
* <p/>
* Processes such as ssh will not be available until 5-10 seconds following the phase ACTIVE
* <ul>
* <li>[Web Hosting #119335]</li>
* </ul>
*
* @author Adrian Cole
*/
public enum ServerStatus {
ACTIVE, SUSPENDED, DELETED, QUEUE_RESIZE, PREP_RESIZE, RESIZE, VERIFY_RESIZE, QUEUE_MOVE, PREP_MOVE, MOVE, VERIFY_MOVE, RESCUE, ERROR, BUILD, RESTORING, PASSWORD, REBUILD, DELETE_IP, SHARE_IP_NO_CONFIG, SHARE_IP, REBOOT, HARD_REBOOT, UNKNOWN, UNRECOGNIZED;
public String value() {
return name();
}
public static ServerStatus fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,43 @@
/**
*
* 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.openstack.nova.domain;
public class ShareIp {
private boolean configureServer;
private int sharedIpGroupId;
public void setConfigureServer(boolean configureServer) {
this.configureServer = configureServer;
}
public boolean isConfigureServer() {
return configureServer;
}
public void setSharedIpGroupId(int sharedIpGroupId) {
this.sharedIpGroupId = sharedIpGroupId;
}
public int getSharedIpGroupId() {
return sharedIpGroupId;
}
}

View File

@ -0,0 +1,112 @@
/**
*
* 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.openstack.nova.domain;
import java.util.List;
import com.google.common.collect.Lists;
/**
* A shared IP group is a collection of servers that can share IPs with other members of the group.
* Any server in a group can share one or more public IPs with any other server in the group. With
* the exception of the first server in a shared IP group, servers must be launched into shared IP
* groups. A server may only be a member of one shared IP group.
*
* @author Adrian Cole
*/
public class SharedIpGroup {
private int id;
private String name;
private List<Integer> servers = Lists.newArrayList();
public SharedIpGroup() {
}
public SharedIpGroup(int id, String name) {
this.id = id;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setServers(List<Integer> servers) {
this.servers = servers;
}
public List<Integer> getServers() {
return servers;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((servers == null) ? 0 : servers.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SharedIpGroup other = (SharedIpGroup) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (servers == null) {
if (other.servers != null)
return false;
} else if (!servers.equals(other.servers))
return false;
return true;
}
@Override
public String toString() {
return "SharedIpGroup [id=" + id + ", name=" + name + ", servers=" + servers + "]";
}
}

View File

@ -0,0 +1,60 @@
/**
*
* 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.openstack.nova.domain;
public class Version {
private String docURL;
private String id = "v1.0";
private VersionStatus status;
private String wadl;
public void setDocURL(String docURL) {
this.docURL = docURL;
}
public String getDocURL() {
return docURL;
}
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setStatus(VersionStatus status) {
this.status = status;
}
public VersionStatus getStatus() {
return status;
}
public void setWadl(String wadl) {
this.wadl = wadl;
}
public String getWadl() {
return wadl;
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.domain;
public enum VersionStatus {
BETA, CURRENT, DEPRECATED, UNRECOGNIZED;
public String value() {
return name();
}
public static VersionStatus fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.domain;
public enum WeeklyBackup {
DISABLED, SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, UNRECOGNIZED;
public String value() {
return name();
}
public static WeeklyBackup fromValue(String v) {
try {
return valueOf(v);
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,96 @@
/**
*
* 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.openstack.nova.handlers;
import static org.jclouds.http.HttpUtils.releasePayload;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
public class ParseNovaErrorFromHttpResponse implements HttpErrorHandler {
@Resource
protected Logger logger = Logger.NULL;
public static final Pattern RESOURCE_PATTERN = Pattern
.compile("^/v1[^/]*/[0-9]+/([^/]+)/([0-9]+)");
public void handleError(HttpCommand command, HttpResponse response) {
Exception exception = new HttpResponseException(command, response);
try {
String content = parseErrorFromContentOrNull(command, response);
exception = content != null ? new HttpResponseException(command, response, content) : exception;
switch (response.getStatusCode()) {
case 401:
exception = new AuthorizationException(exception.getMessage(), exception);
break;
case 404:
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
String path = command.getCurrentRequest().getEndpoint().getPath();
Matcher matcher = RESOURCE_PATTERN.matcher(path);
String message;
if (matcher.find()) {
message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
} else {
message = path;
}
exception = new ResourceNotFoundException(message);
}
break;
case 409:
exception = new IllegalStateException(content);
break;
default:
exception = new HttpResponseException(command, response, content);
break;
}
} finally {
releasePayload(response);
command.setException(exception);
}
}
String parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
if (response.getPayload() != null) {
try {
return Strings2.toStringAndClose(response.getPayload().getInput());
} catch (IOException e) {
logger.warn(e, "exception reading error from response", response);
}
}
return null;
}
}

View File

@ -0,0 +1,241 @@
/**
*
* 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.openstack.nova.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.jclouds.encryption.internal.Base64;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
*
* @author Adrian Cole
*
*/
public class CreateServerOptions extends BindToJsonPayload {
static class File {
private final String path;
private final String contents;
public File(String path, byte[] contents) {
this.path = checkNotNull(path, "path");
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
checkArgument(path.getBytes().length < 255, String.format(
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
.getBytes().length));
checkArgument(contents.length < 10 * 1024, String.format(
"maximum size of the file is 10KB. Contents specified is %d bytes",
contents.length));
}
public String getContents() {
return contents;
}
public String getPath() {
return path;
}
}
@SuppressWarnings("unused")
private class ServerRequest {
final String name;
final int imageId;
final int flavorId;
Map<String, String> metadata;
List<File> personality;
Integer sharedIpGroupId;
Addresses addresses;
private ServerRequest(String name, int imageId, int flavorId) {
this.name = name;
this.imageId = imageId;
this.flavorId = flavorId;
}
}
private Map<String, String> metadata = Maps.newHashMap();
private List<File> files = Lists.newArrayList();
private Integer sharedIpGroupId;
private String publicIp;
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
"name parameter not present"), Integer.parseInt(checkNotNull(postParams
.get("imageId"), "imageId parameter not present")), Integer.parseInt(checkNotNull(
postParams.get("flavorId"), "flavorId parameter not present")));
if (metadata.size() > 0)
server.metadata = metadata;
if (files.size() > 0)
server.personality = files;
if (sharedIpGroupId != null)
server.sharedIpGroupId = this.sharedIpGroupId;
if (publicIp != null) {
server.addresses = new Addresses();
server.addresses.getPublicAddresses().add(publicIp);
server.addresses.setPrivateAddresses(null);
}
return bindToRequest(request, ImmutableMap.of("server", server));
}
/**
* You may further customize a cloud server by injecting data into the file system of the cloud
* server itself. This is useful, for example, for inserting ssh keys, setting configuration
* files, or storing data that you want to retrieve from within the instance itself. It is
* intended to provide a minimal amount of launch-time personalization. If significant
* customization is required, a custom image should be created. The max size of the file path
* data is 255 bytes while the max size of the file contents is 10KB. Note that the file contents
* should be encoded as a Base64 string and the 10KB limit refers to the number of bytes in the
* decoded data not the number of characters in the encoded data. The maximum number of file
* path/content pairs that can be supplied is 5. Any existing files that match the specified file
* will be renamed to include the extension bak followed by a time stamp. For example, the file
* /etc/passwd will be backed up as /etc/passwd.bak.1246036261.5785. All files will have root and
* the root group as owner and group owner, respectively and will allow user and group read
* access only (-r--r-----).
*/
public CreateServerOptions withFile(String path, byte[] contents) {
checkState(files.size() < 5, "maximum number of files allowed is 5");
files.add(new File(path, contents));
return this;
}
/**
* A shared IP group is a collection of servers that can share IPs with other members of the
* group. Any server in a group can share one or more public IPs with any other server in the
* group. With the exception of the first server in a shared IP group, servers must be launched
* into shared IP groups. A server may only be a member of one shared IP group.
*
* <p/>
* Servers in the same shared IP group can share public IPs for various high availability and
* load balancing configurations. To launch an HA server, include the optional sharedIpGroupId
* element and the server will be launched into that shared IP group.
* <p />
*
* Note: sharedIpGroupId is an optional parameter and for optimal performance, should ONLY be
* specified when intending to share IPs between servers.
*
* @see #withSharedIp(String)
*/
public CreateServerOptions withSharedIpGroup(int id) {
checkArgument(id > 0, "id must be positive or zero. was: " + id);
this.sharedIpGroupId = id;
return this;
}
/**
* Custom cloud server metadata can also be supplied at launch time. This metadata is stored in
* the API system where it is retrievable by querying the API for server status. The maximum size
* of the metadata key and value is each 255 bytes and the maximum number of key-value pairs that
* can be supplied per server is 5.
*/
public CreateServerOptions withMetadata(Map<String, String> metadata) {
checkNotNull(metadata, "metadata");
checkArgument(metadata.size() <= 5,
"you cannot have more then 5 metadata values. You specified: " + metadata.size());
for (Entry<String, String> entry : metadata.entrySet()) {
checkArgument(entry.getKey().getBytes().length < 255, String.format(
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes",
entry.getKey(), entry.getKey().getBytes().length));
checkArgument(
entry.getKey().getBytes().length < 255,
String
.format(
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes",
entry.getKey(), entry.getValue(),
entry.getValue().getBytes().length));
}
this.metadata = metadata;
return this;
}
/**
* Public IP addresses can be shared across multiple servers for use in various high availability
* scenarios. When an IP address is shared to another server, the cloud network restrictions are
* modified to allow each server to listen to and respond on that IP address (you may optionally
* specify that the target server network configuration be modified). Shared IP addresses can be
* used with many standard heartbeat facilities (e.g. keepalived) that monitor for failure and
* manage IP failover.
*
* <p/>
* If you intend to use a shared IP on the server being created and have no need for a separate
* public IP address, you may launch the server into a shared IP group and specify an IP address
* from that shared IP group to be used as its public IP. You can accomplish this by specifying
* the public shared IP address in your request. This is optional and is only valid if
* sharedIpGroupId is also supplied.
*/
public CreateServerOptions withSharedIp(String publicIp) {
checkState(sharedIpGroupId != null,
"sharedIp is invalid unless a shared ip group is specified.");
this.publicIp = checkNotNull(publicIp, "ip");
return this;
}
public static class Builder {
/**
* @see CreateServerOptions#withFile(String,byte [])
*/
public static CreateServerOptions withFile(String path, byte[] contents) {
CreateServerOptions options = new CreateServerOptions();
return options.withFile(path, contents);
}
/**
* @see CreateServerOptions#withSharedIpGroup(int)
*/
public static CreateServerOptions withSharedIpGroup(int id) {
CreateServerOptions options = new CreateServerOptions();
return options.withSharedIpGroup(id);
}
/**
* @see CreateServerOptions#withMetadata(Map<String, String>)
*/
public static CreateServerOptions withMetadata(Map<String, String> metadata) {
CreateServerOptions options = new CreateServerOptions();
return options.withMetadata(metadata);
}
/**
* @see CreateServerOptions#withSharedIp(String)
*/
public static CreateServerOptions withSharedIp(String publicIp) {
CreateServerOptions options = new CreateServerOptions();
return options.withSharedIp(publicIp);
}
}
}

View File

@ -0,0 +1,88 @@
/**
*
* 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.openstack.nova.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.annotation.Nullable;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
/**
*
*
* @author Adrian Cole
*
*/
public class CreateSharedIpGroupOptions extends BindToJsonPayload {
Integer serverId;
@SuppressWarnings("unused")
private static class SharedIpGroupRequest {
final String name;
Integer server;
private SharedIpGroupRequest(String name, @Nullable Integer serverId) {
this.name = name;
this.server = serverId;
}
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
SharedIpGroupRequest createRequest = new SharedIpGroupRequest(checkNotNull(postParams
.get("name")), serverId);
return super.bindToRequest(request, ImmutableMap.of("sharedIpGroup", createRequest));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
throw new IllegalStateException("CreateSharedIpGroup is a POST operation");
}
/**
*
* @param id
* of the server to include with this request.
*/
public CreateSharedIpGroupOptions withServer(int id) {
checkArgument(id > 0, "server id must be a positive number");
this.serverId = id;
return this;
}
public static class Builder {
/**
* @see CreateSharedIpGroupOptions#withServer(int)
*/
public static CreateSharedIpGroupOptions withServer(int id) {
CreateSharedIpGroupOptions options = new CreateSharedIpGroupOptions();
return options.withServer(id);
}
}
}

View File

@ -0,0 +1,110 @@
/**
*
* 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.openstack.nova.options;
import java.util.Date;
import org.jclouds.openstack.options.BaseListOptions;
/**
* Options used to control the amount of detail in the request.
*
* @see BaseListOptions
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
* @author Adrian Cole
*/
public class ListOptions extends BaseListOptions {
public static final ListOptions NONE = new ListOptions();
/**
* unless used, only the name and id will be returned per row.
*
* @return
*/
public ListOptions withDetails() {
this.pathSuffix = "/detail";
return this;
}
/**
* {@inheritDoc}
*/
@Override
public ListOptions changesSince(Date ifModifiedSince) {
super.changesSince(ifModifiedSince);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public ListOptions maxResults(int limit) {
super.maxResults(limit);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public ListOptions startAt(long offset) {
super.startAt(offset);
return this;
}
public static class Builder {
/**
* @see ListOptions#withDetails()
*/
public static ListOptions withDetails() {
ListOptions options = new ListOptions();
return options.withDetails();
}
/**
* @see BaseListOptions#startAt(long)
*/
public static ListOptions startAt(long prefix) {
ListOptions options = new ListOptions();
return options.startAt(prefix);
}
/**
* @see BaseListOptions#maxResults(long)
*/
public static ListOptions maxResults(int maxKeys) {
ListOptions options = new ListOptions();
return options.maxResults(maxKeys);
}
/**
* @see BaseListOptions#changesSince(Date)
*/
public static ListOptions changesSince(Date since) {
ListOptions options = new ListOptions();
return options.changesSince(since);
}
}
}

View File

@ -0,0 +1,75 @@
/**
*
* 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.openstack.nova.options;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
*
*
* @author Adrian Cole
*
*/
public class RebuildServerOptions extends BindToJsonPayload {
Integer imageId;
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
Map<String, Integer> image = Maps.newHashMap();
if (imageId != null)
image.put("imageId", imageId);
return super.bindToRequest(request, ImmutableMap.of("rebuild", image));
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
throw new IllegalStateException("RebuildServer is a POST operation");
}
/**
*
* @param id
* of the image to rebuild the server with.
*/
public RebuildServerOptions withImage(int id) {
checkArgument(id > 0, "server id must be a positive number");
this.imageId = id;
return this;
}
public static class Builder {
/**
* @see RebuildServerOptions#withImage(int)
*/
public static RebuildServerOptions withImage(int id) {
RebuildServerOptions options = new RebuildServerOptions();
return options.withImage(id);
}
}
}

View File

@ -0,0 +1,67 @@
/**
*
* 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.openstack.nova.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
* Tests to see if a task succeeds.
*
* @author Adrian Cole
*/
@Singleton
public class ServerActive implements Predicate<Server> {
private final NovaClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public ServerActive(NovaClient client) {
this.client = client;
}
public boolean apply(Server server) {
logger.trace("looking for state on server %s", checkNotNull(server, "server"));
server = refresh(server);
if (server == null)
return false;
logger.trace("%s: looking for server state %s: currently: %s", server.getId(),
ServerStatus.ACTIVE, server.getStatus());
return server.getStatus() == ServerStatus.ACTIVE;
}
private Server refresh(Server server) {
return client.getServer(server.getId());
}
}

View File

@ -0,0 +1,67 @@
/**
*
* 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.openstack.nova.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
* Tests to see if a task succeeds.
*
* @author Adrian Cole
*/
@Singleton
public class ServerDeleted implements Predicate<Server> {
private final NovaClient client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public ServerDeleted(NovaClient client) {
this.client = client;
}
public boolean apply(Server server) {
logger.trace("looking for state on server %s", checkNotNull(server, "server"));
server = refresh(server);
if (server == null)
return true;
logger.trace("%s: looking for server state %s: currently: %s", server.getId(),
ServerStatus.DELETED, server.getStatus());
return server.getStatus() == ServerStatus.DELETED;
}
private Server refresh(Server server) {
return client.getServer(server.getId());
}
}

View File

@ -0,0 +1,905 @@
/**
*
* 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.openstack.nova;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withMetadata;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withSharedIpGroup;
import static org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions.Builder.withServer;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.changesSince;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import static org.jclouds.openstack.nova.options.RebuildServerOptions.Builder.withImage;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Properties;
import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.nova.config.NovaRestClientModule;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.openstack.nova.domain.DailyBackup;
import org.jclouds.openstack.nova.domain.RebootType;
import org.jclouds.openstack.nova.domain.WeeklyBackup;
import org.jclouds.openstack.nova.options.CreateServerOptions;
import org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions;
import org.jclouds.openstack.nova.options.ListOptions;
import org.jclouds.openstack.nova.options.RebuildServerOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.TestOpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AddTimestampQuery;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code NovaAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "NovaAsyncClientTest")
public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[] {}.getClass();
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[] {}
.getClass();
public void testCreateServer() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
createServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1}}",
"application/json", false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCreateServerWithIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
createServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1, withSharedIpGroup(2));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request,
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"sharedIpGroupId\":2}}",
"application/json", false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCreateServerWithFile() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
createServerOptionsVarargsClass);
HttpRequest request = processor
.createRequest(method, "ralphie", 2, 1, withFile("/etc/jclouds", "foo".getBytes()));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(
request,
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"personality\":[{\"path\":\"/etc/jclouds\",\"contents\":\"Zm9v\"}]}}",
"application/json", false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCreateServerWithMetadata() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
createServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1,
withMetadata(ImmutableMap.of("foo", "bar")));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request,
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"metadata\":{\"foo\":\"bar\"}}}",
"application/json", false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCreateServerWithIpGroupAndSharedIp() throws IOException, SecurityException, NoSuchMethodException,
UnknownHostException {
Method method = NovaAsyncClient.class.getMethod("createServer", String.class, int.class, int.class,
createServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1,
withSharedIpGroup(2).withSharedIp("127.0.0.1"));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(
request,
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"sharedIpGroupId\":2,\"addresses\":{\"public\":[\"127.0.0.1\"]}}}",
"application/json", false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDeleteImage() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("deleteImage", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "DELETE http://serverManagementUrl/images/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
checkFilters(request);
}
public void testListServers() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
Date now = new Date(10000000l);
public void testListServersOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/servers?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListServersDetail() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testGetServer() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testListFlavors() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "GET http://serverManagementUrl/flavors?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListFlavorsOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/flavors?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListFlavorsDetail() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
assertRequestLineEquals(request, "GET http://serverManagementUrl/flavors/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListFlavorsDetailOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails().changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/flavors/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testGetFlavor() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getFlavor", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/flavors/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testListImages() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "GET http://serverManagementUrl/images?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListImagesDetail() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
assertRequestLineEquals(request, "GET http://serverManagementUrl/images/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListImagesOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/images?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListImagesDetailOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails().changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/images/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testGetImage() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getImage", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/images/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testDeleteServer() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("deleteServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "DELETE http://serverManagementUrl/servers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
checkFilters(request);
}
public void testShareIpNoConfig() throws IOException, SecurityException, NoSuchMethodException, UnknownHostException {
Method method = NovaAsyncClient.class.getMethod("shareIp", String.class, int.class, int.class,
boolean.class);
HttpRequest request = processor.createRequest(method, "127.0.0.1", 2, 3, false);
assertRequestLineEquals(request, "PUT http://serverManagementUrl/servers/2/ips/public/127.0.0.1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"shareIp\":{\"sharedIpGroupId\":3,\"configureServer\":false}}",
MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testShareIpConfig() throws IOException, SecurityException, NoSuchMethodException, UnknownHostException {
Method method = NovaAsyncClient.class.getMethod("shareIp", String.class, int.class, int.class,
boolean.class);
HttpRequest request = processor.createRequest(method, "127.0.0.1", 2, 3, true);
assertRequestLineEquals(request, "PUT http://serverManagementUrl/servers/2/ips/public/127.0.0.1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"shareIp\":{\"sharedIpGroupId\":3,\"configureServer\":true}}",
MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testUnshareIpNoConfig() throws IOException, SecurityException, NoSuchMethodException,
UnknownHostException {
Method method = NovaAsyncClient.class.getMethod("unshareIp", String.class, int.class);
HttpRequest request = processor.createRequest(method, "127.0.0.1", 2, 3, false);
assertRequestLineEquals(request, "DELETE http://serverManagementUrl/servers/2/ips/public/127.0.0.1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(request);
}
public void testReplaceBackupSchedule() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("replaceBackupSchedule", int.class, BackupSchedule.class);
HttpRequest request = processor.createRequest(method, 2, new BackupSchedule(WeeklyBackup.MONDAY,
DailyBackup.H_0800_1000, true));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/2/backup_schedule HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request,
"{\"backupSchedule\":{\"daily\":\"H_0800_1000\",\"enabled\":true,\"weekly\":\"MONDAY\"}}",
MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOn404.class);
checkFilters(request);
}
public void testDeleteBackupSchedule() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("deleteBackupSchedule", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "DELETE http://serverManagementUrl/servers/2/backup_schedule HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
checkFilters(request);
}
public void testChangeAdminPass() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("changeAdminPass", int.class, String.class);
HttpRequest request = processor.createRequest(method, 2, "foo");
assertRequestLineEquals(request, "PUT http://serverManagementUrl/servers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"server\":{\"adminPass\":\"foo\"}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testChangeServerName() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("renameServer", int.class, String.class);
HttpRequest request = processor.createRequest(method, 2, "foo");
assertRequestLineEquals(request, "PUT http://serverManagementUrl/servers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"server\":{\"name\":\"foo\"}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testListSharedIpGroups() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listSharedIpGroups", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "GET http://serverManagementUrl/shared_ip_groups?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListSharedIpGroupsOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listSharedIpGroups", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/shared_ip_groups?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListSharedIpGroupsDetail() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listSharedIpGroups", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
assertRequestLineEquals(request, "GET http://serverManagementUrl/shared_ip_groups/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListSharedIpGroupsDetailOptions() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listSharedIpGroups", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails().changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
"GET http://serverManagementUrl/shared_ip_groups/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testGetSharedIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getSharedIpGroup", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/shared_ip_groups/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
private static final Class<? extends CreateSharedIpGroupOptions[]> createSharedIpGroupOptionsVarargsClass = new CreateSharedIpGroupOptions[] {}
.getClass();
public void testCreateSharedIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createSharedIpGroup", String.class,
createSharedIpGroupOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie");
assertRequestLineEquals(request, "POST http://serverManagementUrl/shared_ip_groups?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"sharedIpGroup\":{\"name\":\"ralphie\"}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testCreateSharedIpGroupWithIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createSharedIpGroup", String.class,
createSharedIpGroupOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", withServer(2));
assertRequestLineEquals(request, "POST http://serverManagementUrl/shared_ip_groups?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"sharedIpGroup\":{\"name\":\"ralphie\",\"server\":2}}",
MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDeleteSharedIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("deleteSharedIpGroup", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "DELETE http://serverManagementUrl/shared_ip_groups/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnFalseOnNotFoundOr404.class);
checkFilters(request);
}
public void testListAddresses() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/2/ips?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testListPublicAddresses() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listPublicAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/2/ips/public?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListPrivateAddresses() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("listPrivateAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/2/ips/private?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListBackupSchedule() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("getBackupSchedule", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "GET http://serverManagementUrl/servers/2/backup_schedule?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(request);
}
public void testCreateImageWithIpGroup() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("createImageFromServer", String.class, int.class);
HttpRequest request = processor.createRequest(method, "ralphie", 2);
assertRequestLineEquals(request, "POST http://serverManagementUrl/images?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"image\":{\"serverId\":2,\"name\":\"ralphie\"}}", MediaType.APPLICATION_JSON,
false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
private static final Class<? extends RebuildServerOptions[]> rebuildServerOptionsVarargsClass = new RebuildServerOptions[] {}
.getClass();
public void testRebuildServer() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("rebuildServer", int.class,
rebuildServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, 3);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/3/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"rebuild\":{}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testRebuildServerWithImage() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("rebuildServer", int.class,
rebuildServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, 3, withImage(2));
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/3/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"rebuild\":{\"imageId\":2}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testReboot() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("rebootServer", int.class, RebootType.class);
HttpRequest request = processor.createRequest(method, 2, RebootType.HARD);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"reboot\":{\"type\":\"HARD\"}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testResize() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("resizeServer", int.class, int.class);
HttpRequest request = processor.createRequest(method, 2, 3);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"resize\":{\"flavorId\":3}}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testConfirmResize() throws IOException, IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("confirmResizeServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"confirmResize\":null}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testRevertResize() throws IOException, SecurityException, NoSuchMethodException {
Method method = NovaAsyncClient.class.getMethod("revertResizeServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, "{\"revertResize\":null}", MediaType.APPLICATION_JSON, false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<NovaAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<NovaAsyncClient>>() {
};
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 2);
assertEquals(request.getFilters().get(0).getClass(), AuthenticateRequest.class);
assertEquals(request.getFilters().get(1).getClass(), AddTimestampQuery.class);
}
@Override
protected Module createModule() {
return new TestNovaRestClientModule();
}
@ConfiguresRestClient
@RequiresHttp
protected static class TestNovaRestClientModule extends NovaRestClientModule {
private TestNovaRestClientModule() {
super(new TestOpenStackAuthenticationModule());
}
@Override
protected URI provideServerUrl(AuthenticationResponse response) {
return URI.create("http://serverManagementUrl");
}
}
protected String provider = "nova";
@Override
public RestContextSpec<?, ?> createContextSpec() {
return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties());
}
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
overrides.setProperty(PROPERTY_REGIONS, "US");
overrides.setProperty(PROPERTY_API_VERSION, "1");
overrides.setProperty(provider + ".endpoint", "https://auth");
overrides.setProperty(provider + ".contextbuilder", NovaContextBuilder.class.getName());
return overrides;
}
}

View File

@ -0,0 +1,639 @@
/**
*
* 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.openstack.nova;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions.Builder.withServer;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.security.SecureRandom;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.Constants;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.openstack.nova.domain.DailyBackup;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.ImageStatus;
import org.jclouds.openstack.nova.domain.RebootType;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.openstack.nova.domain.SharedIpGroup;
import org.jclouds.openstack.nova.domain.WeeklyBackup;
import org.jclouds.openstack.nova.options.RebuildServerOptions;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payload;
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.rest.RestContextFactory;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Tests behavior of {@code NovaClient}
*
* @author Adrian Cole
*/
// disabled [Web Hosting #129069
@Test(groups = "live", sequential = true)
public class NovaClientLiveTest {
protected NovaClient client;
protected SshClient.Factory sshFactory;
private Predicate<IPSocket> socketTester;
protected String provider = "nova";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides;
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
Injector injector = new RestContextFactory().createContextBuilder(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides)
.buildInjector();
client = injector.getInstance(NovaClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
}
public void testListServers() throws Exception {
Set<Server> response = client.listServers();
assert null != response;
long initialContainerCount = response.size();
assertTrue(initialContainerCount >= 0);
}
public void testListServersDetail() throws Exception {
Set<Server> response = client.listServers(withDetails());
assert null != response;
long initialContainerCount = response.size();
assertTrue(initialContainerCount >= 0);
}
public void testListImages() throws Exception {
Set<Image> response = client.listImages();
assert null != response;
long imageCount = response.size();
assertTrue(imageCount >= 1);
for (Image image : response) {
assertTrue(image.getId() >= 0);
assert null != image.getName() : image;
}
}
public void testListImagesDetail() throws Exception {
Set<Image> response = client.listImages(withDetails());
assert null != response;
long imageCount = response.size();
assertTrue(imageCount >= 0);
for (Image image : response) {
assertTrue(image.getId() >= 1);
assert null != image.getName() : image;
assert null != image.getStatus() : image;
}
}
public void testGetImagesDetail() throws Exception {
Set<Image> response = client.listImages(withDetails());
assert null != response;
long imageCount = response.size();
assertTrue(imageCount >= 0);
for (Image image : response) {
try {
Image newDetails = client.getImage(image.getId());
assertEquals(image, newDetails);
} catch (HttpResponseException e) {// Ticket #9867
if (e.getResponse().getStatusCode() != 400)
throw e;
}
}
}
@Test
public void testGetImageDetailsNotFound() throws Exception {
assert client.getImage(12312987) == null;
}
@Test
public void testGetServerDetailsNotFound() throws Exception {
assert client.getServer(12312987) == null;
}
public void testGetServersDetail() throws Exception {
Set<Server> response = client.listServers(withDetails());
assert null != response;
long serverCount = response.size();
assertTrue(serverCount >= 0);
for (Server server : response) {
Server newDetails = client.getServer(server.getId());
assertEquals(server, newDetails);
}
}
public void testListFlavors() throws Exception {
Set<Flavor> response = client.listFlavors();
assert null != response;
long flavorCount = response.size();
assertTrue(flavorCount >= 1);
for (Flavor flavor : response) {
assertTrue(flavor.getId() >= 0);
assert null != flavor.getName() : flavor;
}
}
public void testListFlavorsDetail() throws Exception {
Set<Flavor> response = client.listFlavors(withDetails());
assert null != response;
long flavorCount = response.size();
assertTrue(flavorCount >= 0);
for (Flavor flavor : response) {
assertTrue(flavor.getId() >= 1);
assert null != flavor.getName() : flavor;
assert null != flavor.getDisk() : flavor;
assert null != flavor.getRam() : flavor;
}
}
public void testGetFlavorsDetail() throws Exception {
Set<Flavor> response = client.listFlavors(withDetails());
assert null != response;
long flavorCount = response.size();
assertTrue(flavorCount >= 0);
for (Flavor flavor : response) {
Flavor newDetails = client.getFlavor(flavor.getId());
assertEquals(flavor, newDetails);
}
}
@Test
public void testGetFlavorDetailsNotFound() throws Exception {
assert client.getFlavor(12312987) == null;
}
public void testListSharedIpGroups() throws Exception {
Set<SharedIpGroup> response = client.listSharedIpGroups();
assert null != response;
long sharedIpGroupCount = response.size();
assertTrue(sharedIpGroupCount >= 0);
for (SharedIpGroup sharedIpGroup : response) {
assertTrue(sharedIpGroup.getId() >= 0);
assert null != sharedIpGroup.getName() : sharedIpGroup;
}
}
public void testListSharedIpGroupsDetail() throws Exception {
Set<SharedIpGroup> response = client.listSharedIpGroups(withDetails());
assert null != response;
long sharedIpGroupCount = response.size();
assertTrue(sharedIpGroupCount >= 0);
for (SharedIpGroup sharedIpGroup : response) {
assertTrue(sharedIpGroup.getId() >= 1);
assert null != sharedIpGroup.getName() : sharedIpGroup;
assert null != sharedIpGroup.getServers() : sharedIpGroup;
}
}
public void testGetSharedIpGroupsDetail() throws Exception {
Set<SharedIpGroup> response = client.listSharedIpGroups(withDetails());
assert null != response;
long sharedIpGroupCount = response.size();
assertTrue(sharedIpGroupCount >= 0);
for (SharedIpGroup sharedIpGroup : response) {
SharedIpGroup newDetails = client.getSharedIpGroup(sharedIpGroup.getId());
assertEquals(sharedIpGroup, newDetails);
}
}
@Test
public void testGetSharedIpGroupDetailsNotFound() throws Exception {
assert client.getSharedIpGroup(12312987) == null;
}
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testCreateSharedIpGroup() throws Exception {
SharedIpGroup sharedIpGroup = null;
while (sharedIpGroup == null) {
String sharedIpGroupName = serverPrefix + "createSharedIpGroup" + new SecureRandom().nextInt();
try {
sharedIpGroup = client.createSharedIpGroup(sharedIpGroupName, withServer(serverId));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 400)
continue;
throw e;
}
}
assertNotNull(sharedIpGroup.getName());
sharedIpGroupId = sharedIpGroup.getId();
// Response doesn't include the server id Web Hosting #119311
// assertEquals(sharedIpGroup.getServers(), ImmutableList.of(serverId));
}
private int sharedIpGroupId;
private String serverPrefix = System.getProperty("user.name") + ".cs";
private int serverId;
private String adminPass;
Map<String, String> metadata = ImmutableMap.of("jclouds", "rackspace");
private String ip;
private int serverId2;
private String adminPass2;
private int imageId;
@Test(enabled = false)
public void testCreateServer() throws Exception {
int imageId = 14362;
int flavorId = 1;
Server server = null;
while (server == null) {
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
try {
server = client.createServer(serverName, imageId, flavorId, withFile("/etc/jclouds.txt",
"rackspace".getBytes()).withMetadata(metadata));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 400)
continue;
throw e;
}
}
assertNotNull(server.getAdminPass());
serverId = server.getId();
adminPass = server.getAdminPass();
ip = server.getAddresses().getPublicAddresses().iterator().next();
assertEquals(server.getStatus(), ServerStatus.BUILD);
blockUntilServerActive(serverId);
}
private void blockUntilServerActive(int serverId) throws InterruptedException {
Server currentDetails = null;
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != ServerStatus.ACTIVE; currentDetails = client
.getServer(serverId)) {
System.out.printf("blocking on status active%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
}
private void blockUntilServerVerifyResize(int serverId) throws InterruptedException {
Server currentDetails = null;
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != ServerStatus.VERIFY_RESIZE; currentDetails = client
.getServer(serverId)) {
System.out.printf("blocking on status verify resize%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
}
private void blockUntilImageActive(int imageId) throws InterruptedException {
Image currentDetails = null;
for (currentDetails = client.getImage(imageId); currentDetails.getStatus() != ImageStatus.ACTIVE; currentDetails = client
.getImage(imageId)) {
System.out.printf("blocking on status active%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
}
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testServerDetails() throws Exception {
Server server = client.getServer(serverId);
assertNotNull(server.getHostId());
assertEquals(server.getStatus(), ServerStatus.ACTIVE);
assert server.getProgress() >= 0 : "newDetails.getProgress()" + server.getProgress();
assertEquals(new Integer(14362), server.getImageId());
assertEquals(new Integer(1), server.getFlavorId());
assertNotNull(server.getAddresses());
// listAddresses tests..
assertEquals(client.getAddresses(serverId), server.getAddresses());
assertEquals(server.getAddresses().getPublicAddresses().size(), 1);
assertEquals(client.listPublicAddresses(serverId), server.getAddresses().getPublicAddresses());
assertEquals(server.getAddresses().getPrivateAddresses().size(), 1);
assertEquals(client.listPrivateAddresses(serverId), server.getAddresses().getPrivateAddresses());
// check metadata
assertEquals(server.getMetadata(), metadata);
checkPassOk(server, adminPass);
}
/**
* this tests "personality" as the file looked up was sent during server creation
*/
private void checkPassOk(Server newDetails, String pass) throws IOException {
try {
doCheckPass(newDetails, pass);
} catch (SshException e) {// try twice in case there is a network timeout
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e1) {
}
doCheckPass(newDetails, pass);
}
}
private void doCheckPass(Server newDetails, String pass) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
try {
client.connect();
Payload etcPasswd = client.get("/etc/jclouds.txt");
String etcPasswdContents = Strings2.toStringAndClose(etcPasswd.getInput());
assertEquals("rackspace", etcPasswdContents.trim());
} finally {
if (client != null)
client.disconnect();
}
}
private ExecResponse exec(Server details, String pass, String command) throws IOException {
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
try {
client.connect();
return client.exec(command);
} finally {
if (client != null)
client.disconnect();
}
}
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testRenameServer() throws Exception {
Server server = client.getServer(serverId);
String oldName = server.getName();
client.renameServer(serverId, oldName + "new");
blockUntilServerActive(serverId);
assertEquals(oldName + "new", client.getServer(serverId).getName());
}
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testChangePassword() throws Exception {
client.changeAdminPass(serverId, "elmo");
blockUntilServerActive(serverId);
checkPassOk(client.getServer(serverId), "elmo");
this.adminPass = "elmo";
}
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateSharedIpGroup")
public void testCreateServerIp() throws Exception {
int imageId = 14362;
int flavorId = 1;
Server server = null;
while (server == null) {
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
try {
server = client
.createServer(serverName, imageId, flavorId, withFile("/etc/jclouds.txt", "rackspace".getBytes())
.withMetadata(metadata).withSharedIpGroup(sharedIpGroupId).withSharedIp(ip));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 400)
continue;
throw e;
}
}
assertNotNull(server.getAdminPass());
serverId2 = server.getId();
adminPass2 = server.getAdminPass();
blockUntilServerActive(serverId2);
assertIpConfigured(server, adminPass2);
assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses() + " doesn't contain " + ip;
assertEquals(server.getSharedIpGroupId(), new Integer(sharedIpGroupId));
}
private void assertIpConfigured(Server server, String password) {
try {
ExecResponse response = exec(server, password, "ifconfig -a");
assert response.getOutput().indexOf(ip) > 0 : String.format("server %s didn't get ip %s%n%s", server, ip,
response);
} catch (Exception e) {
e.printStackTrace();
} catch (AssertionError e) {
e.printStackTrace();
}
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testCreateServerIp")
public void testUnshare() throws Exception {
client.unshareIp(ip, serverId2);
blockUntilServerActive(serverId2);
Server server = client.getServer(serverId2);
assert !server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
assertIpNotConfigured(server, adminPass2);
}
private void assertIpNotConfigured(Server server, String password) {
try {
ExecResponse response = exec(server, password, "ifconfig -a");
assert response.getOutput().indexOf(ip) == -1 : String.format("server %s still has get ip %s%n%s", server, ip,
response);
} catch (Exception e) {
e.printStackTrace();
} catch (AssertionError e) {
e.printStackTrace();
}
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testUnshare")
public void testShareConfig() throws Exception {
client.shareIp(ip, serverId2, sharedIpGroupId, true);
blockUntilServerActive(serverId2);
Server server = client.getServer(serverId2);
assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
assertIpConfigured(server, adminPass2);
testUnshare();
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testShareConfig")
public void testShareNoConfig() throws Exception {
client.shareIp(ip, serverId2, sharedIpGroupId, false);
blockUntilServerActive(serverId2);
Server server = client.getServer(serverId2);
assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
assertIpNotConfigured(server, adminPass2);
testUnshare();
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testShareNoConfig")
public void testBackup() throws Exception {
assertEquals(new BackupSchedule(), client.getBackupSchedule(serverId));
BackupSchedule dailyWeekly = new BackupSchedule();
dailyWeekly.setEnabled(true);
dailyWeekly.setWeekly(WeeklyBackup.FRIDAY);
dailyWeekly.setDaily(DailyBackup.H_0400_0600);
client.replaceBackupSchedule(serverId, dailyWeekly);
client.deleteBackupSchedule(serverId);
// disables, doesn't delete: Web Hosting #119571
assertEquals(client.getBackupSchedule(serverId).isEnabled(), false);
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testBackup")
public void testCreateImage() throws Exception {
Image image = client.createImageFromServer("hoofie", serverId);
assertEquals("hoofie", image.getName());
assertEquals(new Integer(serverId), image.getServerId());
imageId = image.getId();
blockUntilImageActive(imageId);
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testCreateImage")
public void testRebuildServer() throws Exception {
client.rebuildServer(serverId, new RebuildServerOptions().withImage(imageId));
blockUntilServerActive(serverId);
// issue Web Hosting #119580 imageId comes back incorrect after rebuild
// assertEquals(new Integer(imageId), client.getServer(serverId).getImageId());
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebuildServer")
public void testRebootHard() throws Exception {
client.rebootServer(serverId, RebootType.HARD);
blockUntilServerActive(serverId);
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebootHard")
public void testRebootSoft() throws Exception {
client.rebootServer(serverId, RebootType.SOFT);
blockUntilServerActive(serverId);
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebootSoft")
public void testRevertResize() throws Exception {
client.resizeServer(serverId, 2);
blockUntilServerVerifyResize(serverId);
client.revertResizeServer(serverId);
blockUntilServerActive(serverId);
assertEquals(new Integer(1), client.getServer(serverId).getFlavorId());
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebootSoft")
public void testConfirmResize() throws Exception {
client.resizeServer(serverId2, 2);
blockUntilServerVerifyResize(serverId2);
client.confirmResizeServer(serverId2);
blockUntilServerActive(serverId2);
assertEquals(new Integer(2), client.getServer(serverId2).getFlavorId());
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = { "testRebootSoft", "testRevertResize",
"testConfirmResize" })
void deleteServer2() {
if (serverId2 > 0) {
client.deleteServer(serverId2);
assert client.getServer(serverId2) == null;
}
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "deleteServer2")
void testDeleteImage() {
if (imageId > 0) {
client.deleteImage(imageId);
assert client.getImage(imageId) == null;
}
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testDeleteImage")
void deleteServer1() {
if (serverId > 0) {
client.deleteServer(serverId);
assert client.getServer(serverId) == null;
}
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = { "deleteServer1" })
void testDeleteSharedIpGroup() {
if (sharedIpGroupId > 0) {
client.deleteSharedIpGroup(sharedIpGroupId);
assert client.getSharedIpGroup(sharedIpGroupId) == null;
}
}
@AfterTest
void deleteServersOnEnd() {
if (serverId > 0) {
client.deleteServer(serverId);
}
if (serverId2 > 0) {
client.deleteServer(serverId2);
}
if (sharedIpGroupId > 0) {
client.deleteSharedIpGroup(sharedIpGroupId);
}
}
}

View File

@ -0,0 +1,89 @@
/**
*
* 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.openstack.nova.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.openstack.nova.NovaAsyncClient;
import org.jclouds.openstack.nova.NovaClient;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.LocationScope;
import org.jclouds.rest.RestContext;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.Test;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true)
public class NovaComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public NovaComputeServiceLiveTest() {
provider = "nova";
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<NovaClient, NovaAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext();
}
@Override
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
super.checkNodes(nodes, tag);
for (NodeMetadata node : nodes) {
assertEquals(node.getLocation().getScope(), LocationScope.HOST);
}
}
@Test(enabled = true, dependsOnMethods = "testReboot", expectedExceptions = UnsupportedOperationException.class)
public void testSuspendResume() throws Exception {
super.testSuspendResume();
}
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
@Override
public void testGetNodesWithDetails() throws Exception {
super.testGetNodesWithDetails();
}
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
@Override
public void testListNodes() throws Exception {
super.testListNodes();
}
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
@Override
public void testDestroyNodes() {
super.testDestroyNodes();
}
}

View File

@ -0,0 +1,38 @@
/**
*
* 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.openstack.nova.compute.config;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class NovaComputeServiceContextModuleTest {
public void testAllStatusCovered() {
for (ServerStatus state : ServerStatus.values()) {
assert NovaComputeServiceDependenciesModule.serverToNodeState.containsKey(state) : state;
}
}
}

View File

@ -0,0 +1,62 @@
/**
*
* 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.openstack.nova.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.openstack.nova.functions.ParseFlavorFromJsonResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.VolumeBuilder;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class FlavorToHardwareTest {
Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build();
@Test
public void test() throws UnknownHostException {
assertEquals(convertFlavor(), new HardwareBuilder().ids("1").name("256 MB Server").processors(
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true).bootDevice(true)
.build())).build());
}
public static Hardware convertFlavor() {
Flavor flavor = ParseFlavorFromJsonResponseTest.parseFlavor();
FlavorToHardware parser = new FlavorToHardware();
return parser.apply(flavor);
}
}

View File

@ -0,0 +1,67 @@
/**
*
* 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.openstack.nova.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystemBuilder;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.functions.ParseImageFromJsonResponseTest;
import org.testng.annotations.Test;
import com.google.inject.Guice;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class NovaImageToImageTest {
@Test
public void testApplyWhereImageNotFound() throws UnknownHostException {
assertEquals(
convertImage(),
new ImageBuilder()
.name("CentOS 5.2")
.operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.2").description("CentOS 5.2").is64Bit(true)
.build()).description("CentOS 5.2").defaultCredentials(new Credentials("root", null))
.ids("2").version("1286712000000").build());
}
public static Image convertImage() {
org.jclouds.openstack.nova.domain.Image image = ParseImageFromJsonResponseTest.parseImage();
NovaImageToImage parser = new NovaImageToImage(new NovaImageToOperatingSystem(new BaseComputeServiceContextModule() {
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.getInstance(Json.class))));
return parser.apply(image);
}
}

View File

@ -0,0 +1,157 @@
/**
*
* 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.openstack.nova.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import org.jclouds.openstack.nova.compute.config.NovaComputeServiceDependenciesModule;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.openstack.nova.functions.ParseServerFromJsonResponseTest;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OperatingSystemBuilder;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.VolumeBuilder;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.testng.annotations.Test;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ServerToNodeMetadataTest {
Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build();
@Test
public void testApplyWhereImageAndHardwareNotFoundButCredentialsFound() throws UnknownHostException {
Credentials creds = new Credentials("root", "abdce");
Map<ServerStatus, NodeState> serverStateToNodeState = NovaComputeServiceDependenciesModule.serverToNodeState;
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of();
Set<org.jclouds.compute.domain.Hardware> hardwares = ImmutableSet.of();
Server server = ParseServerFromJsonResponseTest.parseServer();
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
.<String, Credentials> of("node#1234", creds), Suppliers.<Set<? extends Image>> ofInstance(images),
Suppliers.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
NodeMetadata metadata = parser.apply(server);
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
.imageId("2").id("1234").providerId("1234").name("sample-server").credentials(creds).location(
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
}
@Test
public void testApplyWhereImageAndHardwareNotFound() throws UnknownHostException {
Map<ServerStatus, NodeState> serverStateToNodeState = NovaComputeServiceDependenciesModule.serverToNodeState;
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of();
Set<org.jclouds.compute.domain.Hardware> hardwares = ImmutableSet.of();
Server server = ParseServerFromJsonResponseTest.parseServer();
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
.<String, Credentials> of(), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers
.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
NodeMetadata metadata = parser.apply(server);
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
.imageId("2").id("1234").providerId("1234").name("sample-server").location(
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
}
@Test
public void testApplyWhereImageFoundAndHardwareNotFound() throws UnknownHostException {
Map<ServerStatus, NodeState> serverStateToNodeState = NovaComputeServiceDependenciesModule.serverToNodeState;
org.jclouds.compute.domain.Image jcImage = NovaImageToImageTest.convertImage();
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of(jcImage);
Set<org.jclouds.compute.domain.Hardware> hardwares = ImmutableSet.of();
Server server = ParseServerFromJsonResponseTest.parseServer();
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
.<String, Credentials> of(), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers
.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
NodeMetadata metadata = parser.apply(server);
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
.imageId("2").operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2")
.is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location(
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
}
@Test
public void testApplyWhereImageAndHardwareFound() throws UnknownHostException {
Map<ServerStatus, NodeState> serverStateToNodeState = NovaComputeServiceDependenciesModule.serverToNodeState;
Set<org.jclouds.compute.domain.Image> images = ImmutableSet.of(NovaImageToImageTest.convertImage());
Set<org.jclouds.compute.domain.Hardware> hardwares = ImmutableSet.of(FlavorToHardwareTest.convertFlavor());
Server server = ParseServerFromJsonResponseTest.parseServer();
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap
.<String, Credentials> of(), Suppliers.<Set<? extends Image>> ofInstance(images), Suppliers
.ofInstance(provider), Suppliers.<Set<? extends Hardware>> ofInstance(hardwares));
NodeMetadata metadata = parser.apply(server);
assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses(
ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16"))
.imageId("2").hardware(
new HardwareBuilder().ids("1").name("256 MB Server").processors(
ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes(
ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true)
.bootDevice(true).build())).build()).operatingSystem(
new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2")
.is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location(
new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0")
.description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build())
.userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build());
}
}

View File

@ -0,0 +1,49 @@
/**
*
* 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.openstack.nova.domain;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code CreateImageBinder}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ServerTest {
public void testStatusDoesntAffectEquals() {
Server server1 = new Server(1, "hello");
server1.setStatus(ServerStatus.ACTIVE);
Server server2 = new Server(1, "hello");
server2.setStatus(ServerStatus.BUILD);
assertEquals(server1, server2);
}
public void testProgressDoesntAffectEquals() {
Server server1 = new Server(1, "hello");
server1.setProgress(1);
Server server2 = new Server(1, "hello");
server2.setProgress(2);
assertEquals(server1, server2);
}
}

View File

@ -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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseAddressesFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseAddressesFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_addresses.json");
UnwrapOnlyJsonValue<Addresses> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Addresses>>() {
}));
Addresses response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
List<String> publicAddresses = ImmutableList.of("67.23.10.132", "67.23.10.131");
List<String> privateAddresses = ImmutableList.of("10.176.42.16");
assertEquals(response.getPublicAddresses(), publicAddresses);
assertEquals(response.getPrivateAddresses(), privateAddresses);
}
}

View File

@ -0,0 +1,69 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import org.jclouds.openstack.nova.domain.BackupSchedule;
import org.jclouds.openstack.nova.domain.DailyBackup;
import org.jclouds.openstack.nova.domain.WeeklyBackup;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseBackupScheduleFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseBackupScheduleFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_backupschedule.json");
UnwrapOnlyJsonValue<BackupSchedule> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<BackupSchedule>>() {
}));
BackupSchedule response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(new BackupSchedule(WeeklyBackup.THURSDAY, DailyBackup.H_0400_0600, true), response);
}
public void testNoSchedule() throws UnknownHostException {
UnwrapOnlyJsonValue<BackupSchedule> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<BackupSchedule>>() {
}));
BackupSchedule response = parser.apply(new HttpResponse(200, "ok", Payloads
.newStringPayload("{\"backupSchedule\":{\"enabled\" : false}}")));
assertEquals(new BackupSchedule(), response);
}
}

View File

@ -0,0 +1,65 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.gson.Gson;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseFlavorFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseFlavorFromJsonResponseTest {
public void test() {
Flavor response = parseFlavor();
String json = new Gson().toJson(response);
assertEquals(json, "{\"id\":1,\"name\":\"256 MB Server\",\"disk\":10,\"ram\":256}");
}
public static Flavor parseFlavor() {
Injector i = Guice.createInjector(new GsonModule());
InputStream is = ParseFlavorFromJsonResponseTest.class.getResourceAsStream("/test_get_flavor_details.json");
UnwrapOnlyJsonValue<Flavor> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Flavor>>() {
}));
Flavor response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
return response;
}
}

View File

@ -0,0 +1,82 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.Flavor;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseFlavorListFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseFlavorListFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_flavors.json");
List<Flavor> expects = ImmutableList.of(new Flavor(1, "256 MB Server"), new Flavor(2, "512 MB Server"));
UnwrapOnlyJsonValue<List<Flavor>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Flavor>>>() {
}));
List<Flavor> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, expects);
}
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_flavors_detail.json");
UnwrapOnlyJsonValue<List<Flavor>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Flavor>>>() {
}));
List<Flavor> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response.get(0).getId(), 1);
assertEquals(response.get(0).getName(), "256 MB Server");
assertEquals(response.get(0).getDisk(), new Integer(10));
assertEquals(response.get(0).getRam(), new Integer(256));
assertEquals(response.get(1).getId(), 2);
assertEquals(response.get(1).getName(), "512 MB Server");
assertEquals(response.get(1).getDisk(), new Integer(20));
assertEquals(response.get(1).getRam(), new Integer(512));
}
}

View File

@ -0,0 +1,93 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.ImageStatus;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.testng.annotations.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseImageFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseImageFromJsonResponseTest {
Injector i = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
}
}, new GsonModule());
DateService dateService = i.getInstance(DateService.class);
public void testApplyInputStreamDetails() throws UnknownHostException {
Image response = parseImage();
assertEquals(response.getId(), 2);
assertEquals(response.getName(), "CentOS 5.2");
assertEquals(response.getCreated(), dateService.iso8601SecondsDateParse("2010-08-10T12:00:00Z"));
assertEquals(response.getProgress(), new Integer(80));
assertEquals(response.getServerId(), new Integer(12));
assertEquals(response.getStatus(), ImageStatus.SAVING);
assertEquals(response.getUpdated(), dateService.iso8601SecondsDateParse(("2010-10-10T12:00:00Z")));
}
public static Image parseImage() {
Injector i = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
}
}, new GsonModule());
InputStream is = ParseImageFromJsonResponseTest.class.getResourceAsStream("/test_get_image_details.json");
UnwrapOnlyJsonValue<Image> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Image>>() {
}));
Image response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
return response;
}
}

View File

@ -0,0 +1,102 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.Image;
import org.jclouds.openstack.nova.domain.ImageStatus;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseImageListFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseImageListFromJsonResponseTest {
Injector i = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
}
},new GsonModule());
DateService dateService = i.getInstance(DateService.class);
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_images.json");
List<Image> expects = ImmutableList.of(new Image(2, "CentOS 5.2"), new Image(743, "My Server Backup"));
UnwrapOnlyJsonValue<List<Image>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Image>>>() {
}));
List<Image> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, expects);
}
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_images_detail.json");
UnwrapOnlyJsonValue<List<Image>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Image>>>() {
}));
List<Image> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response.get(0).getId(), 2);
assertEquals(response.get(0).getName(), "CentOS 5.2");
assertEquals(response.get(0).getCreated(), dateService.iso8601SecondsDateParse("2010-08-10T12:00:00Z"));
assertEquals(response.get(0).getProgress(), null);
assertEquals(response.get(0).getServerId(), null);
assertEquals(response.get(0).getStatus(), ImageStatus.ACTIVE);
assertEquals(response.get(0).getUpdated(), dateService.iso8601SecondsDateParse("2010-10-10T12:00:00Z"));
assertEquals(response.get(1).getId(), 743);
assertEquals(response.get(1).getName(), "My Server Backup");
assertEquals(response.get(1).getCreated(), dateService.iso8601SecondsDateParse("2009-07-07T09:56:16-05:00"));
;
assertEquals(response.get(1).getProgress(), new Integer(80));
assertEquals(response.get(1).getServerId(), new Integer(12));
assertEquals(response.get(1).getStatus(), ImageStatus.SAVING);
assertEquals(response.get(1).getUpdated(), dateService.iso8601SecondsDateParse("2010-10-10T12:00:00Z"));
}
}

View File

@ -0,0 +1,71 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseInetAddressListFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseInetAddressListFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testPublic() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_addresses_public.json");
UnwrapOnlyJsonValue<List<String>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<String>>>() {
}));
List<String> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, ImmutableList.of("67.23.10.132", "67.23.10.131"));
}
public void testPrivate() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_addresses_private.json");
UnwrapOnlyJsonValue<List<String>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<String>>>() {
}));
List<String> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, ImmutableList.of("10.176.42.16"));
}
}

View File

@ -0,0 +1,83 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseServerFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseServerFromJsonResponseTest {
public void testApplyInputStreamDetails() throws UnknownHostException {
Server response = parseServer();
assertEquals(response.getId(), 1234);
assertEquals(response.getName(), "sample-server");
assertEquals(response.getImageId(), new Integer(2));
assertEquals(response.getFlavorId(), new Integer(1));
assertEquals(response.getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
assertEquals(response.getStatus(), ServerStatus.BUILD);
assertEquals(response.getProgress(), new Integer(60));
List<String> publicAddresses = Lists.newArrayList("67.23.10.132", "67.23.10.131");
List<String> privateAddresses = Lists.newArrayList("10.176.42.16");
Addresses addresses1 = new Addresses();
addresses1.getPrivateAddresses().addAll(privateAddresses);
addresses1.getPublicAddresses().addAll(publicAddresses);
assertEquals(response.getAddresses(), addresses1);
assertEquals(response.getMetadata(), ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1"));
}
public static Server parseServer() {
Injector i = Guice.createInjector(new GsonModule());
InputStream is = ParseServerFromJsonResponseTest.class.getResourceAsStream("/test_get_server_detail.json");
UnwrapOnlyJsonValue<Server> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Server>>() {
}));
Server response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
return response;
}
}

View File

@ -0,0 +1,107 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.Addresses;
import org.jclouds.openstack.nova.domain.Server;
import org.jclouds.openstack.nova.domain.ServerStatus;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseServerListFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseServerListFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_servers.json");
List<Server> expects = ImmutableList.of(new Server(1234, "sample-server"), new Server(5678, "sample-server2"));
UnwrapOnlyJsonValue<List<Server>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Server>>>() {
}));
List<Server> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, expects);
}
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_servers_detail.json");
UnwrapOnlyJsonValue<List<Server>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<Server>>>() {
}));
List<Server> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response.get(0).getId(), 1234);
assertEquals(response.get(0).getName(), "sample-server");
assertEquals(response.get(0).getImageId(), new Integer(2));
assertEquals(response.get(0).getFlavorId(), new Integer(1));
assertEquals(response.get(0).getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
assertEquals(response.get(0).getStatus(), ServerStatus.BUILD);
assertEquals(response.get(0).getProgress(), new Integer(60));
List<String> publicAddresses = Lists.newArrayList("67.23.10.132", "67.23.10.131");
List<String> privateAddresses = Lists.newArrayList("10.176.42.16");
Addresses addresses1 = new Addresses();
addresses1.getPrivateAddresses().addAll(privateAddresses);
addresses1.getPublicAddresses().addAll(publicAddresses);
assertEquals(response.get(0).getAddresses(), addresses1);
assertEquals(response.get(0).getMetadata(), ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1"));
assertEquals(response.get(1).getId(), 5678);
assertEquals(response.get(1).getName(), "sample-server2");
assertEquals(response.get(1).getImageId(), new Integer(2));
assertEquals(response.get(1).getFlavorId(), new Integer(1));
assertEquals(response.get(1).getHostId(), "9e107d9d372bb6826bd81d3542a419d6");
assertEquals(response.get(1).getStatus(), ServerStatus.ACTIVE);
assertEquals(response.get(1).getProgress(), null);
List<String> publicAddresses2 = Lists.newArrayList("67.23.10.133");
List<String> privateAddresses2 = Lists.newArrayList("10.176.42.17");
Addresses addresses2 = new Addresses();
addresses2.getPrivateAddresses().addAll(privateAddresses2);
addresses2.getPublicAddresses().addAll(publicAddresses2);
assertEquals(response.get(1).getAddresses(), addresses2);
assertEquals(response.get(1).getMetadata(), ImmutableMap.of("Server Label", "DB 1"));
}
}

View File

@ -0,0 +1,62 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import org.jclouds.openstack.nova.domain.SharedIpGroup;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseSharedIpGroupFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseSharedIpGroupFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_get_sharedipgroup_details.json");
UnwrapOnlyJsonValue<SharedIpGroup> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<SharedIpGroup>>() {
}));
SharedIpGroup response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response.getId(), 1234);
assertEquals(response.getName(), "Shared IP Group 1");
assertEquals(response.getServers(), ImmutableList.of(422));
}
}

View File

@ -0,0 +1,84 @@
/**
*
* 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.openstack.nova.functions;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.List;
import org.jclouds.openstack.nova.domain.SharedIpGroup;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.io.Payloads;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ParseSharedIpGroupListFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ParseSharedIpGroupListFromJsonResponseTest {
Injector i = Guice.createInjector(new GsonModule());
public void testApplyInputStream() {
InputStream is = getClass().getResourceAsStream("/test_list_sharedipgroups.json");
List<SharedIpGroup> expects = ImmutableList.of(new SharedIpGroup(1234, "Shared IP Group 1"), new SharedIpGroup(
5678, "Shared IP Group 2"));
UnwrapOnlyJsonValue<List<SharedIpGroup>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<SharedIpGroup>>>() {
}));
List<SharedIpGroup> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response, expects);
}
public void testApplyInputStreamDetails() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/test_list_sharedipgroups_detail.json");
UnwrapOnlyJsonValue<List<SharedIpGroup>> parser = i.getInstance(Key
.get(new TypeLiteral<UnwrapOnlyJsonValue<List<SharedIpGroup>>>() {
}));
List<SharedIpGroup> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
assertEquals(response.get(0).getId(), 1234);
assertEquals(response.get(0).getName(), "Shared IP Group 1");
assertEquals(response.get(0).getServers(), ImmutableList.of(422, 3445));
assertEquals(response.get(1).getId(), 5678);
assertEquals(response.get(1).getName(), "Shared IP Group 2");
assertEquals(response.get(1).getServers(), ImmutableList.of(23203, 2456, 9891));
}
}

View File

@ -0,0 +1,141 @@
/**
*
* 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.openstack.nova.options;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withSharedIp;
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withSharedIpGroup;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import javax.ws.rs.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseFlavorFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class CreateServerOptionsTest {
Injector injector = Guice.createInjector(new GsonModule());
@Test
public void testAddPayloadToRequestMapOfStringStringHttpRequest() {
CreateServerOptions options = new CreateServerOptions();
HttpRequest request = buildRequest(options);
assertEquals("{\"server\":{\"name\":\"foo\",\"imageId\":1,\"flavorId\":2}}", request.getPayload().getRawContent());
}
private HttpRequest buildRequest(CreateServerOptions options) {
injector.injectMembers(options);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
options.bindToRequest(request, ImmutableMap.of("name", "foo", "imageId", "1", "flavorId", "2"));
return request;
}
@Test
public void testWithFile() {
CreateServerOptions options = new CreateServerOptions();
options.withFile("/tmp/rhubarb", "foo".getBytes());
HttpRequest request = buildRequest(options);
assertFile(request);
}
@Test
public void testWithFileStatic() {
CreateServerOptions options = withFile("/tmp/rhubarb", "foo".getBytes());
HttpRequest request = buildRequest(options);
assertFile(request);
}
private void assertFile(HttpRequest request) {
assertEquals(
"{\"server\":{\"name\":\"foo\",\"imageId\":1,\"flavorId\":2,\"personality\":[{\"path\":\"/tmp/rhubarb\",\"contents\":\"Zm9v\"}]}}",
request.getPayload().getRawContent());
}
@Test
public void testWithSharedIpGroup() {
CreateServerOptions options = new CreateServerOptions();
options.withSharedIpGroup(3);
HttpRequest request = buildRequest(options);
assertSharedIpGroup(request);
}
@Test
public void testWithSharedIpGroupStatic() {
CreateServerOptions options = withSharedIpGroup(3);
HttpRequest request = buildRequest(options);
assertSharedIpGroup(request);
}
private void assertSharedIpGroup(HttpRequest request) {
assertEquals("{\"server\":{\"name\":\"foo\",\"imageId\":1,\"flavorId\":2,\"sharedIpGroupId\":3}}", request
.getPayload().getRawContent());
}
@Test
public void testWithMetadata() {
}
@Test
public void testWithSharedIp() {
CreateServerOptions options = new CreateServerOptions();
options.withSharedIpGroup(3).withSharedIp("127.0.0.1");
HttpRequest request = buildRequest(options);
assertSharedIp(request);
}
@Test
public void testWithSharedIpStatic() {
CreateServerOptions options = withSharedIpGroup(3).withSharedIp("127.0.0.1");
HttpRequest request = buildRequest(options);
assertSharedIp(request);
}
private void assertSharedIp(HttpRequest request) {
assertEquals(
"{\"server\":{\"name\":\"foo\",\"imageId\":1,\"flavorId\":2,\"sharedIpGroupId\":3,\"addresses\":{\"public\":[\"127.0.0.1\"]}}}",
request.getPayload().getRawContent());
}
@Test(expectedExceptions = IllegalStateException.class)
public void testWithSharedIpNoGroup() {
CreateServerOptions options = new CreateServerOptions();
options.withSharedIp("127.0.0.1");
buildRequest(options);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testWithSharedIpNoGroupStatic() {
CreateServerOptions options = withSharedIp("127.0.0.1");
buildRequest(options);
}
}

View File

@ -0,0 +1,80 @@
/**
*
* 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.openstack.nova.options;
import static org.jclouds.openstack.nova.options.CreateSharedIpGroupOptions.Builder.withServer;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import javax.ws.rs.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseFlavorFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class CreateSharedIpGroupOptionsTest {
Injector injector = Guice.createInjector(new GsonModule());
@Test
public void testAddPayloadToRequestMapOfStringStringHttpRequest() {
CreateSharedIpGroupOptions options = new CreateSharedIpGroupOptions();
HttpRequest request = buildRequest(options);
assertEquals("{\"sharedIpGroup\":{\"name\":\"foo\"}}", request.getPayload().getRawContent());
}
private HttpRequest buildRequest(CreateSharedIpGroupOptions options) {
injector.injectMembers(options);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
options.bindToRequest(request, ImmutableMap.of("name", "foo"));
return request;
}
@Test
public void testWithServer() {
CreateSharedIpGroupOptions options = new CreateSharedIpGroupOptions();
options.withServer(3);
HttpRequest request = buildRequest(options);
assertSharedIpGroup(request);
}
@Test
public void testWithServerStatic() {
CreateSharedIpGroupOptions options = withServer(3);
HttpRequest request = buildRequest(options);
assertSharedIpGroup(request);
}
private void assertSharedIpGroup(HttpRequest request) {
assertEquals("{\"sharedIpGroup\":{\"name\":\"foo\",\"server\":3}}", request.getPayload().getRawContent());
}
}

View File

@ -0,0 +1,89 @@
/**
*
* 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.openstack.nova.options;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.changesSince;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.maxResults;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.startAt;
import static org.jclouds.openstack.nova.options.ListOptions.Builder.withDetails;
import static org.testng.Assert.assertEquals;
import java.util.Date;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code ListOptions}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ListOptionsTest {
public void testWithDetails() {
ListOptions options = new ListOptions().withDetails();
assertEquals(options.buildPathSuffix(), "/detail");
}
public void testWithDetailsStatic() {
ListOptions options = withDetails();
assertEquals(options.buildPathSuffix(), "/detail");
}
public void testChangesSince() {
Date ifModifiedSince = new Date();
ListOptions options = new ListOptions().changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
.buildQueryParameters().get("changes-since"));
}
public void testStartAt() {
long offset = 1;
ListOptions options = new ListOptions().startAt(offset);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
}
public void testMaxResults() {
int limit = 1;
ListOptions options = new ListOptions().maxResults(limit);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
}
public void testChangesSinceStatic() {
Date ifModifiedSince = new Date();
ListOptions options = changesSince(ifModifiedSince);
assertEquals(ImmutableList.of(ifModifiedSince.getTime() / 1000 + ""), options
.buildQueryParameters().get("changes-since"));
}
public void testStartAtStatic() {
long offset = 1;
ListOptions options = startAt(offset);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
}
public void testMaxResultsStatic() {
int limit = 1;
ListOptions options = maxResults(limit);
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
}
}

View File

@ -0,0 +1,80 @@
/**
*
* 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.openstack.nova.options;
import static org.jclouds.openstack.nova.options.RebuildServerOptions.Builder.withImage;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.HashMap;
import javax.ws.rs.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseFlavorFromJsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class RebuildServerOptionsTest {
Injector injector = Guice.createInjector(new GsonModule());
@Test
public void testAddPayloadToRequestMapOfStringStringHttpRequest() {
RebuildServerOptions options = new RebuildServerOptions();
HttpRequest request = buildRequest(options);
assertEquals("{\"rebuild\":{}}", request.getPayload().getRawContent());
}
private HttpRequest buildRequest(RebuildServerOptions options) {
injector.injectMembers(options);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
options.bindToRequest(request, new HashMap<String, String>());
return request;
}
@Test
public void testWithServer() {
RebuildServerOptions options = new RebuildServerOptions();
options.withImage(3);
HttpRequest request = buildRequest(options);
assertRebuild(request);
}
@Test
public void testWithServerStatic() {
RebuildServerOptions options = withImage(3);
HttpRequest request = buildRequest(options);
assertRebuild(request);
}
private void assertRebuild(HttpRequest request) {
assertEquals("{\"rebuild\":{\"imageId\":3}}", request.getPayload().getRawContent());
}
}

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="BLOBSTOREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-blobstore.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<appender name="ASYNCBLOBSTORE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="BLOBSTOREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.blobstore">
<priority value="DEBUG" />
<appender-ref ref="ASYNCBLOBSTORE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -0,0 +1,8 @@
{
"flavor" : {
"id" : 1,
"name" : "256 MB Server",
"ram" : 256,
"disk" : 10
}
}

View File

@ -0,0 +1,11 @@
{
"image" : {
"id" : 2,
"name" : "CentOS 5.2",
"serverId" : 12,
"updated" : "2010-10-10T12:00:00Z",
"created" : "2010-08-10T12:00:00Z",
"status" : "SAVING",
"progress" : 80
}
}

View File

@ -0,0 +1,25 @@
{
"server" : {
"id" : 1234,
"name" : "sample-server",
"imageId" : 2,
"flavorId" : 1,
"hostId" : "e4d909c290d0fb1ca068ffaddf22cbd0",
"status" : "BUILD",
"progress" : 60,
"addresses" : {
"public" : [
"67.23.10.132",
"67.23.10.131"
],
"private" : [
"10.176.42.16"
]
},
"metadata" : {
"Server Label" : "Web Head 1",
"Image Version" : "2.1"
}
}
}

View File

@ -0,0 +1,7 @@
{
"sharedIpGroup" : {
"id" : 1234,
"name" : "Shared IP Group 1",
"servers" : [422]
}
}

View File

@ -0,0 +1,12 @@
{
"addresses" : {
"public" : [
"67.23.10.132",
"67.23.10.131"
],
"private" : [
"10.176.42.16"
]
}
}

View File

@ -0,0 +1,8 @@
{
"private" : [
"10.176.42.16"
]
}

View File

@ -0,0 +1,7 @@
{
"public" : [
"67.23.10.132",
"67.23.10.131"
]
}

View File

@ -0,0 +1,7 @@
{
"backupSchedule" : {
"enabled" : true,
"weekly" : "THURSDAY",
"daily" : "H_0400_0600"
}
}

View File

@ -0,0 +1,12 @@
{
"flavors" : [
{
"id" : 1,
"name" : "256 MB Server"
},
{
"id" : 2,
"name" : "512 MB Server"
}
]
}

View File

@ -0,0 +1,16 @@
{
"flavors" : [
{
"id" : 1,
"name" : "256 MB Server",
"ram" : 256,
"disk" : 10
},
{
"id" : 2,
"name" : "512 MB Server",
"ram" : 512,
"disk" : 20
}
]
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"id" : 2,
"name" : "CentOS 5.2"
},
{
"id" : 743,
"name" : "My Server Backup"
}
]
}

View File

@ -0,0 +1,20 @@
{
"images" : [
{
"id" : 2,
"name" : "CentOS 5.2",
"updated" : "2010-10-10T12:00:00Z",
"created" : "2010-08-10T12:00:00Z",
"status" : "ACTIVE"
},
{
"id" : 743,
"name" : "My Server Backup",
"serverId" : 12,
"updated" : "2010-10-10T12:00:00Z",
"created" : "2009-07-07T09:56:16-05:00",
"status" : "SAVING",
"progress" : 80
}
]
}

View File

@ -0,0 +1,12 @@
{
"servers" : [
{
"id" : 1234,
"name" : "sample-server"
},
{
"id" : 5678,
"name" : "sample-server2"
}
]
}

View File

@ -0,0 +1,45 @@
{
"servers" : [
{
"id" : 1234,
"name" : "sample-server",
"imageId" : 2,
"flavorId" : 1,
"hostId" : "e4d909c290d0fb1ca068ffaddf22cbd0",
"status" : "BUILD",
"progress" : 60,
"addresses" : {
"public" : [
"67.23.10.132",
"67.23.10.131"
],
"private" : [
"10.176.42.16"
]
},
"metadata" : {
"Server Label" : "Web Head 1",
"Image Version" : "2.1"
}
},
{
"id" : 5678,
"name" : "sample-server2",
"imageId" : 2,
"flavorId" : 1,
"hostId" : "9e107d9d372bb6826bd81d3542a419d6",
"status" : "ACTIVE",
"addresses" : {
"public" : [
"67.23.10.133"
],
"private" : [
"10.176.42.17"
]
},
"metadata" : {
"Server Label" : "DB 1"
}
}
]
}

View File

@ -0,0 +1,12 @@
{
"sharedIpGroups" : [
{
"id" : 1234,
"name" : "Shared IP Group 1"
},
{
"id" : 5678,
"name" : "Shared IP Group 2"
}
]
}

View File

@ -0,0 +1,14 @@
{
"sharedIpGroups" : [
{
"id" : 1234,
"name" : "Shared IP Group 1",
"servers" : [422, 3445]
},
{
"id" : 5678,
"name" : "Shared IP Group 2",
"servers" : [23203, 2456, 9891]
}
]
}