Add IpType config option for GoGrid

This commit is contained in:
Andrew Donald Kennedy 2011-05-01 17:40:55 +01:00
parent 6bf4ea34cb
commit 7a9f10f442
3 changed files with 275 additions and 18 deletions

View File

@ -26,21 +26,19 @@ import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy;
import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy;
import org.jclouds.gogrid.compute.strategy.FindPublicIpThenCreateNodeInGroup; import org.jclouds.gogrid.compute.strategy.FindIpThenCreateNodeInGroup;
import org.jclouds.gogrid.compute.strategy.GoGridDestroyNodeStrategy; import org.jclouds.gogrid.compute.strategy.GoGridDestroyNodeStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridGetNodeMetadataStrategy; import org.jclouds.gogrid.compute.strategy.GoGridGetNodeMetadataStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridLifeCycleStrategy; import org.jclouds.gogrid.compute.strategy.GoGridLifeCycleStrategy;
import org.jclouds.gogrid.compute.strategy.GoGridListNodesStrategy; import org.jclouds.gogrid.compute.strategy.GoGridListNodesStrategy;
/** /**
*
* @author Adrian Cole * @author Adrian Cole
*
*/ */
public class GoGridBindComputeStrategiesByClass extends BindComputeStrategiesByClass { public class GoGridBindComputeStrategiesByClass extends BindComputeStrategiesByClass {
@Override @Override
protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() { protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() {
return FindPublicIpThenCreateNodeInGroup.class; return FindIpThenCreateNodeInGroup.class;
} }
@Override @Override

View File

@ -0,0 +1,253 @@
/**
*
* Copyright (C) 2011 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.compute.options;
import java.util.Arrays;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.gogrid.domain.IpType;
import org.jclouds.io.Payload;
/**
* Contains options supported in the {@code ComputeService#runNode} operation on the "gogrid"
* provider.
*
* <h2>Usage</h2>
* The recommended way to instantiate a {@link GoGridTemplateOptions} object is to statically
* import {@code GoGridTemplateOptions.*} and invoke a static creation method followed by an
* instance mutator (if needed):
* <p>
* <code>
* import static org.jclouds.compute.options.GoGridTemplateOptions.Builder.*;
* ComputeService client = // get connection
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
* Set<? extends NodeMetadata> set = client.runNodesWithTag(tag, 2, templateBuilder.build());
* <code>
*
* @author Adrian Cole
* @author Andrew Kennedy
*/
public class GoGridTemplateOptions extends TemplateOptions implements Cloneable {
@Override
public GoGridTemplateOptions clone() {
GoGridTemplateOptions options = new GoGridTemplateOptions();
copyTo(options);
return options;
}
@Override
public void copyTo(TemplateOptions to) {
super.copyTo(to);
if (to instanceof GoGridTemplateOptions) {
GoGridTemplateOptions eTo = GoGridTemplateOptions.class.cast(to);
if (getIpType() != null)
eTo.ipType(getIpType());
}
}
private IpType ipType = null;
public static final GoGridTemplateOptions NONE = new GoGridTemplateOptions();
/**
* Specifies the ipType used for network interfaces on the VMs
*/
public GoGridTemplateOptions ipType(IpType ipType) {
this.ipType = ipType;
return this;
}
public static class Builder {
/**
* @see GoGridTemplateOptions#ipAddressAllocationMode
*/
public static GoGridTemplateOptions ipType(IpType ipType) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.ipType(ipType));
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#inboundPorts
*/
public static GoGridTemplateOptions inboundPorts(int... ports) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.inboundPorts(ports));
}
/**
* @see TemplateOptions#port
*/
public static GoGridTemplateOptions blockOnPort(int port, int seconds) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.blockOnPort(port, seconds));
}
/**
* @see TemplateOptions#runScript
*/
public static GoGridTemplateOptions runScript(Payload script) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.runScript(script));
}
/**
* @see TemplateOptions#installPrivateKey
*/
public static GoGridTemplateOptions installPrivateKey(Payload rsaKey) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.installPrivateKey(rsaKey));
}
/**
* @see TemplateOptions#authorizePublicKey
*/
public static GoGridTemplateOptions authorizePublicKey(Payload rsaKey) {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
}
/**
* @see TemplateOptions#withDetails
*/
public static GoGridTemplateOptions withDetails() {
GoGridTemplateOptions options = new GoGridTemplateOptions();
return GoGridTemplateOptions.class.cast(options.withMetadata());
}
}
/**
* @return ipType on the vms
*/
public IpType getIpType() {
return ipType;
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#blockOnPort
*/
@Override
public GoGridTemplateOptions blockOnPort(int port, int seconds) {
return GoGridTemplateOptions.class.cast(super.blockOnPort(port, seconds));
}
/**
*
* special thing is that we do assume if you are passing groups that you have everything you need
* already defined. for example, our option inboundPorts normally creates ingress rules
* accordingly but if we notice you've specified securityGroups, we do not mess with rules at all
*
* @see TemplateOptions#inboundPorts
*/
@Override
public GoGridTemplateOptions inboundPorts(int... ports) {
return GoGridTemplateOptions.class.cast(super.inboundPorts(ports));
}
/**
* @see TemplateOptions#authorizePublicKey(String)
*/
@Override
public GoGridTemplateOptions authorizePublicKey(String publicKey) {
return GoGridTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
}
/**
* @see TemplateOptions#authorizePublicKey(Payload)
*/
@Override
@Deprecated
public GoGridTemplateOptions authorizePublicKey(Payload publicKey) {
return GoGridTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
}
/**
* @see TemplateOptions#installPrivateKey(String)
*/
@Override
public GoGridTemplateOptions installPrivateKey(String privateKey) {
return GoGridTemplateOptions.class.cast(super.installPrivateKey(privateKey));
}
/**
* @see TemplateOptions#installPrivateKey(Payload)
*/
@Override
@Deprecated
public GoGridTemplateOptions installPrivateKey(Payload privateKey) {
return GoGridTemplateOptions.class.cast(super.installPrivateKey(privateKey));
}
/**
* @see TemplateOptions#runScript(Payload)
*/
@Override
public GoGridTemplateOptions runScript(Payload script) {
return GoGridTemplateOptions.class.cast(super.runScript(script));
}
/**
* @see TemplateOptions#runScript(byte[])
*/
@Override
@Deprecated
public GoGridTemplateOptions runScript(byte[] script) {
return GoGridTemplateOptions.class.cast(super.runScript(script));
}
/**
* @see TemplateOptions#withMetadata
*/
@Override
public GoGridTemplateOptions withMetadata() {
return GoGridTemplateOptions.class.cast(super.withMetadata());
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((ipType == null) ? 0 : ipType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
GoGridTemplateOptions other = (GoGridTemplateOptions) obj;
if (ipType != other.ipType)
return false;
return true;
}
@Override
public String toString() {
return "[" + (ipType != null ? "ipType=" + ipType : "") + ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
+ (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null)
+ ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + "]";
}
}

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.gogrid.compute.strategy; package org.jclouds.gogrid.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.*;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Set; import java.util.Set;
@ -26,12 +26,13 @@ import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.GoGridClient;
import org.jclouds.gogrid.compute.options.GoGridTemplateOptions;
import org.jclouds.gogrid.domain.Ip; import org.jclouds.gogrid.domain.Ip;
import org.jclouds.gogrid.domain.IpType; import org.jclouds.gogrid.domain.IpType;
import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.PowerCommand;
@ -48,7 +49,7 @@ import com.google.common.collect.Iterables;
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
@Singleton @Singleton
public class FindPublicIpThenCreateNodeInGroup implements CreateNodeWithGroupEncodedIntoName { public class FindIpThenCreateNodeInGroup implements CreateNodeWithGroupEncodedIntoName {
private final GoGridClient client; private final GoGridClient client;
private final Function<Hardware, String> sizeToRam; private final Function<Hardware, String> sizeToRam;
private final Function<Server, NodeMetadata> serverToNodeMetadata; private final Function<Server, NodeMetadata> serverToNodeMetadata;
@ -56,14 +57,15 @@ public class FindPublicIpThenCreateNodeInGroup implements CreateNodeWithGroupEnc
private RetryablePredicate<Server> serverLatestJobCompletedShort; private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject @Inject
protected FindPublicIpThenCreateNodeInGroup(GoGridClient client, protected FindIpThenCreateNodeInGroup(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Hardware, String> sizeToRam, Function<Server, NodeMetadata> serverToNodeMetadata, Function<Hardware, String> sizeToRam,
Timeouts timeouts) { Timeouts timeouts) {
this.client = client; this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata; this.serverToNodeMetadata = serverToNodeMetadata;
this.sizeToRam = sizeToRam; this.sizeToRam = sizeToRam;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted( this.serverLatestJobCompleted = new RetryablePredicate<Server>(
client.getJobServices()), timeouts.nodeRunning * 9l / 10l); new ServerLatestJobCompleted(client.getJobServices()),
timeouts.nodeRunning * 9l / 10l);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>( this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), new ServerLatestJobCompleted(client.getJobServices()),
timeouts.nodeRunning * 1l / 10l); timeouts.nodeRunning * 1l / 10l);
@ -74,15 +76,19 @@ public class FindPublicIpThenCreateNodeInGroup implements CreateNodeWithGroupEnc
Server addedServer = null; Server addedServer = null;
boolean notStarted = true; boolean notStarted = true;
int numOfRetries = 20; int numOfRetries = 20;
GetIpListOptions unassignedIps = new GetIpListOptions()
.onlyUnassigned()
.inDatacenter(template.getLocation().getId());
if (template.getOptions() instanceof GoGridTemplateOptions) {
IpType ipType = GoGridTemplateOptions.class.cast(template.getOptions()).getIpType();
unassignedIps = unassignedIps.onlyWithType(ipType);
}
// lock-free consumption of a shared resource: IP address pool // lock-free consumption of a shared resource: IP address pool
while (notStarted) { // TODO: replace with Predicate-based thread while (notStarted) { // TODO: replace with Predicate-based thread
// collision avoidance for // collision avoidance for simplicity
// simplicity Set<Ip> availableIps = client.getIpServices().getIpList(unassignedIps);
Set<Ip> availableIps = client.getIpServices().getIpList( if (availableIps.isEmpty())
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC).inDatacenter( throw new RuntimeException("No IPs available on this identity.");
template.getLocation().getId()));
if (availableIps.size() == 0)
throw new RuntimeException("No public IPs available on this identity.");
int ipIndex = new SecureRandom().nextInt(availableIps.size()); int ipIndex = new SecureRandom().nextInt(availableIps.size());
Ip availableIp = Iterables.get(availableIps, ipIndex); Ip availableIp = Iterables.get(availableIps, ipIndex);
try { try {