mirror of https://github.com/apache/jclouds.git
Domain model is fixed to match the API v1.1
remaining parts of shared ip functionality is removed
This commit is contained in:
parent
82e3c4ddf7
commit
a131e2a34b
|
@ -18,22 +18,43 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova;
|
package org.jclouds.openstack.nova;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import java.util.Set;
|
||||||
import org.jclouds.openstack.filters.AddTimestampQuery;
|
import java.util.concurrent.ExecutionException;
|
||||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
|
||||||
import org.jclouds.openstack.nova.domain.*;
|
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.domain.Addresses;
|
||||||
|
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.options.CreateServerOptions;
|
import org.jclouds.openstack.nova.options.CreateServerOptions;
|
||||||
import org.jclouds.openstack.nova.options.ListOptions;
|
import org.jclouds.openstack.nova.options.ListOptions;
|
||||||
import org.jclouds.openstack.nova.options.RebuildServerOptions;
|
import org.jclouds.openstack.nova.options.RebuildServerOptions;
|
||||||
import org.jclouds.rest.annotations.*;
|
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||||
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
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.ReturnEmptySetOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
import javax.ws.rs.*;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides asynchronous access to OpenStack Nova via their REST API.
|
* Provides asynchronous access to OpenStack Nova via their REST API.
|
||||||
|
@ -41,221 +62,221 @@ import java.util.concurrent.ExecutionException;
|
||||||
* All commands return a ListenableFuture of the result from OpenStack Nova. Any exceptions incurred
|
* 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
|
* during processing will be wrapped in an {@link ExecutionException} as documented in
|
||||||
* {@link ListenableFuture#get()}.
|
* {@link ListenableFuture#get()}.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
|
||||||
* @see NovaClient
|
* @see NovaClient
|
||||||
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
|
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
|
||||||
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@SkipEncoding({'/', '='})
|
@SkipEncoding({ '/', '=' })
|
||||||
@RequestFilters({AuthenticateRequest.class, AddTimestampQuery.class})
|
@RequestFilters({ AuthenticateRequest.class, AddTimestampQuery.class })
|
||||||
@Endpoint(ServerManagement.class)
|
@Endpoint(ServerManagement.class)
|
||||||
public interface NovaAsyncClient {
|
public interface NovaAsyncClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#listServers
|
* @see NovaClient#listServers
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers")
|
@Path("/servers")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Set<Server>> listServers(ListOptions... options);
|
ListenableFuture<? extends Set<Server>> listServers(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#getServer
|
* @see NovaClient#getServer
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
ListenableFuture<Server> getServer(@PathParam("id") int id);
|
ListenableFuture<Server> getServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#deleteServer
|
* @see NovaClient#deleteServer
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
ListenableFuture<Boolean> deleteServer(@PathParam("id") int id);
|
ListenableFuture<Boolean> deleteServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#rebootServer
|
* @see NovaClient#rebootServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/action")
|
@Path("/servers/{id}/action")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D")
|
@Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D")
|
||||||
ListenableFuture<Void> rebootServer(@PathParam("id") int id, @PayloadParam("type") RebootType rebootType);
|
ListenableFuture<Void> rebootServer(@PathParam("id") int id, @PayloadParam("type") RebootType rebootType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#resizeServer
|
* @see NovaClient#resizeServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/action")
|
@Path("/servers/{id}/action")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D")
|
@Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D")
|
||||||
ListenableFuture<Void> resizeServer(@PathParam("id") int id, @PayloadParam("flavorId") int flavorId);
|
ListenableFuture<Void> resizeServer(@PathParam("id") int id, @PayloadParam("flavorId") int flavorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#confirmResizeServer
|
* @see NovaClient#confirmResizeServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/action")
|
@Path("/servers/{id}/action")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("{\"confirmResize\":null}")
|
@Payload("{\"confirmResize\":null}")
|
||||||
ListenableFuture<Void> confirmResizeServer(@PathParam("id") int id);
|
ListenableFuture<Void> confirmResizeServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#revertResizeServer
|
* @see NovaClient#revertResizeServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/action")
|
@Path("/servers/{id}/action")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("{\"revertResize\":null}")
|
@Payload("{\"revertResize\":null}")
|
||||||
ListenableFuture<Void> revertResizeServer(@PathParam("id") int id);
|
ListenableFuture<Void> revertResizeServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#createServer
|
* @see NovaClient#createServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers")
|
@Path("/servers")
|
||||||
@MapBinder(CreateServerOptions.class)
|
@MapBinder(CreateServerOptions.class)
|
||||||
ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageRef") String imageRef,
|
ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageRef") String imageRef,
|
||||||
@PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
|
@PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#rebuildServer
|
* @see NovaClient#rebuildServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/action")
|
@Path("/servers/{id}/action")
|
||||||
@MapBinder(RebuildServerOptions.class)
|
@MapBinder(RebuildServerOptions.class)
|
||||||
ListenableFuture<Void> rebuildServer(@PathParam("id") int id, RebuildServerOptions... options);
|
ListenableFuture<Void> rebuildServer(@PathParam("id") int id, RebuildServerOptions... options);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#changeAdminPass
|
* @see NovaClient#changeAdminPass
|
||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("%7B\"server\":%7B\"adminPass\":\"{adminPass}\"%7D%7D")
|
@Payload("%7B\"server\":%7B\"adminPass\":\"{adminPass}\"%7D%7D")
|
||||||
ListenableFuture<Void> changeAdminPass(@PathParam("id") int id, @PayloadParam("adminPass") String adminPass);
|
ListenableFuture<Void> changeAdminPass(@PathParam("id") int id, @PayloadParam("adminPass") String adminPass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#renameServer
|
* @see NovaClient#renameServer
|
||||||
*/
|
*/
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D")
|
@Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D")
|
||||||
ListenableFuture<Void> renameServer(@PathParam("id") int id, @PayloadParam("name") String newName);
|
ListenableFuture<Void> renameServer(@PathParam("id") int id, @PayloadParam("name") String newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#listFlavors
|
* @see NovaClient#listFlavors
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/flavors")
|
@Path("/flavors")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Set<Flavor>> listFlavors(ListOptions... options);
|
ListenableFuture<? extends Set<Flavor>> listFlavors(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#getFlavor
|
* @see NovaClient#getFlavor
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/flavors/{id}")
|
@Path("/flavors/{id}")
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
ListenableFuture<Flavor> getFlavor(@PathParam("id") int id);
|
ListenableFuture<Flavor> getFlavor(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#listImages
|
* @see NovaClient#listImages
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/images")
|
@Path("/images")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Set<Image>> listImages(ListOptions... options);
|
ListenableFuture<? extends Set<Image>> listImages(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#getImage
|
* @see NovaClient#getImage
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/images/{id}")
|
@Path("/images/{id}")
|
||||||
ListenableFuture<Image> getImage(@PathParam("id") int id);
|
ListenableFuture<Image> getImage(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#deleteImage
|
* @see NovaClient#deleteImage
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
@Path("/images/{id}")
|
@Path("/images/{id}")
|
||||||
ListenableFuture<Boolean> deleteImage(@PathParam("id") int id);
|
ListenableFuture<Boolean> deleteImage(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#createImageFromServer
|
* @see NovaClient#createImageFromServer
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/images")
|
@Path("/images")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Payload("%7B\"image\":%7B\"serverId\":{serverId},\"name\":\"{name}\"%7D%7D")
|
@Payload("%7B\"image\":%7B\"serverId\":{serverId},\"name\":\"{name}\"%7D%7D")
|
||||||
ListenableFuture<Image> createImageFromServer(@PayloadParam("name") String imageName,
|
ListenableFuture<Image> createImageFromServer(@PayloadParam("name") String imageName,
|
||||||
@PayloadParam("serverId") int serverId);
|
@PayloadParam("serverId") int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#getAddresses(int)
|
* @see NovaClient#listAddresses
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/ips")
|
@Path("/servers/{id}/ips")
|
||||||
ListenableFuture<Addresses> getAddresses(@PathParam("id") int serverId);
|
ListenableFuture<Addresses> getAddresses(@PathParam("id") int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#listPublicAddresses(int)
|
* @see NovaClient#listPublicAddresses
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/ips/public")
|
@Path("/servers/{id}/ips/public")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Set<String>> listPublicAddresses(@PathParam("id") int serverId);
|
ListenableFuture<? extends Set<String>> listPublicAddresses(@PathParam("id") int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see NovaClient#listPrivateAddresses
|
* @see NovaClient#listPrivateAddresses
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Unwrap
|
@Unwrap
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@QueryParams(keys = "format", values = "json")
|
@QueryParams(keys = "format", values = "json")
|
||||||
@Path("/servers/{id}/ips/private")
|
@Path("/servers/{id}/ips/private")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<? extends Set<String>> listPrivateAddresses(@PathParam("id") int serverId);
|
ListenableFuture<? extends Set<String>> listPrivateAddresses(@PathParam("id") int serverId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,18 +18,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova;
|
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.concurrent.Timeout;
|
||||||
import org.jclouds.openstack.nova.domain.*;
|
import org.jclouds.openstack.nova.domain.Addresses;
|
||||||
|
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.options.CreateServerOptions;
|
import org.jclouds.openstack.nova.options.CreateServerOptions;
|
||||||
import org.jclouds.openstack.nova.options.ListOptions;
|
import org.jclouds.openstack.nova.options.ListOptions;
|
||||||
import org.jclouds.openstack.nova.options.RebuildServerOptions;
|
import org.jclouds.openstack.nova.options.RebuildServerOptions;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to OpenStack Nova via their REST API.
|
* Provides access to OpenStack Nova via their REST API.
|
||||||
|
@ -37,224 +43,240 @@ import java.util.concurrent.TimeUnit;
|
||||||
* All commands return a Future of the result from OpenStack Nova. Any exceptions incurred
|
* 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
|
* during processing will be wrapped in an {@link ExecutionException} as documented in
|
||||||
* {@link Future#get()}.
|
* {@link Future#get()}.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
|
||||||
* @see NovaAsyncClient
|
* @see NovaAsyncClient
|
||||||
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
|
* @see <a href="http://wiki.openstack.org/OpenStackAPI_1-1" />
|
||||||
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
||||||
public interface NovaClient {
|
public interface NovaClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all servers (IDs and names only)
|
*
|
||||||
* <p/>
|
* 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.
|
* This operation provides a list of servers associated with your identity. Servers that have been
|
||||||
* <p/>
|
* deleted are not included in this list.
|
||||||
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
* <p/>
|
||||||
* withDetails()}
|
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
||||||
*/
|
* withDetails()}
|
||||||
Set<Server> listServers(ListOptions... options);
|
*/
|
||||||
|
Set<Server> listServers(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation returns details of the specified server.
|
*
|
||||||
*
|
* This operation returns details of the specified server.
|
||||||
* @return null, if the server is not found
|
*
|
||||||
* @see Server
|
* @return null, if the server is not found
|
||||||
*/
|
* @see Server
|
||||||
Server getServer(@PathParam("id") int id);
|
*/
|
||||||
|
Server getServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation deletes a cloud server instance from the system.
|
*
|
||||||
* <p/>
|
* This operation deletes a cloud server instance from the system.
|
||||||
* Note: When a server is deleted, all images created from that server are also removed.
|
* <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
|
* @return false if the server is not found
|
||||||
*/
|
* @see Server
|
||||||
boolean deleteServer(@PathParam("id") int id);
|
*/
|
||||||
|
boolean deleteServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reboot function allows for either a soft or hard reboot of a server.
|
* The reboot function allows for either a soft or hard reboot of a server.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition:
|
* Status Transition:
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - REBOOT - ACTIVE (soft reboot)
|
* ACTIVE - REBOOT - ACTIVE (soft reboot)
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - HARD_REBOOT - ACTIVE (hard reboot)
|
* ACTIVE - HARD_REBOOT - ACTIVE (hard reboot)
|
||||||
*
|
*
|
||||||
* @param rebootType With a soft reboot, the operating system is signaled to restart, which allows for a
|
* @param rebootType
|
||||||
* graceful shutdown of all processes. A hard reboot is the equivalent of power cycling
|
* With a soft reboot, the operating system is signaled to restart, which allows for a
|
||||||
* the server.
|
* graceful shutdown of all processes. A hard reboot is the equivalent of power cycling
|
||||||
*/
|
* the server.
|
||||||
void rebootServer(int id, RebootType rebootType);
|
*/
|
||||||
|
void rebootServer(int id, RebootType rebootType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* 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
|
* 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
|
* 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
|
* original server is removed. All resizes are automatically confirmed after 24 hours if they are
|
||||||
* not confirmed or reverted.
|
* not confirmed or reverted.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition:
|
* Status Transition:
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - QUEUE_RESIZE - PREP_RESIZE - VERIFY_RESIZE
|
* ACTIVE - QUEUE_RESIZE - PREP_RESIZE - VERIFY_RESIZE
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - QUEUE_RESIZE - ACTIVE (on error)
|
* ACTIVE - QUEUE_RESIZE - ACTIVE (on error)
|
||||||
*/
|
*/
|
||||||
void resizeServer(int id, int flavorId);
|
void resizeServer(int id, int flavorId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* 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
|
* 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
|
* 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
|
* original server is removed. All resizes are automatically confirmed after 24 hours if they are
|
||||||
* not confirmed or reverted.
|
* not confirmed or reverted.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition:
|
* Status Transition:
|
||||||
* <p/>
|
* <p/>
|
||||||
* VERIFY_RESIZE - ACTIVE
|
* VERIFY_RESIZE - ACTIVE
|
||||||
*/
|
*/
|
||||||
void confirmResizeServer(int id);
|
void confirmResizeServer(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
* 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
|
* 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
|
* 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
|
* original server is removed. All resizes are automatically reverted after 24 hours if they are
|
||||||
* not reverted or reverted.
|
* not reverted or reverted.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition:
|
* Status Transition:
|
||||||
* <p/>
|
* <p/>
|
||||||
* VERIFY_RESIZE - ACTIVE
|
* VERIFY_RESIZE - ACTIVE
|
||||||
*/
|
*/
|
||||||
void revertResizeServer(int id);
|
void revertResizeServer(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation asynchronously provisions a new server. The progress of this operation depends
|
* 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
|
* 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,
|
* 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
|
* 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
|
* 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.
|
* returned in subsequent GET calls against a given server ID.
|
||||||
*
|
*
|
||||||
* @param options - used to specify extra files, metadata, or ip parameters during server creation.
|
* @param options
|
||||||
*/
|
* - used to specify extra files, metadata, or ip parameters during server creation.
|
||||||
Server createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
|
*/
|
||||||
|
Server createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The rebuild function removes all data on the server and replaces it with the specified image.
|
* The rebuild function removes all data on the server and replaces it with the specified image.
|
||||||
* Server ID and IP addresses remain the same.
|
* Server ID and IP addresses remain the same.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition:
|
* Status Transition:
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - REBUILD - ACTIVE
|
* ACTIVE - REBUILD - ACTIVE
|
||||||
* <p/>
|
* <p/>
|
||||||
* ACTIVE - REBUILD - ERROR (on error)
|
* ACTIVE - REBUILD - ERROR (on error)
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @param options - imageId is an optional argument. If it is not specified, the server is rebuilt
|
* @param options
|
||||||
* with the original imageId.
|
* - imageId is an optional argument. If it is not specified, the server is rebuilt
|
||||||
*/
|
* with the original imageId.
|
||||||
void rebuildServer(int id, RebuildServerOptions... options);
|
*/
|
||||||
|
void rebuildServer(int id, RebuildServerOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation allows you to change the administrative password.
|
* This operation allows you to change the administrative password.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
||||||
*/
|
*
|
||||||
void changeAdminPass(int id, String adminPass);
|
*/
|
||||||
|
void changeAdminPass(int id, String adminPass);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation allows you to update the name of the server. This operation changes the name of
|
* 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.
|
* the server in the OpenStack Nova system and does not change the server host name itself.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
||||||
*/
|
*
|
||||||
void renameServer(int id, String newName);
|
*/
|
||||||
|
void renameServer(int id, String newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List available flavors (IDs and names only)
|
*
|
||||||
* <p/>
|
* List available flavors (IDs and names only)
|
||||||
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
*
|
||||||
* withDetails()}
|
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
||||||
*/
|
* withDetails()}
|
||||||
Set<Flavor> listFlavors(ListOptions... options);
|
*/
|
||||||
|
Set<Flavor> listFlavors(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation returns details of the specified flavor.
|
*
|
||||||
*
|
* This operation returns details of the specified flavor.
|
||||||
* @return null, if the flavor is not found
|
*
|
||||||
* @see Flavor
|
* @return null, if the flavor is not found
|
||||||
*/
|
* @see Flavor
|
||||||
Flavor getFlavor(int id);
|
*/
|
||||||
|
Flavor getFlavor(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List available images (IDs and names only)
|
*
|
||||||
* <p/>
|
* List available images (IDs and names only)
|
||||||
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
*
|
||||||
* withDetails()}
|
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
||||||
*/
|
* withDetails()}
|
||||||
Set<Image> listImages(ListOptions... options);
|
*/
|
||||||
|
Set<Image> listImages(ListOptions... options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation returns details of the specified image.
|
*
|
||||||
*
|
* This operation returns details of the specified image.
|
||||||
* @return null, if the image is not found
|
*
|
||||||
* @see Image
|
* @return null, if the image is not found
|
||||||
*/
|
*
|
||||||
Image getImage(int id);
|
* @see Image
|
||||||
|
*/
|
||||||
|
Image getImage(int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation deletes an image from the system.
|
*
|
||||||
* <p/>
|
* This operation deletes an image from the system.
|
||||||
* Note: Images are immediately removed. Currently, there are no state transitions to track the
|
* <p/>
|
||||||
* delete operation.
|
* 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
|
* @return false if the image is not found
|
||||||
*/
|
* @see Image
|
||||||
boolean deleteImage(int id);
|
*/
|
||||||
|
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
|
* This operation creates a new image for the given server ID. Once complete, a new image will be
|
||||||
* existing custom image replaces the image. The image creation status can be queried by
|
* available that can be used to rebuild or create servers. Specifying the same image name as an
|
||||||
* performing a GET on /images/id and examining the status and progress attributes.
|
* existing custom image replaces the image. The image creation status can be queried by
|
||||||
* <p/>
|
* performing a GET on /images/id and examining the status and progress attributes.
|
||||||
* Status Transition:
|
*
|
||||||
* <p/>
|
* Status Transition:
|
||||||
* QUEUED - PREPARING - SAVING - ACTIVE
|
* <p/>
|
||||||
* <p/>
|
* QUEUED - PREPARING - SAVING - ACTIVE
|
||||||
* QUEUED - PREPARING - SAVING - FAILED (on error)
|
* <p/>
|
||||||
* <p/>
|
* QUEUED - PREPARING - SAVING - FAILED (on error)
|
||||||
* Note: At present, image creation is an asynchronous operation, so coordinating the creation
|
* <p/>
|
||||||
* with data quiescence, etc. is currently not possible.
|
* 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
|
* @throws ResourceNotFoundException
|
||||||
*/
|
* if the server is not found
|
||||||
Image createImageFromServer(String imageName, int serverId);
|
* @see Image
|
||||||
|
*/
|
||||||
|
Image createImageFromServer(String imageName, int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all server addresses
|
* List all server addresses
|
||||||
* <p/>
|
*
|
||||||
* returns empty set if the server doesn't exist
|
* returns empty set if the server doesn't exist
|
||||||
*/
|
*/
|
||||||
Addresses getAddresses(int serverId);
|
Addresses getAddresses(int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all public server addresses
|
* List all public server addresses
|
||||||
* <p/>
|
*
|
||||||
* returns empty set if the server doesn't exist
|
* returns empty set if the server doesn't exist
|
||||||
*/
|
*/
|
||||||
Set<String> listPublicAddresses(int serverId);
|
Set<String> listPublicAddresses(int serverId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List all private server addresses
|
* List all private server addresses
|
||||||
* <p/>
|
*
|
||||||
* returns empty set if the server doesn't exist
|
* returns empty set if the server doesn't exist
|
||||||
*/
|
*/
|
||||||
Set<String> listPrivateAddresses(int serverId);
|
Set<String> listPrivateAddresses(int serverId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,119 +18,127 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.compute.functions;
|
package org.jclouds.openstack.nova.compute.functions;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.base.Predicate;
|
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.common.collect.Iterables;
|
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.Address;
|
||||||
|
import org.jclouds.openstack.nova.domain.Server;
|
||||||
|
import org.jclouds.openstack.nova.domain.ServerStatus;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.domain.*;
|
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.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.domain.Server;
|
|
||||||
import org.jclouds.openstack.nova.domain.ServerStatus;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import com.google.common.base.Function;
|
||||||
import javax.inject.Inject;
|
import com.google.common.base.Predicate;
|
||||||
import javax.inject.Named;
|
import com.google.common.base.Supplier;
|
||||||
import javax.inject.Singleton;
|
import com.google.common.collect.Iterables;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.NoSuchElementException;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
protected final Supplier<Location> location;
|
protected final Supplier<Location> location;
|
||||||
protected final Map<String, Credentials> credentialStore;
|
protected final Map<String, Credentials> credentialStore;
|
||||||
protected final Map<ServerStatus, NodeState> serverToNodeState;
|
protected final Map<ServerStatus, NodeState> serverToNodeState;
|
||||||
protected final Supplier<Set<? extends Image>> images;
|
protected final Supplier<Set<? extends Image>> images;
|
||||||
protected final Supplier<Set<? extends Hardware>> hardwares;
|
protected final Supplier<Set<? extends Hardware>> hardwares;
|
||||||
|
|
||||||
private static class FindImageForServer implements Predicate<Image> {
|
private static class FindImageForServer implements Predicate<Image> {
|
||||||
private final Server instance;
|
private final Server instance;
|
||||||
|
|
||||||
private FindImageForServer(Server instance) {
|
private FindImageForServer(Server instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Image input) {
|
public boolean apply(Image input) {
|
||||||
return input.getProviderId().equals(instance.getImageRef() + "");
|
return input.getProviderId().equals(instance.getImageRef() + "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FindHardwareForServer implements Predicate<Hardware> {
|
private static class FindHardwareForServer implements Predicate<Hardware> {
|
||||||
private final Server instance;
|
private final Server instance;
|
||||||
|
|
||||||
private FindHardwareForServer(Server instance) {
|
private FindHardwareForServer(Server instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Hardware input) {
|
public boolean apply(Hardware input) {
|
||||||
return input.getProviderId().equals(instance.getFlavorRef() + "");
|
return input.getProviderId().equals(instance.getFlavorRef() + "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ServerToNodeMetadata(Map<ServerStatus, NodeState> serverStateToNodeState, Map<String, Credentials> credentialStore,
|
ServerToNodeMetadata(Map<ServerStatus, NodeState> serverStateToNodeState, Map<String, Credentials> credentialStore,
|
||||||
@Memoized Supplier<Set<? extends Image>> images, Supplier<Location> location,
|
@Memoized Supplier<Set<? extends Image>> images, Supplier<Location> location,
|
||||||
@Memoized Supplier<Set<? extends Hardware>> hardwares) {
|
@Memoized Supplier<Set<? extends Hardware>> hardwares) {
|
||||||
this.serverToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
|
this.serverToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
|
||||||
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
|
||||||
this.images = checkNotNull(images, "images");
|
this.images = checkNotNull(images, "images");
|
||||||
this.location = checkNotNull(location, "location");
|
this.location = checkNotNull(location, "location");
|
||||||
this.hardwares = checkNotNull(hardwares, "hardwares");
|
this.hardwares = checkNotNull(hardwares, "hardwares");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata apply(Server from) {
|
public NodeMetadata apply(Server from) {
|
||||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
builder.ids(from.getId() + "");
|
builder.ids(from.getId() + "");
|
||||||
builder.name(from.getName());
|
builder.name(from.getName());
|
||||||
builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description(
|
builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description(
|
||||||
from.getHostId()).parent(location.get()).build());
|
from.getHostId()).parent(location.get()).build());
|
||||||
builder.userMetadata(from.getMetadata());
|
builder.userMetadata(from.getMetadata());
|
||||||
builder.group(parseGroupFromName(from.getName()));
|
builder.group(parseGroupFromName(from.getName()));
|
||||||
builder.imageId(from.getImageRef() + "");
|
builder.imageId(from.getImageRef() + "");
|
||||||
builder.operatingSystem(parseOperatingSystem(from));
|
builder.operatingSystem(parseOperatingSystem(from));
|
||||||
builder.hardware(parseHardware(from));
|
builder.hardware(parseHardware(from));
|
||||||
builder.state(serverToNodeState.get(from.getStatus()));
|
builder.state(serverToNodeState.get(from.getStatus()));
|
||||||
builder.publicAddresses(from.getAddresses().getPublicAddresses());
|
builder.publicAddresses(Iterables.transform(from.getAddresses().getPublicAddresses(), Address.newAddress2StringFunction()));
|
||||||
builder.privateAddresses(from.getAddresses().getPrivateAddresses());
|
builder.privateAddresses(Iterables.transform(from.getAddresses().getPrivateAddresses(), Address.newAddress2StringFunction()));
|
||||||
builder.credentials(credentialStore.get("node#" + from.getId()));
|
builder.credentials(credentialStore.get("node#" + from.getId()));
|
||||||
builder.uri(from.getURI());
|
builder.uri(from.getURI());
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Hardware parseHardware(Server from) {
|
protected Hardware parseHardware(Server from) {
|
||||||
try {
|
try {
|
||||||
return Iterables.find(hardwares.get(), new FindHardwareForServer(from));
|
return Iterables.find(hardwares.get(), new FindHardwareForServer(from));
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
logger.warn("could not find a matching hardware for server %s", from);
|
logger.warn("could not find a matching hardware for server %s", from);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OperatingSystem parseOperatingSystem(Server from) {
|
protected OperatingSystem parseOperatingSystem(Server from) {
|
||||||
try {
|
try {
|
||||||
return Iterables.find(images.get(), new FindImageForServer(from)).getOperatingSystem();
|
return Iterables.find(images.get(), new FindImageForServer(from)).getOperatingSystem();
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
logger.warn("could not find a matching image for server %s in location %s", from, location);
|
logger.warn("could not find a matching image for server %s in location %s", from, location);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Dmitri Babaev
|
||||||
|
*/
|
||||||
|
public class Address {
|
||||||
|
@SerializedName("addr")
|
||||||
|
private String address;
|
||||||
|
private int version;
|
||||||
|
|
||||||
|
//for de-serialization
|
||||||
|
private Address() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address(String address, int version) {
|
||||||
|
this.address = address;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
Address address1 = (Address) o;
|
||||||
|
|
||||||
|
if (version != address1.version) return false;
|
||||||
|
if (address != null ? !address.equals(address1.address) : address1.address != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = address != null ? address.hashCode() : 0;
|
||||||
|
result = 31 * result + version;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<Address, String> newAddress2StringFunction() {
|
||||||
|
return new Function<Address, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(@Nullable Address input) {
|
||||||
|
return input.getAddress();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Address valueOf(String address) {
|
||||||
|
return new Address(address, address.startsWith("::") ? 6 : 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Function<String, Address> newString2AddressFunction() {
|
||||||
|
return new Function<String, Address>() {
|
||||||
|
@Override
|
||||||
|
public Address apply(@Nullable String input) {
|
||||||
|
return valueOf(input);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,113 +18,81 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.domain;
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Addresses {
|
public class Addresses {
|
||||||
|
|
||||||
@SerializedName("public")
|
@SerializedName("public")
|
||||||
private Set<Map<String, String>> publicAddresses = Sets.newHashSet();
|
private Set<Address> publicAddresses = Sets.newLinkedHashSet();
|
||||||
@SerializedName("private")
|
@SerializedName("private")
|
||||||
private Set<Map<String, String>> privateAddresses = Sets.newHashSet();
|
private Set<Address> privateAddresses = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
public Addresses() {
|
public Addresses() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// public Addresses(Set<Map<String, String>> publicAddresses, Set<Map<String, String>> privateAddresses) {
|
public Addresses(Set<Address> publicAddresses, Set<Address> privateAddresses) {
|
||||||
// this.publicAddresses = publicAddresses;
|
this.publicAddresses = publicAddresses;
|
||||||
// this.privateAddresses = privateAddresses;
|
this.privateAddresses = privateAddresses;
|
||||||
// }
|
}
|
||||||
|
|
||||||
public Addresses(Set<String> publicAddresses, Set<String> privateAddresses) {
|
public void setPublicAddresses(Set<Address> publicAddresses) {
|
||||||
this.publicAddresses.clear();
|
this.publicAddresses = publicAddresses;
|
||||||
this.privateAddresses.clear();
|
}
|
||||||
for (String address : publicAddresses) {
|
|
||||||
HashMap<String, String> addressMap = new HashMap<String, String>();
|
|
||||||
addressMap.put("version", "4");
|
|
||||||
addressMap.put("addr", "address");
|
|
||||||
this.publicAddresses.add(addressMap);
|
|
||||||
}
|
|
||||||
for (String address : privateAddresses) {
|
|
||||||
HashMap<String, String> addressMap = new HashMap<String, String>();
|
|
||||||
addressMap.put("version", "4");
|
|
||||||
addressMap.put("addr", "address");
|
|
||||||
this.privateAddresses.add(addressMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
public Set<Address> getPublicAddresses() {
|
||||||
|
return publicAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPublicAddresses(Set<Map<String, String>> publicAddresses) {
|
public void setPrivateAddresses(Set<Address> privateAddresses) {
|
||||||
this.publicAddresses = publicAddresses;
|
this.privateAddresses = privateAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getPublicAddresses() {
|
public Set<Address> getPrivateAddresses() {
|
||||||
HashSet<String> addresses = new HashSet<String>();
|
return privateAddresses;
|
||||||
for (Map<String, String> address : publicAddresses) {
|
}
|
||||||
if (address.containsKey("addr")) {
|
|
||||||
addresses.add(address.get("addr"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrivateAddresses(Set<Map<String, String>> privateAddresses) {
|
@Override
|
||||||
this.privateAddresses = privateAddresses;
|
public String toString() {
|
||||||
}
|
return "Addresses [privateAddresses=" + privateAddresses + ", publicAddresses="
|
||||||
|
+ publicAddresses + "]";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<String> getPrivateAddresses() {
|
@Override
|
||||||
HashSet<String> addresses = new HashSet<String>();
|
public int hashCode() {
|
||||||
for (Map<String, String> address : privateAddresses) {
|
final int prime = 31;
|
||||||
if (address.containsKey("addr")) {
|
int result = 1;
|
||||||
addresses.add(address.get("addr"));
|
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
||||||
}
|
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
|
||||||
}
|
return result;
|
||||||
return addresses;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public boolean equals(Object obj) {
|
||||||
return "Addresses [privateAddresses=" + privateAddresses + ", publicAddresses="
|
if (this == obj)
|
||||||
+ publicAddresses + "]";
|
return true;
|
||||||
}
|
if (obj == null)
|
||||||
|
return false;
|
||||||
@Override
|
if (getClass() != obj.getClass())
|
||||||
public int hashCode() {
|
return false;
|
||||||
final int prime = 31;
|
Addresses other = (Addresses) obj;
|
||||||
int result = 1;
|
if (privateAddresses == null) {
|
||||||
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
|
if (other.privateAddresses != null)
|
||||||
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;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
} else if (!privateAddresses.equals(other.privateAddresses))
|
||||||
|
return false;
|
||||||
|
if (publicAddresses == null) {
|
||||||
|
if (other.publicAddresses != null)
|
||||||
return false;
|
return false;
|
||||||
Addresses other = (Addresses) obj;
|
} else if (!publicAddresses.equals(other.publicAddresses))
|
||||||
if (privateAddresses == null) {
|
return false;
|
||||||
if (other.privateAddresses != null)
|
return true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,217 +18,196 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.domain;
|
package org.jclouds.openstack.nova.domain;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
|
|
||||||
import java.util.Map;
|
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
|
* A server is a virtual machine instance in the OpenStack Nova system. Flavor and image are
|
||||||
* requisite elements when creating a server.
|
* requisite elements when creating a server.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Server extends Resource {
|
public class Server extends Resource {
|
||||||
private int id;
|
private int id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
// private Map<String, Map<String,String>> metadata = Maps.newHashMap();
|
private Map<String, String> metadata = Maps.newHashMap();
|
||||||
|
|
||||||
public Map<String, String> getMetadata() {
|
private Addresses addresses;
|
||||||
return metadata;
|
private String adminPass;
|
||||||
}
|
private String flavorRef;
|
||||||
|
private String hostId;
|
||||||
|
private String imageRef;
|
||||||
|
|
||||||
public void setMetadata(Map<String, String> metadata) {
|
private Integer progress;
|
||||||
this.metadata = metadata;
|
private ServerStatus status;
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, String> metadata = Maps.newHashMap();
|
public Server() {
|
||||||
|
}
|
||||||
|
|
||||||
private Addresses addresses;
|
public Server(int id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
private String adminPass;
|
public void setMetadata(Map<String, String> metadata) {
|
||||||
private String flavorRef;
|
this.metadata = metadata;
|
||||||
private String hostId;
|
}
|
||||||
private String imageRef;
|
|
||||||
|
|
||||||
public String getAffinityId() {
|
public Map<String, String> getMetadata() {
|
||||||
return affinityId;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAffinityId(String affinityId) {
|
public void setAddresses(Addresses addresses) {
|
||||||
this.affinityId = affinityId;
|
this.addresses = addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String affinityId;
|
public Addresses getAddresses() {
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
private Integer progress;
|
public void setAdminPass(String adminPass) {
|
||||||
private ServerStatus status;
|
this.adminPass = adminPass;
|
||||||
|
}
|
||||||
|
|
||||||
public Server() {
|
public String getAdminPass() {
|
||||||
}
|
return adminPass;
|
||||||
|
}
|
||||||
|
|
||||||
public Server(int id, String name) {
|
public void setFlavorRef(String flavorRef) {
|
||||||
this.id = id;
|
this.flavorRef = flavorRef;
|
||||||
this.name = name;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// public void setMetadata(Map<String, String> metadata) {
|
public String getFlavorRef() {
|
||||||
// this.metadata.put("values", metadata);
|
return flavorRef;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// public Map<String, String> getMetadata() {
|
public void setHostId(String hostId) {
|
||||||
// return metadata.get("values");
|
this.hostId = hostId;
|
||||||
// }
|
}
|
||||||
|
|
||||||
public void setAddresses(Addresses addresses) {
|
/**
|
||||||
this.addresses = addresses;
|
* 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 Addresses getAddresses() {
|
public int getId() {
|
||||||
return addresses;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdminPass(String adminPass) {
|
public void setImageRef(String imageRef) {
|
||||||
this.adminPass = adminPass;
|
this.imageRef = imageRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAdminPass() {
|
public String getImageRef() {
|
||||||
return adminPass;
|
return imageRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFlavorRef(String flavorRef) {
|
public String getName() {
|
||||||
this.flavorRef = flavorRef;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFlavorRef() {
|
public void setProgress(Integer progress) {
|
||||||
return flavorRef;
|
this.progress = progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHostId(String hostId) {
|
public Integer getProgress() {
|
||||||
this.hostId = hostId;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setStatus(ServerStatus status) {
|
||||||
* The OpenStack Nova provisioning algorithm has an anti-affinity property that attempts to spread
|
this.status = status;
|
||||||
* 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;
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
public void getImageRef(String imageRef) {
|
@Override
|
||||||
this.imageRef = imageRef;
|
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 + ((flavorRef == null) ? 0 : flavorRef.hashCode());
|
||||||
|
result = prime * result + ((hostId == null) ? 0 : hostId.hashCode());
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + ((imageRef == null) ? 0 : imageRef.hashCode());
|
||||||
|
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public String getImageRef() {
|
@Override
|
||||||
return imageRef;
|
public boolean equals(Object obj) {
|
||||||
}
|
if (this == obj)
|
||||||
|
return true;
|
||||||
public String getName() {
|
if (obj == null)
|
||||||
return name;
|
return false;
|
||||||
}
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
public void setProgress(Integer progress) {
|
Server other = (Server) obj;
|
||||||
this.progress = progress;
|
if (addresses == null) {
|
||||||
}
|
if (other.addresses != null)
|
||||||
|
|
||||||
public Integer getProgress() {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 + ((flavorRef == null) ? 0 : flavorRef.hashCode());
|
|
||||||
result = prime * result + ((hostId == null) ? 0 : hostId.hashCode());
|
|
||||||
result = prime * result + id;
|
|
||||||
result = prime * result + ((imageRef == null) ? 0 : imageRef.hashCode());
|
|
||||||
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
|
|
||||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj)
|
|
||||||
return true;
|
|
||||||
if (obj == null)
|
|
||||||
return false;
|
return false;
|
||||||
if (getClass() != obj.getClass())
|
} else if (!addresses.equals(other.addresses))
|
||||||
|
return false;
|
||||||
|
if (adminPass == null) {
|
||||||
|
if (other.adminPass != null)
|
||||||
return false;
|
return false;
|
||||||
Server other = (Server) obj;
|
} else if (!adminPass.equals(other.adminPass))
|
||||||
if (addresses == null) {
|
return false;
|
||||||
if (other.addresses != null)
|
if (flavorRef == null) {
|
||||||
return false;
|
if (other.flavorRef != null)
|
||||||
} else if (!addresses.equals(other.addresses))
|
|
||||||
return false;
|
return false;
|
||||||
if (adminPass == null) {
|
} else if (!flavorRef.equals(other.flavorRef))
|
||||||
if (other.adminPass != null)
|
return false;
|
||||||
return false;
|
if (hostId == null) {
|
||||||
} else if (!adminPass.equals(other.adminPass))
|
if (other.hostId != null)
|
||||||
return false;
|
return false;
|
||||||
if (flavorRef == null) {
|
} else if (!hostId.equals(other.hostId))
|
||||||
if (other.flavorRef != null)
|
return false;
|
||||||
return false;
|
if (id != other.id)
|
||||||
} else if (!flavorRef.equals(other.flavorRef))
|
return false;
|
||||||
|
if (imageRef == null) {
|
||||||
|
if (other.imageRef != null)
|
||||||
return false;
|
return false;
|
||||||
if (hostId == null) {
|
} else if (!imageRef.equals(other.imageRef))
|
||||||
if (other.hostId != null)
|
return false;
|
||||||
return false;
|
if (metadata == null) {
|
||||||
} else if (!hostId.equals(other.hostId))
|
if (other.metadata != null)
|
||||||
return false;
|
return false;
|
||||||
if (id != other.id)
|
} else if (!metadata.equals(other.metadata))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
return false;
|
return false;
|
||||||
if (imageRef == null) {
|
} else if (!name.equals(other.name))
|
||||||
if (other.imageRef != null)
|
return false;
|
||||||
return false;
|
return true;
|
||||||
} else if (!imageRef.equals(other.imageRef))
|
}
|
||||||
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;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Server [addresses=" + addresses + ", adminPass=" + adminPass + ", flavorRef="
|
return "Server [addresses=" + addresses + ", adminPass=" + adminPass + ", flavorRef="
|
||||||
+ flavorRef + ", hostId=" + hostId + ", id=" + id + ", imageRef=" + imageRef
|
+ flavorRef + ", hostId=" + hostId + ", id=" + id + ", imageRef=" + imageRef
|
||||||
+ ", metadata=" + metadata + ", name=" + name + "]";
|
+ ", metadata=" + metadata + ", name=" + name + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,81 +18,88 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.options;
|
package org.jclouds.openstack.nova.options;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import com.google.common.collect.Lists;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.collect.Maps;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.Base64;
|
import org.jclouds.encryption.internal.Base64;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.openstack.nova.domain.Addresses;
|
import org.jclouds.openstack.nova.domain.Addresses;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.util.Map;
|
import com.google.common.collect.Lists;
|
||||||
import java.util.Map.Entry;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class CreateServerOptions extends BindToJsonPayload {
|
public class CreateServerOptions extends BindToJsonPayload {
|
||||||
|
|
||||||
static class File {
|
static class File {
|
||||||
private final String path;
|
private final String path;
|
||||||
private final String contents;
|
private final String contents;
|
||||||
|
|
||||||
public File(String path, byte[] contents) {
|
public File(String path, byte[] contents) {
|
||||||
this.path = checkNotNull(path, "path");
|
this.path = checkNotNull(path, "path");
|
||||||
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
this.contents = Base64.encodeBytes(checkNotNull(contents, "contents"));
|
||||||
checkArgument(path.getBytes().length < 255, String.format(
|
checkArgument(path.getBytes().length < 255, String.format(
|
||||||
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
|
"maximum length of path is 255 bytes. Path specified %s is %d bytes", path, path
|
||||||
.getBytes().length));
|
.getBytes().length));
|
||||||
checkArgument(contents.length < 10 * 1024, String.format(
|
checkArgument(contents.length < 10 * 1024, String.format(
|
||||||
"maximum size of the file is 10KB. Contents specified is %d bytes",
|
"maximum size of the file is 10KB. Contents specified is %d bytes",
|
||||||
contents.length));
|
contents.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContents() {
|
public String getContents() {
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private class ServerRequest {
|
private class ServerRequest {
|
||||||
final String name;
|
final String name;
|
||||||
final String imageRef;
|
final String imageRef;
|
||||||
final String flavorRef;
|
final String flavorRef;
|
||||||
Map<String, String> metadata;
|
Map<String, String> metadata;
|
||||||
List<File> personality;
|
List<File> personality;
|
||||||
Addresses addresses;
|
Integer sharedIpGroupId;
|
||||||
|
Addresses addresses;
|
||||||
|
|
||||||
private ServerRequest(String name, String imageRef, String flavorRef) {
|
private ServerRequest(String name, String imageRef, String flavorRef) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.imageRef = imageRef;
|
this.imageRef = imageRef;
|
||||||
this.flavorRef = flavorRef;
|
this.flavorRef = flavorRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> metadata = Maps.newHashMap();
|
private Map<String, String> metadata = Maps.newHashMap();
|
||||||
private List<File> files = Lists.newArrayList();
|
private List<File> files = Lists.newArrayList();
|
||||||
private String publicIp;
|
private String publicIp;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
|
||||||
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
|
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
|
||||||
"name parameter not present"), checkNotNull(postParams
|
"name parameter not present"), checkNotNull(postParams
|
||||||
.get("imageRef"), "imageRef parameter not present"), checkNotNull(
|
.get("imageRef"), "imageRef parameter not present"), checkNotNull(
|
||||||
postParams.get("flavorRef"), "flavorRef parameter not present"));
|
postParams.get("flavorRef"), "flavorRef parameter not present"));
|
||||||
if (metadata.size() > 0)
|
if (metadata.size() > 0)
|
||||||
server.metadata = metadata;
|
server.metadata = metadata;
|
||||||
if (files.size() > 0)
|
if (files.size() > 0)
|
||||||
server.personality = files;
|
server.personality = files;
|
||||||
if (publicIp != null) {
|
if (publicIp != null) {
|
||||||
server.addresses = new Addresses();
|
server.addresses = new Addresses();
|
||||||
server.addresses.getPublicAddresses().add(publicIp);
|
server.addresses.getPublicAddresses().add(publicIp);
|
||||||
|
@ -101,71 +108,69 @@ public class CreateServerOptions extends BindToJsonPayload {
|
||||||
return bindToRequest(request, ImmutableMap.of("server", server));
|
return bindToRequest(request, ImmutableMap.of("server", server));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* You may further customize a cloud server by injecting data into the file system of the cloud
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* /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
|
* the root group as owner and group owner, respectively and will allow user and group read
|
||||||
* access only (-r--r-----).
|
* access only (-r--r-----).
|
||||||
*/
|
*/
|
||||||
public CreateServerOptions withFile(String path, byte[] contents) {
|
public CreateServerOptions withFile(String path, byte[] contents) {
|
||||||
checkState(files.size() < 5, "maximum number of files allowed is 5");
|
checkState(files.size() < 5, "maximum number of files allowed is 5");
|
||||||
files.add(new File(path, contents));
|
files.add(new File(path, contents));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom cloud server metadata can also be supplied at launch time. This metadata is stored in
|
* 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
|
* 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
|
* 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.
|
* can be supplied per server is 5.
|
||||||
*/
|
*/
|
||||||
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
public CreateServerOptions withMetadata(Map<String, String> metadata) {
|
||||||
checkNotNull(metadata, "metadata");
|
checkNotNull(metadata, "metadata");
|
||||||
checkArgument(metadata.size() <= 5,
|
checkArgument(metadata.size() <= 5,
|
||||||
"you cannot have more then 5 metadata values. You specified: " + metadata.size());
|
"you cannot have more then 5 metadata values. You specified: " + metadata.size());
|
||||||
for (Entry<String, String> entry : metadata.entrySet()) {
|
for (Entry<String, String> entry : metadata.entrySet()) {
|
||||||
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
checkArgument(entry.getKey().getBytes().length < 255, String.format(
|
||||||
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes",
|
"maximum length of metadata key is 255 bytes. Key specified %s is %d bytes",
|
||||||
entry.getKey(), entry.getKey().getBytes().length));
|
entry.getKey(), entry.getKey().getBytes().length));
|
||||||
checkArgument(
|
checkArgument(
|
||||||
entry.getKey().getBytes().length < 255,
|
entry.getKey().getBytes().length < 255,
|
||||||
String
|
String
|
||||||
.format(
|
.format(
|
||||||
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes",
|
"maximum length of metadata value is 255 bytes. Value specified for %s (%s) is %d bytes",
|
||||||
entry.getKey(), entry.getValue(),
|
entry.getKey(), entry.getValue(),
|
||||||
entry.getValue().getBytes().length));
|
entry.getValue().getBytes().length));
|
||||||
}
|
}
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
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#withFile(String, byte[])
|
* @see CreateServerOptions#withMetadata(Map<String, String>)
|
||||||
*/
|
*/
|
||||||
public static CreateServerOptions withFile(String path, byte[] contents) {
|
public static CreateServerOptions withMetadata(Map<String, String> metadata) {
|
||||||
CreateServerOptions options = new CreateServerOptions();
|
CreateServerOptions options = new CreateServerOptions();
|
||||||
return options.withFile(path, contents);
|
return options.withMetadata(metadata);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @see CreateServerOptions#withMetadata(Map<String, String>)
|
|
||||||
*/
|
|
||||||
public static CreateServerOptions withMetadata(Map<String, String> metadata) {
|
|
||||||
CreateServerOptions options = new CreateServerOptions();
|
|
||||||
return options.withMetadata(metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,7 @@ import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RestClientTest;
|
import org.jclouds.rest.RestClientTest;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
import org.jclouds.rest.RestContextSpec;
|
import org.jclouds.rest.RestContextSpec;
|
||||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
import org.jclouds.rest.functions.*;
|
||||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
|
||||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -54,8 +52,7 @@ import java.util.Properties;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||||
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
|
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.*;
|
||||||
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withMetadata;
|
|
||||||
import static org.jclouds.openstack.nova.options.ListOptions.Builder.changesSince;
|
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.ListOptions.Builder.withDetails;
|
||||||
import static org.jclouds.openstack.nova.options.RebuildServerOptions.Builder.withImage;
|
import static org.jclouds.openstack.nova.options.RebuildServerOptions.Builder.withImage;
|
||||||
|
@ -81,7 +78,7 @@ public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
||||||
|
|
||||||
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
|
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
||||||
assertPayloadEquals(request, "{\"server\":{\"name\":\"ralphie\",\"imageRef\":2,\"flavorRef\":1}}",
|
assertPayloadEquals(request, "{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1}}",
|
||||||
"application/json", false);
|
"application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
||||||
|
@ -103,7 +100,7 @@ public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
||||||
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
||||||
assertPayloadEquals(
|
assertPayloadEquals(
|
||||||
request,
|
request,
|
||||||
"{\"server\":{\"name\":\"ralphie\",\"imageRef\":2,\"flavorRef\":1,\"personality\":[{\"path\":\"/etc/jclouds\",\"contents\":\"Zm9v\"}]}}",
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"personality\":[{\"path\":\"/etc/jclouds\",\"contents\":\"Zm9v\"}]}}",
|
||||||
"application/json", false);
|
"application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
||||||
|
@ -124,7 +121,7 @@ public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
||||||
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
|
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
|
||||||
assertPayloadEquals(request,
|
assertPayloadEquals(request,
|
||||||
"{\"server\":{\"name\":\"ralphie\",\"imageRef\":2,\"flavorRef\":1,\"metadata\":{\"foo\":\"bar\"}}}",
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"metadata\":{\"foo\":\"bar\"}}}",
|
||||||
"application/json", false);
|
"application/json", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
|
||||||
|
@ -506,7 +503,7 @@ public class NovaAsyncClientTest extends RestClientTest<NovaAsyncClient> {
|
||||||
|
|
||||||
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/3/action?format=json HTTP/1.1");
|
assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/3/action?format=json HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(request, "");
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
assertPayloadEquals(request, "{\"rebuild\":{\"imageRef\":2}}", MediaType.APPLICATION_JSON, false);
|
assertPayloadEquals(request, "{\"rebuild\":{\"imageId\":2}}", MediaType.APPLICATION_JSON, false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
|
|
@ -275,11 +275,11 @@ public class NovaClientLiveTest {
|
||||||
"rackspace".getBytes()).withMetadata(metadata));
|
"rackspace".getBytes()).withMetadata(metadata));
|
||||||
|
|
||||||
assertNotNull(server.getAdminPass());
|
assertNotNull(server.getAdminPass());
|
||||||
assertEquals(server.getStatus(), ServerStatus.BUILD);
|
|
||||||
serverId = server.getId();
|
serverId = server.getId();
|
||||||
adminPass = server.getAdminPass();
|
adminPass = server.getAdminPass();
|
||||||
|
ip = server.getAddresses().getPublicAddresses().iterator().next().getAddress();
|
||||||
|
assertEquals(server.getStatus(), ServerStatus.BUILD);
|
||||||
blockUntilServerActive(serverId);
|
blockUntilServerActive(serverId);
|
||||||
ip = client.getServer(serverId).getAddresses().getPublicAddresses().iterator().next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void blockUntilServerActive(int serverId) throws InterruptedException {
|
private void blockUntilServerActive(int serverId) throws InterruptedException {
|
||||||
|
@ -316,8 +316,8 @@ public class NovaClientLiveTest {
|
||||||
assertNotNull(server.getHostId());
|
assertNotNull(server.getHostId());
|
||||||
assertEquals(server.getStatus(), ServerStatus.ACTIVE);
|
assertEquals(server.getStatus(), ServerStatus.ACTIVE);
|
||||||
assert server.getProgress() >= 0 : "newDetails.getProgress()" + server.getProgress();
|
assert server.getProgress() >= 0 : "newDetails.getProgress()" + server.getProgress();
|
||||||
assertEquals("14362", server.getImageRef());
|
assertEquals(new Integer(14362), server.getImageRef());
|
||||||
assertEquals("1", server.getFlavorRef());
|
assertEquals(new Integer(1), server.getFlavorRef());
|
||||||
assertNotNull(server.getAddresses());
|
assertNotNull(server.getAddresses());
|
||||||
// listAddresses tests..
|
// listAddresses tests..
|
||||||
assertEquals(client.getAddresses(serverId), server.getAddresses());
|
assertEquals(client.getAddresses(serverId), server.getAddresses());
|
||||||
|
@ -328,12 +328,21 @@ public class NovaClientLiveTest {
|
||||||
|
|
||||||
// check metadata
|
// check metadata
|
||||||
assertEquals(server.getMetadata(), metadata);
|
assertEquals(server.getMetadata(), metadata);
|
||||||
assertPassword(server, adminPass);
|
|
||||||
|
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 {
|
||||||
|
doCheckPass(newDetails, pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void assertPassword(Server server, String pass) throws IOException {
|
private void doCheckPass(Server newDetails, String pass) throws IOException {
|
||||||
IPSocket socket = new IPSocket(Iterables.get(server.getAddresses().getPublicAddresses(), 0), 22);
|
IPSocket socket = new IPSocket(Iterables.get(newDetails.getAddresses().getPublicAddresses(), 0).getAddress(), 22);
|
||||||
socketTester.apply(socket);
|
socketTester.apply(socket);
|
||||||
|
|
||||||
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
||||||
|
@ -349,7 +358,7 @@ public class NovaClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecResponse exec(Server details, String pass, String command) throws IOException {
|
private ExecResponse exec(Server details, String pass, String command) throws IOException {
|
||||||
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0), 22);
|
IPSocket socket = new IPSocket(Iterables.get(details.getAddresses().getPublicAddresses(), 0).getAddress(), 22);
|
||||||
socketTester.apply(socket);
|
socketTester.apply(socket);
|
||||||
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
SshClient client = sshFactory.create(socket, new Credentials("root", pass));
|
||||||
try {
|
try {
|
||||||
|
@ -374,7 +383,7 @@ public class NovaClientLiveTest {
|
||||||
public void testChangePassword() throws Exception {
|
public void testChangePassword() throws Exception {
|
||||||
client.changeAdminPass(serverId, "elmo");
|
client.changeAdminPass(serverId, "elmo");
|
||||||
blockUntilServerActive(serverId);
|
blockUntilServerActive(serverId);
|
||||||
assertPassword(client.getServer(serverId), "elmo");
|
checkPassOk(client.getServer(serverId), "elmo");
|
||||||
this.adminPass = "elmo";
|
this.adminPass = "elmo";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +420,7 @@ public class NovaClientLiveTest {
|
||||||
client.rebuildServer(serverId, new RebuildServerOptions().withImage(imageId));
|
client.rebuildServer(serverId, new RebuildServerOptions().withImage(imageId));
|
||||||
blockUntilServerActive(serverId);
|
blockUntilServerActive(serverId);
|
||||||
// issue Web Hosting #119580 imageId comes back incorrect after rebuild
|
// issue Web Hosting #119580 imageId comes back incorrect after rebuild
|
||||||
assertEquals(imageId, client.getServer(serverId).getImageRef());
|
assertEquals(new Integer(imageId), client.getServer(serverId).getImageRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebuildServer")
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebuildServer")
|
||||||
|
|
|
@ -39,15 +39,15 @@ public class _NovaClient {
|
||||||
System.out.println(cs.listAssignableLocations());
|
System.out.println(cs.listAssignableLocations());
|
||||||
System.out.println(cs.listNodes());
|
System.out.println(cs.listNodes());
|
||||||
|
|
||||||
TemplateOptions options = new TemplateOptions();
|
/*TemplateOptions options = new TemplateOptions();
|
||||||
Template template = cs.templateBuilder().imageId("13").options(options).build();
|
Template template = cs.templateBuilder().imageId("13").options(options).build();
|
||||||
try {
|
try {
|
||||||
Set<? extends NodeMetadata> metedata = cs.runNodesWithTag("test", 1, template);
|
Set<? extends NodeMetadata> metedata = cs.runNodesWithTag("test", 1, template);
|
||||||
System.out.println(metedata);
|
System.out.println(metedata);
|
||||||
} catch (RunNodesException e) {
|
} catch (RunNodesException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.functions;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
|
@ -28,6 +29,7 @@ import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.nova.domain.Address;
|
||||||
import org.jclouds.openstack.nova.domain.Addresses;
|
import org.jclouds.openstack.nova.domain.Addresses;
|
||||||
import org.jclouds.openstack.nova.domain.Server;
|
import org.jclouds.openstack.nova.domain.Server;
|
||||||
import org.jclouds.openstack.nova.domain.ServerStatus;
|
import org.jclouds.openstack.nova.domain.ServerStatus;
|
||||||
|
@ -49,7 +51,7 @@ import static org.testng.Assert.assertEquals;
|
||||||
public class ParseServerFromJsonResponseTest {
|
public class ParseServerFromJsonResponseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testApplyInputStreamDetails() throws UnknownHostException, NoSuchMethodException, ClassNotFoundException {
|
public void testApplyInputStreamDetails() throws UnknownHostException {
|
||||||
Server response = parseServer();
|
Server response = parseServer();
|
||||||
|
|
||||||
assertEquals(response.getId(), 1234);
|
assertEquals(response.getId(), 1234);
|
||||||
|
@ -57,27 +59,25 @@ public class ParseServerFromJsonResponseTest {
|
||||||
assertEquals(response.getImageRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234");
|
assertEquals(response.getImageRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234");
|
||||||
assertEquals(response.getFlavorRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1");
|
assertEquals(response.getFlavorRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1");
|
||||||
assertEquals(response.getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
|
assertEquals(response.getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
|
||||||
assertEquals(response.getAffinityId(), "fc88bcf8394db9c8d0564e08ca6a9724188a84d1");
|
|
||||||
assertEquals(response.getStatus(), ServerStatus.BUILD);
|
assertEquals(response.getStatus(), ServerStatus.BUILD);
|
||||||
assertEquals(response.getProgress(), new Integer(60));
|
assertEquals(response.getProgress(), new Integer(60));
|
||||||
|
|
||||||
List<String> publicAddresses = ImmutableList.of("67.23.10.132", "::babe:67.23.10.132", "67.23.10.131", "::babe:4317:0A83");
|
List<Address> publicAddresses = ImmutableList.copyOf(Iterables.transform(ImmutableList.of("67.23.10.132", "::babe:67.23.10.132", "67.23.10.131", "::babe:4317:0A83"), Address.newString2AddressFunction()));
|
||||||
List<String> privateAddresses = ImmutableList.of("10.176.42.16", "::babe:10.176.42.16");
|
List<Address> privateAddresses = ImmutableList.copyOf(Iterables.transform(ImmutableList.of("10.176.42.16", "::babe:10.176.42.16"), Address.newString2AddressFunction()));
|
||||||
Addresses addresses1 = new Addresses(new HashSet<String>(publicAddresses), new HashSet<String>(privateAddresses));
|
Addresses addresses1 = new Addresses(new HashSet<Address>(publicAddresses), new HashSet<Address>(privateAddresses));
|
||||||
assertEquals(response.getMetadata(), ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1"));
|
|
||||||
assertEquals(response.getAddresses(), addresses1);
|
assertEquals(response.getAddresses(), addresses1);
|
||||||
|
assertEquals(response.getMetadata(), ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Server parseServer() throws NoSuchMethodException, ClassNotFoundException {
|
public static Server parseServer() {
|
||||||
Injector i = Guice.createInjector(new GsonModule());
|
Injector i = Guice.createInjector(new GsonModule());
|
||||||
|
|
||||||
InputStream is = ParseServerFromJsonResponseTest.class.getResourceAsStream("/test_get_server_detail.json");
|
InputStream is = ParseServerFromJsonResponseTest.class.getResourceAsStream("/test_get_server_detail.json");
|
||||||
|
|
||||||
UnwrapOnlyJsonValue<Server> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Server>>() {
|
UnwrapOnlyJsonValue<Server> parser = i.getInstance(Key.get(new TypeLiteral<UnwrapOnlyJsonValue<Server>>() {
|
||||||
}));
|
}));
|
||||||
|
Server response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
|
||||||
//Function<HttpResponse, ?> parser = i.getInstance(getParserOrThrowException(NovaClient.class.getMethod("getServer", int.class)));
|
return response;
|
||||||
return (Server) parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.functions;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
|
@ -28,6 +29,7 @@ import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.nova.domain.Address;
|
||||||
import org.jclouds.openstack.nova.domain.Addresses;
|
import org.jclouds.openstack.nova.domain.Addresses;
|
||||||
import org.jclouds.openstack.nova.domain.Server;
|
import org.jclouds.openstack.nova.domain.Server;
|
||||||
import org.jclouds.openstack.nova.domain.ServerStatus;
|
import org.jclouds.openstack.nova.domain.ServerStatus;
|
||||||
|
@ -77,15 +79,13 @@ public class ParseServerListFromJsonResponseTest {
|
||||||
assertEquals(response.get(0).getName(), "sample-server");
|
assertEquals(response.get(0).getName(), "sample-server");
|
||||||
assertEquals(response.get(0).getImageRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234");
|
assertEquals(response.get(0).getImageRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234");
|
||||||
assertEquals(response.get(0).getFlavorRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1");
|
assertEquals(response.get(0).getFlavorRef(), "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1");
|
||||||
assertEquals(true, false, "Uncomment next line");
|
|
||||||
//assertEquals(response.getAffinityId(), "fc88bcf8394db9c8d0564e08ca6a9724188a84d1");
|
|
||||||
assertEquals(response.get(0).getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
|
assertEquals(response.get(0).getHostId(), "e4d909c290d0fb1ca068ffaddf22cbd0");
|
||||||
assertEquals(response.get(0).getStatus(), ServerStatus.BUILD);
|
assertEquals(response.get(0).getStatus(), ServerStatus.BUILD);
|
||||||
assertEquals(response.get(0).getProgress(), new Integer(60));
|
assertEquals(response.get(0).getProgress(), new Integer(60));
|
||||||
|
|
||||||
List<String> publicAddresses = ImmutableList.of("67.23.10.132", "::babe:67.23.10.132", "67.23.10.131", "::babe:4317:0A83");
|
List<Address> publicAddresses = ImmutableList.copyOf(Iterables.transform(ImmutableList.of("67.23.10.132", "::babe:67.23.10.132", "67.23.10.131", "::babe:4317:0A83"), Address.newString2AddressFunction()));
|
||||||
List<String> privateAddresses = ImmutableList.of("10.176.42.16", "::babe:10.176.42.16");
|
List<Address> privateAddresses = ImmutableList.copyOf(Iterables.transform(ImmutableList.of("10.176.42.16", "::babe:10.176.42.16"), Address.newString2AddressFunction()));
|
||||||
Addresses addresses1 = new Addresses(new HashSet<String>(publicAddresses), new HashSet<String>(privateAddresses));
|
Addresses addresses1 = new Addresses(new HashSet<Address>(publicAddresses), new HashSet<Address>(privateAddresses));
|
||||||
|
|
||||||
assertEquals(response.get(0).getAddresses(), addresses1);
|
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(0).getMetadata(), ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1"));
|
||||||
|
@ -99,9 +99,9 @@ public class ParseServerListFromJsonResponseTest {
|
||||||
assertEquals(response.get(1).getStatus(), ServerStatus.ACTIVE);
|
assertEquals(response.get(1).getStatus(), ServerStatus.ACTIVE);
|
||||||
assertEquals(response.get(1).getProgress(), null);
|
assertEquals(response.get(1).getProgress(), null);
|
||||||
|
|
||||||
List<String> publicAddresses2 = ImmutableList.of("67.23.10.133", "::babe:67.23.10.133");
|
List<Address> publicAddresses2 = ImmutableList.of(new Address("67.23.10.133", 4), new Address("::babe:67.23.10.133", 4));
|
||||||
List<String> privateAddresses2 = ImmutableList.of("10.176.42.17", "::babe:10.176.42.17");
|
List<Address> privateAddresses2 = ImmutableList.of(new Address("10.176.42.17", 4), new Address("::babe:10.176.42.17", 4));
|
||||||
Addresses addresses2 = new Addresses(new HashSet<String>(publicAddresses2), new HashSet<String>(privateAddresses2));
|
Addresses addresses2 = new Addresses(new HashSet<Address>(publicAddresses2), new HashSet<Address>(privateAddresses2));
|
||||||
|
|
||||||
assertEquals(response.get(1).getAddresses(), addresses2);
|
assertEquals(response.get(1).getAddresses(), addresses2);
|
||||||
assertEquals(response.get(1).getMetadata(), ImmutableMap.of("Server Label", "DB 1"));
|
assertEquals(response.get(1).getMetadata(), ImmutableMap.of("Server Label", "DB 1"));
|
||||||
|
|
|
@ -18,66 +18,67 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.options;
|
package org.jclouds.openstack.nova.options;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
|
||||||
import com.google.inject.Guice;
|
import static org.testng.Assert.assertEquals;
|
||||||
import com.google.inject.Injector;
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.HttpMethod;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import javax.ws.rs.HttpMethod;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.net.URI;
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withFile;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code ParseFlavorFromJsonResponse}
|
* Tests behavior of {@code ParseFlavorFromJsonResponse}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit")
|
@Test(groups = "unit")
|
||||||
public class CreateServerOptionsTest {
|
public class CreateServerOptionsTest {
|
||||||
|
|
||||||
Injector injector = Guice.createInjector(new GsonModule());
|
Injector injector = Guice.createInjector(new GsonModule());
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddPayloadToRequestMapOfStringStringHttpRequest() {
|
public void testAddPayloadToRequestMapOfStringStringHttpRequest() {
|
||||||
CreateServerOptions options = new CreateServerOptions();
|
CreateServerOptions options = new CreateServerOptions();
|
||||||
HttpRequest request = buildRequest(options);
|
HttpRequest request = buildRequest(options);
|
||||||
assertEquals("{\"server\":{\"name\":\"foo\",\"imageRef\":1,\"flavorRef\":2}}", request.getPayload().getRawContent());
|
assertEquals("{\"server\":{\"name\":\"foo\",\"imageId\":1,\"flavorId\":2}}", request.getPayload().getRawContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpRequest buildRequest(CreateServerOptions options) {
|
private HttpRequest buildRequest(CreateServerOptions options) {
|
||||||
injector.injectMembers(options);
|
injector.injectMembers(options);
|
||||||
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost"));
|
||||||
options.bindToRequest(request, ImmutableMap.of("name", "foo", "imageRef", "1", "flavorRef", "2"));
|
options.bindToRequest(request, ImmutableMap.of("name", "foo", "imageId", "1", "flavorId", "2"));
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWithFile() {
|
public void testWithFile() {
|
||||||
CreateServerOptions options = new CreateServerOptions();
|
CreateServerOptions options = new CreateServerOptions();
|
||||||
options.withFile("/tmp/rhubarb", "foo".getBytes());
|
options.withFile("/tmp/rhubarb", "foo".getBytes());
|
||||||
HttpRequest request = buildRequest(options);
|
HttpRequest request = buildRequest(options);
|
||||||
assertFile(request);
|
assertFile(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWithFileStatic() {
|
public void testWithFileStatic() {
|
||||||
CreateServerOptions options = withFile("/tmp/rhubarb", "foo".getBytes());
|
CreateServerOptions options = withFile("/tmp/rhubarb", "foo".getBytes());
|
||||||
HttpRequest request = buildRequest(options);
|
HttpRequest request = buildRequest(options);
|
||||||
assertFile(request);
|
assertFile(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertFile(HttpRequest request) {
|
|
||||||
assertEquals(request.getPayload().getRawContent(),
|
|
||||||
"{\"server\":{\"name\":\"foo\",\"imageRef\":1,\"flavorRef\":2,\"personality\":[{\"path\":\"/tmp/rhubarb\",\"contents\":\"Zm9v\"}]}}");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWithMetadata() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 testWithMetadata() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,56 +1,46 @@
|
||||||
{
|
{
|
||||||
"server" : {
|
"server" : {
|
||||||
"id" : 1234,
|
"id" : 1234,
|
||||||
"name" : "sample-server",
|
"name" : "sample-server",
|
||||||
"imageRef" : "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234",
|
"imageRef" : "https://servers.api.rackspacecloud.com/v1.1/32278/images/1234",
|
||||||
"flavorRef" : "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1",
|
"flavorRef" : "https://servers.api.rackspacecloud.com/v1.1/32278/flavors/1",
|
||||||
"updated" : "2010-10-10T12:00:00Z",
|
"updated" : "2010-10-10T12:00:00Z",
|
||||||
"created" : "2010-08-10T12:00:00Z",
|
"created" : "2010-08-10T12:00:00Z",
|
||||||
"hostId" : "e4d909c290d0fb1ca068ffaddf22cbd0",
|
"hostId" : "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||||
"affinityId" : "fc88bcf8394db9c8d0564e08ca6a9724188a84d1",
|
"affinityId" : "fc88bcf8394db9c8d0564e08ca6a9724188a84d1",
|
||||||
"status" : "BUILD",
|
"status" : "BUILD",
|
||||||
"progress" : 60,
|
"progress" : 60,
|
||||||
"addresses" : {
|
"addresses" : {
|
||||||
"values" : [
|
"public": [
|
||||||
{
|
{"version" : 4, "addr" : "67.23.10.132"},
|
||||||
"id" : "public",
|
{"version" : 6, "addr" : "::babe:67.23.10.132"},
|
||||||
"values" : [
|
{"version" : 4, "addr" : "67.23.10.131"},
|
||||||
{"version" : 4, "addr" : "67.23.10.132"},
|
{"version" : 6, "addr" : "::babe:4317:0A83"}
|
||||||
{"version" : 6, "addr" : "::babe:67.23.10.132"},
|
],
|
||||||
{"version" : 4, "addr" : "67.23.10.131"},
|
"private" : [
|
||||||
{"version" : 6, "addr" : "::babe:4317:0A83"}
|
{"version" : 4, "addr" : "10.176.42.16"},
|
||||||
]
|
{"version" : 6, "addr" : "::babe:10.176.42.16"}
|
||||||
},
|
]
|
||||||
{
|
},
|
||||||
"id" : "private",
|
"metadata" : {
|
||||||
"values" : [
|
"Server Label" : "Web Head 1",
|
||||||
{"version" : 4, "addr" : "10.176.42.16"},
|
"Image Version" : "2.1"
|
||||||
{"version" : 6, "addr" : "::babe:10.176.42.16"}
|
},
|
||||||
]
|
"links": [
|
||||||
}
|
{
|
||||||
]
|
"rel" : "self",
|
||||||
},
|
"href" : "http://servers.api.openstack.org/v1.1/1234/servers/1234"
|
||||||
"metadata" : {
|
},
|
||||||
"values" : {
|
{
|
||||||
"Server Label" : "Web Head 1",
|
"rel" : "bookmark",
|
||||||
"Image Version" : "2.1"
|
"type" : "application/vnd.openstack.compute-v1.1+xml",
|
||||||
}
|
"href" : "http://servers.api.openstack.org/1234/servers/1234"
|
||||||
},
|
},
|
||||||
"links": [
|
{
|
||||||
{
|
"rel" : "bookmark",
|
||||||
"rel" : "self",
|
"type" : "application/vnd.openstack.compute-v1.1+json",
|
||||||
"href" : "http://servers.api.openstack.org/v1.1/1234/servers/1234"
|
"href" : "http://servers.api.openstack.org/1234/servers/1234"
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
"rel" : "bookmark",
|
}
|
||||||
"type" : "application/vnd.openstack.compute-v1.1+xml",
|
}
|
||||||
"href" : "http://servers.api.openstack.org/1234/servers/1234"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"rel" : "bookmark",
|
|
||||||
"type" : "application/vnd.openstack.compute-v1.1+json",
|
|
||||||
"href" : "http://servers.api.openstack.org/1234/servers/1234"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue