added resolve images functionality (currently supported are ec2 and gogrid). current implementations are only resolving the credentials/authentication

This commit is contained in:
Alex Yarmula 2010-04-07 16:10:37 -07:00
parent 7d4d1b3b4a
commit 1bdf5eda18
11 changed files with 614 additions and 341 deletions

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.Properties;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule;
import org.jclouds.aws.ec2.compute.config.internal.EC2AuthenticationModule;
import org.jclouds.aws.ec2.config.EC2RestClientModule;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
@ -68,4 +69,8 @@ public class EC2ContextBuilder extends
modules.add(new EC2RestClientModule());
}
@Override
protected void addImageResolutionModule() {
modules.add(new EC2AuthenticationModule());
}
}

View File

@ -0,0 +1,37 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute.config.internal;
import com.google.inject.AbstractModule;
import org.jclouds.aws.ec2.compute.strategy.EC2AuthenticateImagesStrategy;
import org.jclouds.compute.config.ResolvesImages;
import org.jclouds.compute.strategy.AuthenticateImagesStrategy;
/**
* @author Oleksiy Yarmula
*/
@ResolvesImages
public class EC2AuthenticationModule extends AbstractModule {
@Override
protected void configure() {
bind(AuthenticateImagesStrategy.class).to(EC2AuthenticateImagesStrategy.class);
}
}

View File

@ -18,6 +18,7 @@ import org.jclouds.aws.ec2.services.AMIClient;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.strategy.AuthenticateImagesStrategy;
import org.jclouds.domain.Credentials;
import com.google.common.base.Function;
@ -34,12 +35,15 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
private final AMIClient amiClient;
private final Map<RegionTag, KeyPairCredentials> credentialsMap;
private final AuthenticateImagesStrategy authenticator;
@Inject
public RunningInstanceToNodeMetadata(AMIClient amiClient,
Map<RegionTag, KeyPairCredentials> credentialsMap) {
Map<RegionTag, KeyPairCredentials> credentialsMap,
AuthenticateImagesStrategy authenticator) {
this.amiClient = amiClient;
this.credentialsMap = credentialsMap;
this.authenticator = authenticator;
}
@Override
@ -58,10 +62,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
Image image = Iterables.getOnlyElement(amiClient.describeImagesInRegion(from.getRegion(),
DescribeImagesOptions.Builder.imageIds(from.getImageId())));
// canonical/alestic images use the ubuntu user to login
// TODO: add this as a property of image
if (credentials != null && image.getImageOwnerId().matches("063491364108|099720109477"))
credentials = new Credentials("ubuntu", credentials.key);
if(credentials == null) credentials = authenticator.execute(image);
String locationId = from.getAvailabilityZone().toString();
Map<String, String> extra = ImmutableMap.<String, String> of();

View File

@ -0,0 +1,48 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute.strategy;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.compute.strategy.AuthenticateImagesStrategy;
import org.jclouds.domain.Credentials;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Oleksiy Yarmula
*/
public class EC2AuthenticateImagesStrategy implements AuthenticateImagesStrategy {
@Override
public Credentials execute(Object resourceToAuthenticate) {
checkNotNull(resourceToAuthenticate);
checkArgument(resourceToAuthenticate instanceof Image, "Resource must be an image (for EC2)");
Image image = (Image) resourceToAuthenticate;
Credentials credentials = null;
// canonical/alestic images use the ubuntu user to login
if (image.getImageOwnerId().matches("063491364108|099720109477"))
credentials = new Credentials("ubuntu", "");
else credentials = new Credentials("root", "");
return credentials;
}
}

View File

@ -21,14 +21,13 @@ package org.jclouds.aws.ec2.compute;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.*;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
import java.util.Map;
/**
*
@ -62,6 +61,14 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
Architecture.X86_32).imageId("ami-bb709dd2").build();
}
@Test
public void testCredentialsMapping() {
// Template simpleTemplate = client.templateBuilder().smallest().build();
// client.runNodesWithTag("ec2", 1, simpleTemplate);
Map<String, ? extends NodeMetadata> map = client.getNodesWithTag("ec2");
int a = 5;
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();

View File

@ -18,8 +18,13 @@
*/
package org.jclouds.compute;
import java.util.List;
import java.util.Properties;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import org.jclouds.compute.config.ResolvesImages;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.rest.RestContextBuilder;
@ -43,12 +48,18 @@ public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuil
}
/**
@Override
public Injector buildInjector() {
addImageResolutionModuleIfNotPresent();
return super.buildInjector();
}
/**
* {@inheritDoc}
*/
@Override
public ComputeServiceContextBuilder<A, S> withModules(Module... modules) {
return (ComputeServiceContextBuilder<A, S>) super.withModules(modules);
return (ComputeServiceContextBuilder<A, S>) super.withModules(modules);
}
public ComputeServiceContext buildComputeServiceContext() {
@ -57,4 +68,21 @@ public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuil
Key.get(Types.newParameterizedType(ComputeServiceContextImpl.class, asyncClientType
.getType(), syncClientType.getType())));
}
protected void addImageResolutionModuleIfNotPresent() {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ResolvesImages.class);
}
})) {
addImageResolutionModule();
}
}
@SuppressWarnings({"UnusedDeclaration"})
protected void addImageResolutionModule() {
// do nothing;
// this is to be overridden when needed
}
}

View File

@ -0,0 +1,43 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.config;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Marks that the module can augment an images of
* a given cloud.
*
* Such a module binds a strategy to determine such things,
* as:
* <ul>
* <li>default username</li>
* <li>default password, specific to a cloud and image.</li>
* </ul>
*
* @author Oleksiy Yarmula
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface ResolvesImages {
}

View File

@ -0,0 +1,41 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.strategy;
import org.jclouds.domain.Credentials;
/**
* @author Oleksiy Yarmula
*/
public interface AuthenticateImagesStrategy {
/**
* Processes the resource to determine credentials.
*
* @param resourceToAuthenticate
* this can be any resource, such as an image,
* running server instance or other. It's the
* responsibility of an implementation to apply
* the cloud-specific logic.
* @return credentials object. Note: the key
* may not be set, but the account must be set
*/
Credentials execute(Object resourceToAuthenticate);
}

View File

@ -34,7 +34,7 @@ import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.gogrid.config.GoGridComputeServiceContextModule;
import org.jclouds.gogrid.config.GoGridRestClientModule;
import org.jclouds.gogrid.reference.GoGridConstants;
import org.jclouds.gogrid.config.internal.GoGridAuthenticationModule;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@ -60,6 +60,11 @@ public class GoGridContextBuilder extends ComputeServiceContextBuilder<GoGridAsy
modules.add(new GoGridComputeServiceContextModule());
}
@Override
protected void addImageResolutionModule() {
modules.add(new GoGridAuthenticationModule());
}
@Override
public ComputeServiceContext buildComputeServiceContext() {
return this
@ -69,5 +74,4 @@ public class GoGridContextBuilder extends ComputeServiceContextBuilder<GoGridAsy
.get(new TypeLiteral<ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>>() {
}));
}
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.gogrid.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.*;
import static org.jclouds.compute.domain.OsFamily.CENTOS;
import java.net.InetAddress;
@ -36,6 +36,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import com.google.inject.AbstractModule;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
@ -54,11 +55,7 @@ import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.predicates.RunScriptRunning;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.*;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
@ -97,372 +94,373 @@ import com.google.inject.TypeLiteral;
*/
public class GoGridComputeServiceContextModule extends GoGridContextModule {
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
}).to(ServerToNodeMetadata.class);
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
}
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
}).to(ServerToNodeMetadata.class);
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
}
@Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations,
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(CENTOS)
.imageNameMatches(".*w/ None.*");
}
@Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations,
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(CENTOS)
.imageNameMatches(".*w/ None.*");
}
@Provides
@Named("NAMING_CONVENTION")
@Singleton
String provideNamingConvention() {
return "%s-%d";
}
@Provides
@Named("NAMING_CONVENTION")
@Singleton
String provideNamingConvention() {
return "%s-%d";
}
@Singleton
public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
private final GoGridClient client;
private final Function<Size, String> sizeToRam;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Singleton
public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
private final GoGridClient client;
private final Function<Size, String> sizeToRam;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
this.sizeToRam = sizeToRam;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Inject
protected GoGridAddNodeWithTagStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
this.sizeToRam = sizeToRam;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Override
public NodeMetadata execute(String tag, String name, Template template) {
Server addedServer = null;
boolean notStarted = true;
int numOfRetries = 20;
// lock-free consumption of a shared resource: IP address pool
while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for
// simplicity
Set<Ip> availableIps = client.getIpServices().getIpList(
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
if (availableIps.size() == 0)
throw new RuntimeException("No public IPs available on this account.");
int ipIndex = new SecureRandom().nextInt(availableIps.size());
Ip availableIp = Iterables.get(availableIps, ipIndex);
try {
addedServer = client.getServerServices().addServer(name,
checkNotNull(template.getImage().getId()),
sizeToRam.apply(template.getSize()), availableIp.getIp());
notStarted = false;
} catch (Exception e) {
if (--numOfRetries == 0)
Throwables.propagate(e);
notStarted = true;
@Override
public NodeMetadata execute(String tag, String name, Template template) {
Server addedServer = null;
boolean notStarted = true;
int numOfRetries = 20;
// lock-free consumption of a shared resource: IP address pool
while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for
// simplicity
Set<Ip> availableIps = client.getIpServices().getIpList(
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
if (availableIps.size() == 0)
throw new RuntimeException("No public IPs available on this account.");
int ipIndex = new SecureRandom().nextInt(availableIps.size());
Ip availableIp = Iterables.get(availableIps, ipIndex);
try {
addedServer = client.getServerServices().addServer(name,
checkNotNull(template.getImage().getId()),
sizeToRam.apply(template.getSize()), availableIp.getIp());
notStarted = false;
} catch (Exception e) {
if (--numOfRetries == 0)
Throwables.propagate(e);
notStarted = true;
}
}
}
serverLatestJobCompleted.apply(addedServer);
serverLatestJobCompleted.apply(addedServer);
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
serverLatestJobCompletedShort.apply(addedServer);
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
serverLatestJobCompletedShort.apply(addedServer);
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
addedServer.getName()));
return serverToNodeMetadata.apply(addedServer);
}
}
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
addedServer.getName()));
return serverToNodeMetadata.apply(addedServer);
}
}
@Singleton
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Singleton
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject
protected GoGridRebootNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Inject
protected GoGridRebootNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START);
return serverLatestJobCompletedShort.apply(server);
}
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START);
return serverLatestJobCompletedShort.apply(server);
}
}
@Singleton
public static class GoGridListNodesStrategy implements ListNodesStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Singleton
public static class GoGridListNodesStrategy implements ListNodesStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridListNodesStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Inject
protected GoGridListNodesStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public Iterable<? extends ComputeMetadata> execute() {
return Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata);
}
@Override
public Iterable<? extends ComputeMetadata> execute() {
return Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata);
}
}
}
@Singleton
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Singleton
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Inject
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
return server == null ? null : serverToNodeMetadata.apply(server);
}
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
return server == null ? null : serverToNodeMetadata.apply(server);
}
}
@Singleton
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
@Singleton
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
@Inject
protected GoGridDestroyNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
}
@Inject
protected GoGridDestroyNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server);
}
}
}
@Singleton
@Provides
Map<String, NodeState> provideServerToNodeState() {
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
NodeState.PENDING).build();
}
@Singleton
@Provides
Map<String, NodeState> provideServerToNodeState() {
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
NodeState.PENDING).build();
}
@Singleton
@Provides
Function<String, InetAddress> provideStringIpToInetAddress() {
return new Function<String, InetAddress>() {
@Override
public InetAddress apply(String from) {
try {
return InetAddress.getByName(from);
} catch (UnknownHostException e) {
// TODO: log the failure.
return null;
@Singleton
@Provides
Function<String, InetAddress> provideStringIpToInetAddress() {
return new Function<String, InetAddress>() {
@Override
public InetAddress apply(String from) {
try {
return InetAddress.getByName(from);
} catch (UnknownHostException e) {
// TODO: log the failure.
return null;
}
}
}
};
}
};
}
/**
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March 2010)
*
* @return matched size
*/
@Singleton
@Provides
Function<Size, String> provideSizeToRam() {
return new Function<Size, String>() {
@Override
public String apply(Size size) {
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
return "8GB";
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
return "4GB";
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
return "2GB";
if (size.getRam() >= 1024 || size.getDisk() >= 55)
return "1GB";
return "512MB"; /* smallest */
}
};
}
/**
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March 2010)
*
* @return matched size
*/
@Singleton
@Provides
Function<Size, String> provideSizeToRam() {
return new Function<Size, String>() {
@Override
public String apply(Size size) {
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
return "8GB";
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
return "4GB";
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
return "2GB";
if (size.getRam() >= 1024 || size.getDisk() >= 55)
return "1GB";
return "512MB"; /* smallest */
}
};
}
@Singleton
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
private final Map<String, NodeState> serverStateToNodeState;
private final Function<String, InetAddress> stringIpToInetAddress;
private final GoGridClient client;
@Singleton
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
private final Map<String, NodeState> serverStateToNodeState;
private final Function<String, InetAddress> stringIpToInetAddress;
private final GoGridClient client;
private final AuthenticateImagesStrategy authenticator;
@SuppressWarnings("unused")
@Inject
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
Function<String, InetAddress> stringIpToInetAddress, GoGridClient client) {
this.serverStateToNodeState = serverStateToNodeState;
this.stringIpToInetAddress = stringIpToInetAddress;
this.client = client;
}
@SuppressWarnings("unused")
@Inject
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
Function<String, InetAddress> stringIpToInetAddress, GoGridClient client,
AuthenticateImagesStrategy authenticator) {
this.serverStateToNodeState = serverStateToNodeState;
this.stringIpToInetAddress = stringIpToInetAddress;
this.client = client;
this.authenticator = authenticator;
}
@Override
public NodeMetadata apply(Server from) {
String locationId = "Unavailable";
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
Credentials creds = client.getServerServices().getServerCredentialsList().get(
from.getName());
Set<InetAddress> ipSet = ImmutableSet
.of(stringIpToInetAddress.apply(from.getIp().getIp()));
NodeState state = serverStateToNodeState.get(from.getState().getName());
@Override
public NodeMetadata apply(Server from) {
String locationId = "Unavailable";
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
Set<InetAddress> ipSet = ImmutableSet
.of(stringIpToInetAddress.apply(from.getIp().getIp()));
NodeState state = serverStateToNodeState.get(from.getState().getName());
Credentials creds = authenticator.execute(from);
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
ImmutableMap.<String, String> of(), tag, state, ipSet, ImmutableList
.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
}
}
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
ImmutableMap.<String, String> of(), tag, state, ipSet, ImmutableList
.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
}
}
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<GoGridAsyncClient, GoGridClient> context) {
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(computeService, context);
}
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<GoGridAsyncClient, GoGridClient> context) {
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(computeService, context);
}
@Provides
@Singleton
@Named("NOT_RUNNING")
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
TimeUnit.SECONDS);
}
@Provides
@Singleton
@Named("NOT_RUNNING")
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
TimeUnit.SECONDS);
}
@Provides
@Singleton
Location getDefaultLocation(Map<String, ? extends Location> locations) {
return locations.get("SANFRANCISCO");
}
@Provides
@Singleton
Location getDefaultLocation(Map<String, ? extends Location> locations) {
return locations.get("SANFRANCISCO");
}
@Provides
@Singleton
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer) {
final Set<Location> locations = Sets.newHashSet();
holder.logger.debug(">> providing locations");
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
true));
holder.logger.debug("<< locations(%d)", locations.size());
return Maps.uniqueIndex(locations, new Function<Location, String>() {
@Provides
@Singleton
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer) {
final Set<Location> locations = Sets.newHashSet();
holder.logger.debug(">> providing locations");
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
true));
holder.logger.debug("<< locations(%d)", locations.size());
return Maps.uniqueIndex(locations, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
}
@Override
public String apply(Location from) {
return from.getId();
}
});
}
@Provides
@Singleton
protected Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getId();
}
};
}
@Provides
@Singleton
protected Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getId();
}
};
}
@Provides
@Singleton
protected Map<String, ? extends Size> provideSizes(GoGridClient sync,
Map<String, ? extends Image> images, LogHolder holder,
Function<ComputeMetadata, String> indexer) throws InterruptedException,
@Provides
@Singleton
protected Map<String, ? extends Size> provideSizes(GoGridClient sync,
Map<String, ? extends Image> images, LogHolder holder,
Function<ComputeMetadata, String> indexer) throws InterruptedException,
TimeoutException, ExecutionException {
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
sizes.add(new SizeImpl("1", "1", null, null, ImmutableMap.<String, String> of(), 1, 512, 28,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("2", "2", null, null, ImmutableMap.<String, String> of(), 1, 1024, 57,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("3", "3", null, null, ImmutableMap.<String, String> of(), 1, 2048,
113, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("4", "4", null, null, ImmutableMap.<String, String> of(), 3, 4096,
233, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("5", "5", null, null, ImmutableMap.<String, String> of(), 6, 8192,
462, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
holder.logger.debug("<< sizes(%d)", sizes.size());
return Maps.uniqueIndex(sizes, indexer);
}
sizes.add(new SizeImpl("1", "1", null, null, ImmutableMap.<String, String> of(), 1, 512, 28,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("2", "2", null, null, ImmutableMap.<String, String> of(), 1, 1024, 57,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("3", "3", null, null, ImmutableMap.<String, String> of(), 1, 2048,
113, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("4", "4", null, null, ImmutableMap.<String, String> of(), 3, 4096,
233, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("5", "5", null, null, ImmutableMap.<String, String> of(), 6, 8192,
462, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
holder.logger.debug("<< sizes(%d)", sizes.size());
return Maps.uniqueIndex(sizes, indexer);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
@Provides
@Singleton
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer, Location location)
@Provides
@Singleton
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer, Location location)
throws InterruptedException, ExecutionException, TimeoutException {
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
Set<ServerImage> allImages = sync.getImageServices().getImageList();
for (ServerImage from : allImages) {
OsFamily os = null;
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
String osDescription;
String version = "";
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
Set<ServerImage> allImages = sync.getImageServices().getImageList();
for (ServerImage from : allImages) {
OsFamily os = null;
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
String osDescription;
String version = "";
osDescription = from.getOs().getName();
osDescription = from.getOs().getName();
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
.getName(), GOGRID_OS_NAME_PATTERN, 1);
try {
os = OsFamily.fromValue(matchedOs.toLowerCase());
} catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matchedOs);
}
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
.getName(), GOGRID_OS_NAME_PATTERN, 1);
try {
os = OsFamily.fromValue(matchedOs.toLowerCase());
} catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matchedOs);
}
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), location.getId(),
null, ImmutableMap.<String, String> of(), from.getDescription(), version, os,
osDescription, arch));
}
holder.logger.debug("<< images(%d)", images.size());
return Maps.uniqueIndex(images, indexer);
}
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), location.getId(),
null, ImmutableMap.<String, String> of(), from.getDescription(), version, os,
osDescription, arch));
}
holder.logger.debug("<< images(%d)", images.size());
return Maps.uniqueIndex(images, indexer);
}
}

View File

@ -0,0 +1,61 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.gogrid.config.internal;
import com.google.inject.AbstractModule;
import org.jclouds.compute.config.ResolvesImages;
import org.jclouds.compute.strategy.AuthenticateImagesStrategy;
import org.jclouds.domain.Credentials;
import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.domain.Server;
import javax.inject.Inject;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Oleksiy Yarmula
*/
@ResolvesImages
public class GoGridAuthenticationModule extends AbstractModule {
@Override
protected void configure() {
bind(AuthenticateImagesStrategy.class).to(GoGridAuthenticateImagesStrategy.class);
}
public static class GoGridAuthenticateImagesStrategy implements AuthenticateImagesStrategy {
private final GoGridClient client;
@Inject
protected GoGridAuthenticateImagesStrategy(GoGridClient client) {
this.client = client;
}
@Override
public Credentials execute(Object resourceToAuthenticate) {
checkNotNull(resourceToAuthenticate);
checkArgument(resourceToAuthenticate instanceof Server, "Resource must be a server (for GoGrid)");
Server server = (Server) resourceToAuthenticate;
return client.getServerServices().getServerCredentialsList().get(
server.getName());
}
}
}