Add compute service support to openstack-labs nova client

This commit is contained in:
Matt Stephenson 2012-03-09 13:33:30 -08:00
parent 6df17b858d
commit cc4b0cac82
22 changed files with 1278 additions and 74 deletions

View File

@ -79,6 +79,9 @@ public class RegionIdToURIFromAccessForTypeAndVersionSupplier implements RegionI
@Override
public boolean apply(Endpoint input) {
if (input.getVersionId() == null) {
return true;
}
return input.getVersionId().equals(apiVersion);
}

View File

@ -23,7 +23,12 @@ import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.openstack.nova.v1_1.features.*;
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.FloatingIPAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.KeyPairAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
@ -88,5 +93,4 @@ public interface NovaAsyncClient {
@Delegate
KeyPairAsyncClient getKeyPairClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
}

View File

@ -21,16 +21,20 @@ package org.jclouds.openstack.nova.v1_1;
import java.util.List;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.openstack.nova.v1_1.compute.config.NovaComputeServiceContextModule;
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Module;
/**
*
* A context builder for getting nova clients.
*
* @author Adrian Cole
*/
public class NovaContextBuilder extends RestContextBuilder<NovaClient, NovaAsyncClient> {
public class NovaContextBuilder extends ComputeServiceContextBuilder<NovaClient, NovaAsyncClient>
{
public NovaContextBuilder(Properties props) {
super(NovaClient.class, NovaAsyncClient.class, props);
@ -41,4 +45,8 @@ public class NovaContextBuilder extends RestContextBuilder<NovaClient, NovaAsync
modules.add(new NovaRestClientModule());
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new NovaComputeServiceContextModule());
}
}

View File

@ -0,0 +1,71 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.config;
import com.google.common.base.Function;
import com.google.inject.TypeLiteral;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.domain.Location;
import org.jclouds.functions.IdentityFunction;
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.openstack.nova.v1_1.compute.functions.FlavorToHardware;
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToImage;
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
import org.jclouds.openstack.nova.v1_1.compute.functions.ServerToNodeMetadata;
import org.jclouds.openstack.nova.v1_1.compute.strategy.NovaComputeServiceAdapter;
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
import org.jclouds.openstack.nova.v1_1.domain.Server;
/**
* Module for building a compute service context for Nova
*
* @author Matt Stephenson
*/
public class NovaComputeServiceContextModule extends
ComputeServiceAdapterContextModule<NovaClient, NovaAsyncClient, Server, Flavor, org.jclouds.openstack.nova.v1_1.domain.Image, Location>
{
public NovaComputeServiceContextModule()
{
super(NovaClient.class, NovaAsyncClient.class);
}
@SuppressWarnings("unchecked")
@Override
protected void configure()
{
super.configure();
bind(new TypeLiteral<ComputeServiceAdapter<Server, Flavor, org.jclouds.openstack.nova.v1_1.domain.Image, Location>>(){}).to(NovaComputeServiceAdapter.class);
bind(new TypeLiteral<Function<Server, NodeMetadata>>(){}).to(ServerToNodeMetadata.class);
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, Image>>(){}).to(NovaImageToImage.class);
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>(){}).to(NovaImageToOperatingSystem.class);
bind(new TypeLiteral<Function<Flavor, Hardware>>(){}).to(FlavorToHardware.class);
// we aren't converting location from a provider-specific type
bind(new TypeLiteral<Function<Location, Location>>(){}).to((Class)IdentityFunction.class);
}
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.functions;
import com.google.common.base.Function;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
/**
* A function for transforming the nova specific Flavor object to the generic Hardware object.
*
* @author Matt Stephenson
*/
public class FlavorToHardware implements Function<Flavor, Hardware>
{
@Override
public Hardware apply(Flavor flavor)
{
return new HardwareBuilder()
.id(flavor.getId())
.name(flavor.getName())
.ram(flavor.getRam())
.processor(new Processor(flavor.getVcpus(), 1.0))
.volume(new VolumeImpl(Float.valueOf(flavor.getDisk()), true, true))
.build();
}
}

View File

@ -0,0 +1,52 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.functions;
import com.google.common.base.Function;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import javax.inject.Inject;
/**
* A function for transforming a nova-specific Image into a generic Image object.
*
* @author Matt Stephenson
*/
public class NovaImageToImage implements Function<org.jclouds.openstack.nova.v1_1.domain.Image, Image>
{
private final Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem> imageToOs;
@Inject
public NovaImageToImage(Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem> imageToOs)
{
this.imageToOs = imageToOs;
}
@Override
public Image apply(org.jclouds.openstack.nova.v1_1.domain.Image image)
{
return new ImageBuilder()
.id(image.getId())
.name(image.getName())
.operatingSystem(imageToOs.apply(image))
.description(image.getName())
.build();
}
}

View File

@ -0,0 +1,115 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.functions;
import com.google.common.base.CharMatcher;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeServiceUtils;
import org.jclouds.logging.Logger;
import org.jclouds.openstack.nova.v1_1.domain.Image;
import java.util.Arrays;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
/**
* A function for transforming a nova specific Image into a generic OperatingSystem object.
*
* @author Matt Stephenson
*/
public class NovaImageToOperatingSystem implements Function<Image, OperatingSystem>
{
public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
// Windows Server 2008 R2 x64
public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])");
@javax.annotation.Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Map<OsFamily, Map<String, String>> osVersionMap;
@Inject
public NovaImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap)
{
this.osVersionMap = osVersionMap;
}
public OperatingSystem apply(final Image from)
{
OsFamily osFamily = null;
String osVersion = null;
String imageName = Objects.firstNonNull(from.getName(), "unspecified");
boolean is64Bit = true;
if (imageName.indexOf("Windows") != -1)
{
osFamily = OsFamily.WINDOWS;
Matcher matcher = WINDOWS_PATTERN.matcher(from.getName());
if (matcher.find())
{
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
is64Bit = matcher.group(2).equals("x64");
}
}
else
{
if (imageName.contains("Red Hat EL"))
{
osFamily = OsFamily.RHEL;
}
else if (imageName.contains("Oracle EL"))
{
osFamily = OsFamily.OEL;
}
else
{
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split(imageName.toLowerCase());
osFamily = Iterables.find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>()
{
@Override
public boolean apply(@Nullable OsFamily osFamily)
{
return Iterables.any(imageNameParts, Predicates.equalTo(osFamily.name().toLowerCase()));
}
});
}
Matcher matcher = DEFAULT_PATTERN.matcher(imageName);
if (matcher.find() && matcher.groupCount() >= 3)
{
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap);
}
}
return new OperatingSystem(osFamily, imageName, osVersion, null, imageName, is64Bit);
}
}

View File

@ -0,0 +1,76 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.functions;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.openstack.nova.v1_1.domain.Address;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
import java.util.Map;
/**
* A function for transforming a nova-specific Server into a generic NodeMetadata object.
*
* @author Matt Stephenson
*/
public class ServerToNodeMetadata implements Function<Server, NodeMetadata>
{
@VisibleForTesting
public static final Map<ServerStatus, NodeState> serverToNodeState = ImmutableMap.<ServerStatus, NodeState>builder()
.put(ServerStatus.ACTIVE, NodeState.RUNNING)
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)
.put(ServerStatus.DELETED, NodeState.TERMINATED)
.put(ServerStatus.RESIZE, NodeState.PENDING)
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)
.put(ServerStatus.BUILD, NodeState.PENDING)
.put(ServerStatus.PASSWORD, NodeState.PENDING)
.put(ServerStatus.REBUILD, NodeState.PENDING)
.put(ServerStatus.REBOOT, NodeState.PENDING)
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)
.put(ServerStatus.UNKNOWN, NodeState.UNRECOGNIZED)
.put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
@Override
public NodeMetadata apply(Server server)
{
return new NodeMetadataBuilder()
.id(server.getId())
.name(server.getName())
.publicAddresses(Iterables.transform(server.getPublicAddresses(), new AddressToStringTransformationFunction()))
.privateAddresses(Iterables.transform(server.getPrivateAddresses(), new AddressToStringTransformationFunction()))
.state(server.getStatus().getNodeState())
.build();
}
private class AddressToStringTransformationFunction implements Function<Address, String>
{
@Override
public String apply(Address address)
{
return address.getAddr();
}
}
}

View File

@ -0,0 +1,147 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.compute.strategy;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
import org.jclouds.openstack.nova.v1_1.domain.Image;
import org.jclouds.openstack.nova.v1_1.domain.RebootType;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Inject;
/**
* The adapter used by the NovaComputeServiceContextModule to interface the nova-specific domain model to the computeService generic domain model.
*
* @author Matt Stephenson
*/
public class NovaComputeServiceAdapter implements ComputeServiceAdapter<Server, Flavor, Image, Location>
{
private final NovaClient novaClient;
private final ServerClient defaultLocationServerClient;
private final FlavorClient defaultFlavorClient;
private final ImageClient defaultImageClient;
private final Set<String> regions;
@Inject
public NovaComputeServiceAdapter(NovaClient novaClient)
{
this.novaClient = novaClient;
regions = novaClient.getConfiguredRegions();
if (regions.isEmpty())
{
throw new IllegalStateException("No regions exist for this compute service. The Nova compute service requires at least 1 region.");
}
String region = regions.iterator().next();
this.defaultLocationServerClient = novaClient.getServerClientForRegion(region);
this.defaultFlavorClient = novaClient.getFlavorClientForRegion(region);
this.defaultImageClient = novaClient.getImageClientForRegion(region);
}
@Override
public NodeAndInitialCredentials<Server> createNodeWithGroupEncodedIntoName(String tag, String name, Template template)
{
ServerClient serverClient = template.getLocation() != null ? novaClient.getServerClientForRegion(template.getLocation().getId()) : defaultLocationServerClient;
Server server = serverClient.createServer(name, template.getImage().getId(), template.getHardware().getId());
return new NodeAndInitialCredentials<Server>(server, server.getId() + "", LoginCredentials.builder().password(server.getAdminPass()).build());
}
@Override
public Iterable<Flavor> listHardwareProfiles()
{
return defaultFlavorClient.listFlavorsInDetail();
}
@Override
public Iterable<Image> listImages()
{
return defaultImageClient.listImagesInDetail();
}
@Override
public Iterable<Location> listLocations()
{
return Iterables.transform(novaClient.getConfiguredRegions(), new Function<String, Location>()
{
@Override
public Location apply(@Nullable String region)
{
return new LocationBuilder().id(region).description(region).build();
}
});
}
@Override
public Server getNode(String id)
{
return defaultLocationServerClient.getServer(id);
}
@Override
public void destroyNode(String id)
{
defaultLocationServerClient.deleteServer(id);
}
@Override
public void rebootNode(String id)
{
defaultLocationServerClient.rebootServer(id, RebootType.SOFT);
}
@Override
public void resumeNode(String id)
{
throw new UnsupportedOperationException("suspend not supported");
}
@Override
public void suspendNode(String id)
{
throw new UnsupportedOperationException("suspend not supported");
}
@Override
public Iterable<Server> listNodes()
{
ImmutableSet.Builder<Server> servers = new ImmutableSet.Builder<Server>();
for (String region : regions)
{
servers.addAll(novaClient.getServerClientForRegion(region).listServersInDetail());
}
return servers.build();
}
}

View File

@ -18,11 +18,9 @@
*/
package org.jclouds.openstack.nova.v1_1.domain;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Collection;
import java.util.Date;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@ -37,6 +35,8 @@ import org.jclouds.util.Multimaps2;
import com.google.gson.annotations.SerializedName;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A server is a virtual machine instance in the compute system. Flavor and
* image are requisite elements when creating a server.
@ -69,8 +69,8 @@ public class Server extends Resource {
private Resource flavor;
private Map<String, String> metadata = Maps.newHashMap();
// TODO: get gson multimap ad
private Multimap<Address.Type, Address> addresses = LinkedHashMultimap
.create();
private Multimap<Address.Type, Address> addresses = LinkedHashMultimap.create();
private String adminPass;
/**
* @see Server#getTenantId()
@ -211,11 +211,19 @@ public class Server extends Resource {
return this;
}
/**
* @see Server#getAdminPass()
*/
public Builder adminPass(String adminPass) {
this.adminPass = adminPass;
return this;
}
public Server build() {
// return new Server(id, name, links, addresses);
return new Server(id, name, links, tenantId, userId, updated,
created, hostId, accessIPv4, accessIPv6, status, progress,
image, flavor, addresses, metadata);
image, flavor, adminPass, addresses, metadata);
}
public Builder fromServer(Server in) {
@ -268,15 +276,15 @@ public class Server extends Resource {
protected int progress;
protected Resource image;
protected Resource flavor;
protected final String adminPass;
// TODO: get gson multimap adapter!
protected final Map<Address.Type, Set<Address>> addresses;
protected Map<String, String> metadata;
protected String adminPass;
protected Server(String id, String name, Set<Link> links, String tenantId,
String userId, Date updated, Date created, String hostId,
String accessIPv4, String accessIPv6, ServerStatus status,
int progress, Resource image, Resource flavor,
int progress, Resource image, Resource flavor, String adminPass,
Multimap<Address.Type, Address> addresses, Map<String, String> metadata) {
super(id, name, links);
this.tenantId = tenantId;
@ -293,7 +301,7 @@ public class Server extends Resource {
this.metadata = Maps.newHashMap(metadata);
this.addresses = Multimaps2.toOldSchool(ImmutableMultimap
.copyOf(checkNotNull(addresses, "addresses")));
this.adminPass = adminPass;
}
public String getTenantId() {
@ -343,11 +351,6 @@ public class Server extends Resource {
public Map<String, String> getMetadata() {
return this.metadata;
}
public String getAdminPass() {
return this.adminPass;
}
/**
* @return the private ip addresses assigned to the server
@ -402,6 +405,13 @@ public class Server extends Resource {
}
}
/**
* @return the administrative password for this server.
*/
public String getAdminPass() {
return adminPass;
}
@Override
public String toString() {
return toStringHelper("").add("id", id).add("name", name)
@ -411,7 +421,7 @@ public class Server extends Resource {
.add("status", status).add("progress", progress)
.add("image", image).add("flavor", flavor)
.add("metadata", metadata)
.add("links", links).add("addresses", addresses).toString();
.add("links", links).add("addresses", addresses)
.add("adminPass",adminPass).toString();
}
}

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.openstack.nova.v1_1.domain;
import org.jclouds.compute.domain.NodeState;
/**
* 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.
@ -29,7 +31,27 @@ package org.jclouds.openstack.nova.v1_1.domain;
* @author Adrian Cole
*/
public enum ServerStatus {
ACTIVE, BUILD, REBUILD, SUSPENDED, RESIZE, VERIFY_RESIZE, REVERT_RESIZE, PASSWORD, REBOOT, HARD_REBOOT, DELETED, UNKNOWN, ERROR, UNRECOGNIZED;
ACTIVE (NodeState.RUNNING),
BUILD (NodeState.PENDING),
REBUILD (NodeState.PENDING),
SUSPENDED (NodeState.SUSPENDED),
RESIZE (NodeState.PENDING),
VERIFY_RESIZE(NodeState.PENDING),
REVERT_RESIZE(NodeState.PENDING),
PASSWORD (NodeState.PENDING),
REBOOT (NodeState.PENDING),
HARD_REBOOT (NodeState.PENDING),
DELETED (NodeState.TERMINATED),
UNKNOWN (NodeState.UNRECOGNIZED),
ERROR (NodeState.ERROR),
UNRECOGNIZED (NodeState.UNRECOGNIZED);
private final NodeState nodeState;
ServerStatus(NodeState nodeState) {
this.nodeState = nodeState;
}
public String value() {
return name();
@ -43,4 +65,8 @@ public enum ServerStatus {
}
}
public NodeState getNodeState()
{
return nodeState;
}
}

View File

@ -94,9 +94,8 @@ public interface ServerAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Server> getServer(@PathParam("id") String id);
/**
* @see NovaClient#deleteServer
* @see ServerClient#deleteServer
*/
@DELETE
@Consumes
@ -105,7 +104,7 @@ public interface ServerAsyncClient {
ListenableFuture<Boolean> deleteServer(@PathParam("id") String id);
/**
* @see NovaClient#rebootServer
* @see ServerClient#rebootServer
*/
@POST
@Path("/servers/{id}/action")
@ -115,7 +114,7 @@ public interface ServerAsyncClient {
ListenableFuture<Void> rebootServer(@PathParam("id") String id, @PayloadParam("type") RebootType rebootType);
/**
* @see NovaClient#resizeServer
* @see ServerClient#resizeServer
*/
@POST
@Path("/servers/{id}/action")
@ -125,7 +124,7 @@ public interface ServerAsyncClient {
ListenableFuture<Void> resizeServer(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId);
/**
* @see NovaClient#confirmResizeServer
* @see ServerClient#confirmResizeServer
*/
@POST
@Path("/servers/{id}/action")
@ -135,7 +134,7 @@ public interface ServerAsyncClient {
ListenableFuture<Void> confirmResizeServer(@PathParam("id") String id);
/**
* @see NovaClient#revertResizeServer
* @see ServerClient#revertResizeServer
*/
@POST
@Path("/servers/{id}/action")
@ -145,7 +144,7 @@ public interface ServerAsyncClient {
ListenableFuture<Void> revertResizeServer(@PathParam("id") String id);
/**
* @see NovaClient#createServer
* @see ServerClient#createServer
*/
@POST
@Unwrap
@ -156,7 +155,7 @@ public interface ServerAsyncClient {
@PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
/**
* @see NovaClient#rebuildServer
* @see ServerClient#rebuildServer
*/
@POST
@Path("/servers/{id}/action")
@ -166,7 +165,7 @@ public interface ServerAsyncClient {
/**
* @see NovaClient#changeAdminPass
* @see ServerClient#changeAdminPass
*/
@POST
@Path("/servers/{id}/action")
@ -176,7 +175,7 @@ public interface ServerAsyncClient {
ListenableFuture<Void> changeAdminPass(@PathParam("id") String id, @PayloadParam("adminPass") String adminPass);
/**
* @see NovaClient#renameServer
* @see ServerClient#renameServer
*/
@PUT
@Path("/servers/{id}")

View File

@ -18,33 +18,14 @@
*/
package org.jclouds.openstack.nova.v1_1.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
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.concurrent.Timeout;
import org.jclouds.openstack.domain.Resource;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.openstack.nova.v1_1.domain.RebootType;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.options.CreateServerOptions;
import org.jclouds.openstack.nova.v1_1.options.RebuildServerOptions;
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.Unwrap;
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Provides synchronous access to Server.
@ -82,49 +63,92 @@ public interface ServerClient {
Server getServer(String id);
/**
* @see NovaClient#createServer
* Create a new server
*
* @param name
* name of the server to create
* @param imageRef
* reference to the image for the server to use
* @param flavorRef
* reference to the flavor to use when creating the server
* @param options
* optional parameters to be passed into the server creation request
* @return the newly created server
*/
Server createServer(String name, String imageRef,
String flavorRef, CreateServerOptions... options);
Server createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
/**
* @see NovaClient#deleteServer
* Terminate and delete a server.
*
* @param id
* id of the server
* @return True if successful, False otherwise
*/
Boolean deleteServer(String id);
/**
* @see NovaClient#rebootServer
*/
/**
* Reboot a server.
*
* @param id
* id of the server
* @param rebootType
* The type of reboot to perform (Hard/Soft)
*/
void rebootServer(String id, RebootType rebootType);
/**
* @see NovaClient#resizeServer
*/
/**
* Resize a server to a new flavor size.
*
* @param id
* id of the server
* @param flavorId
* id of the new flavor to use
*/
void resizeServer(String id, String flavorId);
/**
* @see NovaClient#confirmResizeServer
/**
* Confirm a resize operation.
*
* @param id
* id of the server
*/
void confirmResizeServer(String id);
/**
* @see NovaClient#revertResizeServer
*/
/**
* Revert a resize operation.
*
* @param id
* id of the server
*/
void revertResizeServer(String id);
/**
* @see NovaClient#rebuildServer
/**
* Rebuild a server.
*
* @param id
* id of the server
* @param options
* Optional paramaters to the rebuilding operation.
*/
void rebuildServer(String id, RebuildServerOptions... options);
/**
* @see NovaClient#changeAdminPass
/**
* Change the administrative password to a server.
*
* @param id
* id of the server
* @param adminPass
* The new administrative password to use
*/
void changeAdminPass(String id, String adminPass);
/**
* @see NovaClient#renameServer
/**
* Rename a server.
*
* @param id
* id of the server
* @param newName
* The new name for the server
*/
void renameServer(String id, String newName);
}

View File

@ -1,3 +1,21 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import static org.testng.Assert.assertEquals;

View File

@ -1,3 +1,21 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import com.google.common.collect.ImmutableMultimap;

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import com.google.common.collect.ImmutableMultimap;
import org.jclouds.compute.ComputeService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.openstack.domain.Resource;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceExpectTest;
import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest;
import org.testng.annotations.Test;
import java.net.URI;
import java.util.Set;
import static org.testng.Assert.*;
/**
* Tests the compute service abstraction of the nova client.
*
* @author Matt Stephenson
*/
@Test(groups = "unit", testName = "NovaComputeServiceExpectTest")
public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTest
{
public void testListServersWhenResponseIs2xx() throws Exception
{
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers(
ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put("X-Auth-Token",
authToken).build()).build();
HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/server_list_details.json")).build();
ComputeService clientWhenServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
responseWithKeystoneAccess, listServers, listServersResponse);
assertNotNull(clientWhenServersExist.listAssignableLocations());
assertEquals(clientWhenServersExist.listAssignableLocations().size(), 1);
assertEquals(clientWhenServersExist.listAssignableLocations().iterator().next().getId(), "North");
assertNotNull(clientWhenServersExist.listNodes());
assertEquals(clientWhenServersExist.listNodes().size(), 1);
assertEquals(clientWhenServersExist.listNodes().iterator().next().getId(), "52415800-8b69-11e0-9b19-734f000004d2");
assertEquals(clientWhenServersExist.listNodes().iterator().next().getName(), "sample-server");
}
public void testListServersWhenReponseIs404IsEmpty() throws Exception
{
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers(
ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put("X-Auth-Token",
authToken).build()).build();
HttpResponse listServersResponse = HttpResponse.builder().statusCode(404).build();
ComputeService clientWhenNoServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
responseWithKeystoneAccess, listServers, listServersResponse);
assertTrue(clientWhenNoServersExist.listNodes().isEmpty());
}
}

View File

@ -0,0 +1,62 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.functions;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.openstack.nova.v1_1.compute.functions.FlavorToHardware;
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
import org.testng.annotations.Test;
import java.util.UUID;
import static org.testng.Assert.*;
/**
* Tests the function used to transform Flavor objects into Hardware objects
*
* @author Matt Stephenson
*/
public class FlavorToHardwareTest
{
@Test
public void testConversion()
{
UUID id = UUID.randomUUID();
Flavor flavorToConvert = Flavor.builder()
.id(id.toString())
.name("Test Flavor " + id)
.ram(262144)
.disk(10000)
.vcpus(16)
.build();
Hardware converted = new FlavorToHardware().apply(flavorToConvert);
assertEquals(converted.getName(), flavorToConvert.getName());
assertEquals(converted.getId(), flavorToConvert.getId());
assertEquals(converted.getRam(), flavorToConvert.getRam());
assertNotNull(converted.getProcessors());
assertFalse(converted.getProcessors().isEmpty());
assertEquals(converted.getProcessors().iterator().next().getCores(), (double)flavorToConvert.getVcpus());
assertNotNull(converted.getVolumes());
assertFalse(converted.getVolumes().isEmpty());
assertEquals(converted.getVolumes().iterator().next().getSize(), Float.valueOf(flavorToConvert.getDisk()));
}
}

View File

@ -0,0 +1,75 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.functions;
import com.google.common.base.Function;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToImage;
import org.jclouds.openstack.nova.v1_1.domain.Image;
import org.testng.annotations.Test;
import java.util.UUID;
import javax.annotation.Nullable;
import static org.testng.Assert.assertEquals;
/**
* Tests the function that transforms nova-specific images to generic images.
*
* @author Matt Stephenson
*/
public class NovaImageToImageTest
{
@Test
public void testConversion()
{
UUID id = UUID.randomUUID();
Image novaImageToConvert = Image.builder().id(id.toString()).name("Test Image " + id).build();
OperatingSystem operatingSystem = new OperatingSystem(OsFamily.UBUNTU, "My Test OS", "My Test Version", "x86", "My Test OS", true);
NovaImageToImage converter = new NovaImageToImage(new MockImageToOsConverter(operatingSystem));
org.jclouds.compute.domain.Image convertedImage = converter.apply(novaImageToConvert);
assertEquals(convertedImage.getId(), novaImageToConvert.getId());
assertEquals(convertedImage.getName(), novaImageToConvert.getName());
assertEquals(convertedImage.getOperatingSystem(), operatingSystem);
}
private class MockImageToOsConverter implements Function<Image, OperatingSystem>
{
private final OperatingSystem operatingSystem;
public MockImageToOsConverter(OperatingSystem operatingSystem)
{
this.operatingSystem = operatingSystem;
}
@Override
public OperatingSystem apply(@Nullable Image image)
{
return operatingSystem;
}
@Override
public boolean equals(@Nullable Object o)
{
return false;
}
}
}

View File

@ -0,0 +1,157 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.functions;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
import org.jclouds.openstack.nova.v1_1.domain.Image;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
import static org.testng.Assert.*;
/**
* Tests for the function for transforming a nova specific Image into a generic OperatingSystem object.
*
* @author Matt Stephenson
*/
public class NovaImageToOperatingSystemTest
{
@Test(dataProvider = "getOsFamilyValues")
public void testOsFamilyValues(OsFamily family)
{
Image imageToConvert = Image.builder().id("id-" + family.name()).name(family.name()).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), family);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), null);
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
@DataProvider
public Object[][] getOsFamilyValues()
{
return Iterables.toArray(Iterables.transform(Arrays.asList(OsFamily.values()), new Function<OsFamily, Object[]>()
{
@Override
public Object[] apply(@Nullable OsFamily osFamily)
{
return new Object[]{osFamily};
}
}), Object[].class);
}
@Test
public void testWindowsServer2008R2x64()
{
String name = "Windows Server 2008 R2 x64";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("Server 2008 R2", "Server-2008-R2"));
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
OperatingSystem convertedOs = converter.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.WINDOWS);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), "Server-2008-R2");
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
@Test
public void testWindows98x86()
{
String name = "Windows 98 x86";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("98", "98"));
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
OperatingSystem convertedOs = converter.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.WINDOWS);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), "98");
assertEquals(convertedOs.getArch(), null);
assertFalse(convertedOs.is64Bit());
}
@Test
public void testRHEL()
{
String name = "Red Hat EL";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.RHEL);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), null);
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
@Test
public void testOEL()
{
String name = "Oracle EL";
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
OperatingSystem convertedOs = converter.apply(imageToConvert);
assertEquals(convertedOs.getName(), imageToConvert.getName());
assertEquals(convertedOs.getFamily(), OsFamily.OEL);
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
assertEquals(convertedOs.getVersion(), null);
assertEquals(convertedOs.getArch(), null);
assertTrue(convertedOs.is64Bit());
}
}

View File

@ -0,0 +1,67 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.functions;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.openstack.nova.v1_1.compute.functions.ServerToNodeMetadata;
import org.jclouds.openstack.nova.v1_1.domain.Address;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
import org.testng.annotations.Test;
import java.util.UUID;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/**
* Tests for the function for transforming a nova specific Server into a generic NodeMetadata object.
*
* @author Matt Stephenson
*/
public class ServerToNodeMetadataTest
{
@Test
public void testConversion()
{
UUID id = UUID.randomUUID();
Server serverToConvert = Server.builder()
.id(id.toString())
.name("Test Server " + id)
.privateAddresses(Address.createV4("10.0.0.1"))
.publicAddresses(Address.createV4("10.0.1.1"))
.status(ServerStatus.ACTIVE)
.build();
ServerToNodeMetadata converter = new ServerToNodeMetadata();
NodeMetadata convertedNodeMetadata = converter.apply(serverToConvert);
assertEquals(serverToConvert.getId(), convertedNodeMetadata.getId());
assertEquals(serverToConvert.getName(), convertedNodeMetadata.getName());
assertEquals(serverToConvert.getStatus().getNodeState(), convertedNodeMetadata.getState());
assertNotNull(convertedNodeMetadata.getPrivateAddresses());
assertEquals(convertedNodeMetadata.getPrivateAddresses().size(), 1);
assertEquals(convertedNodeMetadata.getPrivateAddresses().iterator().next(), "10.0.0.1");
assertNotNull(convertedNodeMetadata.getPublicAddresses());
assertEquals(convertedNodeMetadata.getPublicAddresses().size(), 1);
assertEquals(convertedNodeMetadata.getPublicAddresses().iterator().next(), "10.0.1.1");
}
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.internal;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture;
import org.jclouds.rest.BaseRestClientExpectTest;
import java.util.Properties;
/**
* Base class for writing KeyStone Expect tests with the ComputeService abstraction
*
* @author Matt Stephenson
*/
public class BaseNovaComputeServiceExpectTest extends BaseRestClientExpectTest<ComputeService>
{
protected HttpRequest keystoneAuthWithUsernameAndPassword;
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
protected String authToken;
protected HttpResponse responseWithKeystoneAccess;
public BaseNovaComputeServiceExpectTest()
{
provider = "openstack-nova";
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
credential);
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
credential);
authToken = KeystoneFixture.INSTANCE.getAuthToken();
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
// now, createContext arg will need tenant prefix
identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity;
}
@Override
public ComputeService createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props)
{
return new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, identity, credential,
ImmutableSet.<Module>of(new ExpectModule(fn), new NullLoggingModule(), module), props).getComputeService();
}
}

View File

@ -0,0 +1,79 @@
{
"servers": [
{
"id": "52415800-8b69-11e0-9b19-734f000004d2",
"tenant_id": "1234",
"user_id": "5678",
"name": "sample-server",
"updated": "2010-10-10T12:00:00Z",
"created": "2010-08-10T12:00:00Z",
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
"accessIPv4" : "67.23.10.132",
"accessIPv6" : "::babe:67.23.10.132",
"status": "BUILD",
"progress": 60,
"image" : {
"id": "52415800-8b69-11e0-9b19-734f6f006e54",
"links": [
{
"rel": "self",
"href": "http://servers.api.openstack.org/v1.1/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
},
{
"rel": "bookmark",
"href": "http://servers.api.openstack.org/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
}
]
},
"flavor" : {
"id": "52415800-8b69-11e0-9b19-734f216543fd",
"links": [
{
"rel": "self",
"href": "http://servers.api.openstack.org/v1.1/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
},
{
"rel": "bookmark",
"href": "http://servers.api.openstack.org/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
}
]
},
"addresses": {
"public" : [
{
"version": 4,
"addr": "67.23.10.132"
},
{
"version": 6,
"addr": "::babe:67.23.10.132"
},
{
"version": 4,
"addr": "67.23.10.131"
},
{
"version": 6,
"addr": "::babe:4317:0A83"
}
],
"private" : [
{
"version": 4,
"addr": "10.176.42.16"
},
{
"version": 6,
"addr": "::babe:10.176.42.16"
}
]
},
"metadata": {
"Server Label": "Web Head 1",
"Image Version": "2.1"
},
"links": [
]
}
]
}