diff --git a/compute/src/main/resources/compute.properties b/compute/src/main/resources/compute.properties index 4a42445731..924ead79dd 100644 --- a/compute/src/main/resources/compute.properties +++ b/compute/src/main/resources/compute.properties @@ -30,5 +30,7 @@ cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersConte cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder bluelock.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudContextBuilder bluelock.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudPropertiesBuilder +gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridContextBuilder +gogrid.contextbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder # example of where to change your endpoint # bluelock.endpoint=https://express3.bluelock.com/api diff --git a/gogrid/pom.xml b/gogrid/pom.xml index d9ce63083c..de18a8e761 100644 --- a/gogrid/pom.xml +++ b/gogrid/pom.xml @@ -72,5 +72,10 @@ ${project.version} test + + org.jclouds + jclouds-jsch + 1.0-SNAPSHOT + diff --git a/gogrid/src/main/java/org/jclouds/gogrid/GoGridContextBuilder.java b/gogrid/src/main/java/org/jclouds/gogrid/GoGridContextBuilder.java index 5d32c416ee..61818cf45b 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/GoGridContextBuilder.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/GoGridContextBuilder.java @@ -28,8 +28,11 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.List; import java.util.Properties; -import org.jclouds.rest.RestContextBuilder; -import org.jclouds.gogrid.config.GoGridContextModule; +import com.google.inject.Key; +import org.jclouds.compute.ComputeServiceContext; +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; @@ -37,26 +40,36 @@ import com.google.inject.Module; import com.google.inject.TypeLiteral; /** - * + * * @author Adrian Cole */ -public class GoGridContextBuilder extends RestContextBuilder { +public class GoGridContextBuilder extends ComputeServiceContextBuilder { - public GoGridContextBuilder(Properties props) { - super(new TypeLiteral() { - }, new TypeLiteral() { - }, props); - checkNotNull(properties.getProperty(GoGridConstants.PROPERTY_GOGRID_USER)); - checkNotNull(properties.getProperty(GoGridConstants.PROPERTY_GOGRID_PASSWORD)); - } + public GoGridContextBuilder(Properties props) { + super(new TypeLiteral() { + }, new TypeLiteral() { + }, props); + checkNotNull(properties.getProperty(GoGridConstants.PROPERTY_GOGRID_USER)); + checkNotNull(properties.getProperty(GoGridConstants.PROPERTY_GOGRID_PASSWORD)); + } - protected void addClientModule(List modules) { - modules.add(new GoGridRestClientModule()); - } + protected void addClientModule(List modules) { + modules.add(new GoGridRestClientModule()); + } - @Override - protected void addContextModule(List modules) { - modules.add(new GoGridContextModule()); - } + @Override + protected void addContextModule(List modules) { + modules.add(new GoGridComputeServiceContextModule()); + } + + @Override + public ComputeServiceContext buildComputeServiceContext() { + return this + .buildInjector() + .getInstance( + Key + .get(new TypeLiteral>() { + })); + } } diff --git a/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridComputeServiceContextModule.java b/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridComputeServiceContextModule.java new file mode 100644 index 0000000000..a1628254fa --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/config/GoGridComputeServiceContextModule.java @@ -0,0 +1,278 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; +import org.jclouds.compute.domain.*; +import org.jclouds.compute.domain.internal.NodeMetadataImpl; +import org.jclouds.compute.strategy.*; +import org.jclouds.domain.Credentials; +import org.jclouds.gogrid.GoGridClient; +import org.jclouds.gogrid.domain.Ip; +import org.jclouds.gogrid.domain.PowerCommand; +import org.jclouds.gogrid.domain.Server; +import org.jclouds.gogrid.predicates.ServerLatestJobCompleted; +import org.jclouds.predicates.RetryablePredicate; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author Oleksiy Yarmula + */ +public class GoGridComputeServiceContextModule extends GoGridContextModule { + + @Override + protected void configure() { + super.configure(); + bind(new TypeLiteral>() { + }).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 + @Named("NAMING_CONVENTION") + @Singleton + String provideNamingConvention() { + return "%s-%d"; + } + + @Singleton + public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy { + private final GoGridClient client; + private final Function stringIpToInetAddress; + private final Function sizeToRam; + private final Map serverStateToNodeState; + private RetryablePredicate serverLatestJobCompleted; + + @Inject + protected GoGridAddNodeWithTagStrategy(GoGridClient client, + Function stringIpToInetAddress, + Map serverStateToNodeState, + Function sizeToRam) { + this.client = client; + this.stringIpToInetAddress = stringIpToInetAddress; + this.serverStateToNodeState = serverStateToNodeState; + this.sizeToRam = sizeToRam; + this.serverLatestJobCompleted = new RetryablePredicate( + new ServerLatestJobCompleted(client.getJobServices()), + 800, 20, TimeUnit.SECONDS); + } + + @Override + public NodeMetadata execute(String tag, String name, Template template) { + Set availableIps = client.getIpServices().getUnassignedIpList(); + Ip availableIp = Iterables.getLast(availableIps); + Server addedServer = client.getServerServices().addServer(name, checkNotNull(template.getImage().getId()), + sizeToRam.apply(template.getSize()), availableIp.getIp()); + serverLatestJobCompleted.apply(addedServer); + addedServer = Iterables.getOnlyElement( + client.getServerServices().getServersByName(addedServer.getName()) + ); + + NodeMetadata node = new NodeMetadataImpl(String.valueOf(addedServer.getId()), addedServer.getName(), + template.getLocation().getId(), null, ImmutableMap. of(), tag, + serverStateToNodeState.get(addedServer.getState().getName()), + ImmutableSet.of(stringIpToInetAddress.apply(addedServer.getIp().getIp())), + ImmutableList. of(), ImmutableMap. of(), + /*todo give proper credentials*/ new Credentials("root", "")); + return node; + } + + } + + @Singleton + public static class GoGridRebootNodeStrategy implements RebootNodeStrategy { + private final GoGridClient client; + private RetryablePredicate serverLatestJobCompleted; + + @Inject + protected GoGridRebootNodeStrategy(GoGridClient client) { + this.client = client; + this.serverLatestJobCompleted = new RetryablePredicate( + 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().power(server.getName(), PowerCommand.RESTART); + return serverLatestJobCompleted.apply(server); + } + } + + @Singleton + public static class GoGridListNodesStrategy implements ListNodesStrategy { + private final GoGridClient client; + private final Function serverToNodeMetadata; + + @Inject + protected GoGridListNodesStrategy(GoGridClient client, + Function serverToNodeMetadata) { + this.client = client; + this.serverToNodeMetadata = serverToNodeMetadata; + } + + @Override + public Iterable execute() { + return Iterables.transform(client.getServerServices().getServerList(), serverToNodeMetadata); + } + + } + + @Singleton + public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy { + private final GoGridClient client; + private final Function serverToNodeMetadata; + + @Inject + protected GoGridGetNodeMetadataStrategy(GoGridClient client, + Function 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); + } + } + + @Singleton + public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy { + private final GoGridClient client; + private RetryablePredicate serverLatestJobCompleted; + + @Inject + protected GoGridDestroyNodeStrategy(GoGridClient client) { + this.client = client; + this.serverLatestJobCompleted = new RetryablePredicate( + 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); + } + + } + + @Singleton + @Provides + Map provideServerToNodeState() { + return ImmutableMap. builder() + .put("On", NodeState.RUNNING) + .put("Starting", NodeState.SUSPENDED) + .put("Off", NodeState.TERMINATED) + .put("Saving", NodeState.PENDING) + .put("Restarting", NodeState.PENDING) + .put("Stopping", NodeState.PENDING) + .build(); + } + + @Singleton + @Provides + Function provideStringIpToInetAddress() { + return new Function() { + @Override + public InetAddress apply(String from) { + try { + return InetAddress.getByName(from); + } catch (UnknownHostException e) { + // TODO: log the failure. + return null; + } + } + }; + } + + @Singleton + @Provides + Function provideSizeToRam() { + return new Function() { + @Override + public String apply(Size size) { + int ramRequired = size.getRam(); + if(ramRequired > 8 * 1024) return "8GB"; + if(ramRequired > 4 * 1024) return "4GB"; + if(ramRequired > 2 * 1024) return "2GB"; + if(ramRequired > 1024) return "1GB"; + return "512MB"; /*smallest*/ + } + }; + } + + @Singleton + private static class ServerToNodeMetadata implements Function { + private final Map serverStateToNodeState; + private final Function stringIpToInetAddress; + + @Inject + ServerToNodeMetadata(Map serverStateToNodeState, + Function stringIpToInetAddress) { + this.serverStateToNodeState = serverStateToNodeState; + this.stringIpToInetAddress = stringIpToInetAddress; + } + + @Override + public NodeMetadata apply(Server from) { + String locationId = "Unavailable"; + String tag = from.getName(); + Credentials creds = null; //todo use password service to get the password + Set ipSet = + ImmutableSet.of(stringIpToInetAddress.apply(from.getIp().getIp())); + NodeState state = serverStateToNodeState.get(from.getState().getName()); + + return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null, + ImmutableMap. of(), tag, state, + ipSet, + ImmutableList. of(), ImmutableMap. of(), creds); + + } + } + + +}