mirror of https://github.com/apache/jclouds.git
Issue 355: shell for nova 1.1 based on cloudservers
This commit is contained in:
parent
b9f0cbcb89
commit
1cfbdf00f3
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"flavor" : {
|
||||
"id" : 1,
|
||||
"name" : "256 MB Server",
|
||||
"ram" : 256,
|
||||
"disk" : 10
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"sharedIpGroup" : {
|
||||
"id" : 1234,
|
||||
"name" : "Shared IP Group 1",
|
||||
"servers" : [422]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"addresses" : {
|
||||
"public" : [
|
||||
"67.23.10.132",
|
||||
"67.23.10.131"
|
||||
],
|
||||
"private" : [
|
||||
"10.176.42.16"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
|
||||
"private" : [
|
||||
"10.176.42.16"
|
||||
]
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"public" : [
|
||||
"67.23.10.132",
|
||||
"67.23.10.131"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"backupSchedule" : {
|
||||
"enabled" : true,
|
||||
"weekly" : "THURSDAY",
|
||||
"daily" : "H_0400_0600"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"flavors" : [
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "256 MB Server"
|
||||
},
|
||||
{
|
||||
"id" : 2,
|
||||
"name" : "512 MB Server"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"id" : 2,
|
||||
"name" : "CentOS 5.2"
|
||||
},
|
||||
{
|
||||
"id" : 743,
|
||||
"name" : "My Server Backup"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"servers" : [
|
||||
{
|
||||
"id" : 1234,
|
||||
"name" : "sample-server"
|
||||
},
|
||||
{
|
||||
"id" : 5678,
|
||||
"name" : "sample-server2"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"sharedIpGroups" : [
|
||||
{
|
||||
"id" : 1234,
|
||||
"name" : "Shared IP Group 1"
|
||||
},
|
||||
{
|
||||
"id" : 5678,
|
||||
"name" : "Shared IP Group 2"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue