glesys template options should support passing root password and data transfer limit
diff --git a/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java b/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
index 7d268fa..9f5e45c 100644
--- a/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
+++ b/providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java
@@ -24,6 +24,7 @@
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.util.Map;
+import java.util.UUID;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -32,7 +33,6 @@
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
-import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.Constants;
@@ -93,18 +93,16 @@
private final ExecutorService userThreads;
private final Timeouts timeouts;
private final Supplier<Set<? extends Location>> locations;
- private final Provider<String> passwordProvider;
@Inject
public GleSYSComputeServiceAdapter(GleSYSApi api, GleSYSAsyncApi aapi,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads, Timeouts timeouts,
- @Memoized Supplier<Set<? extends Location>> locations, @Named("PASSWORD") Provider<String> passwordProvider) {
+ @Memoized Supplier<Set<? extends Location>> locations) {
this.api = checkNotNull(api, "api");
this.aapi = checkNotNull(aapi, "aapi");
this.userThreads = checkNotNull(userThreads, "userThreads");
this.timeouts = checkNotNull(timeouts, "timeouts");
this.locations = checkNotNull(locations, "locations");
- this.passwordProvider = checkNotNull(passwordProvider, "passwordProvider");
}
@Override
@@ -134,11 +132,12 @@
builder.memorySizeMB(template.getHardware().getRam());
builder.diskSizeGB(Math.round(template.getHardware().getVolumes().get(0).getSize()));
builder.cpuCores((int) template.getHardware().getProcessors().get(0).getCores());
- builder.transferGB(50);// TODO: add to template options with default value
+ builder.transferGB(templateOptions.getTransferGB());
ServerSpec spec = builder.build();
- String password = passwordProvider.get(); // TODO: add to templateOptions
- // and set if present
+
+ // use random root password unless one was provided via template options
+ String password = templateOptions.hasRootPassword() ? templateOptions.getRootPassword() : getRandomPassword();
logger.debug(">> creating new Server spec(%s) name(%s) options(%s)", spec, name, createServerOptions);
ServerDetails result = api.getServerApi().createWithHostnameAndRootPassword(spec, name, password,
@@ -149,6 +148,13 @@
.password(password).build());
}
+ /**
+ * @return a generated random password string
+ */
+ private String getRandomPassword() {
+ return UUID.randomUUID().toString().replace("-","");
+ }
+
@Singleton
public static class FindLocationForServerSpec extends FindResourceInSet<ServerSpec, Location> {
diff --git a/providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java b/providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java
index e71bc1f..4e44b02 100644
--- a/providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java
+++ b/providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java
@@ -18,12 +18,6 @@
*/
package org.jclouds.glesys.compute.config;
-import java.util.UUID;
-
-import javax.inject.Named;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
@@ -42,9 +36,7 @@
import org.jclouds.glesys.domain.ServerDetails;
import com.google.common.base.Function;
-import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
-import com.google.inject.name.Names;
/**
*
@@ -70,19 +62,7 @@
bind(new TypeLiteral<Function<String, OsFamilyVersion64Bit>>() {
}).to(ParseOsFamilyVersion64BitFromImageName.class);
bind(TemplateOptions.class).to(GleSYSTemplateOptions.class);
- bind(String.class).annotatedWith(Names.named("PASSWORD")).toProvider(PasswordProvider.class).in(Scopes.SINGLETON);
- // to have the compute service adapter override default locations
install(new LocationsFromComputeServiceAdapterModule<ServerDetails, Hardware, OSTemplate, String>(){});
}
- @Named("PASSWORD")
- @Singleton
- public static class PasswordProvider implements Provider<String> {
-
- @Override
- public String get() {
- return UUID.randomUUID().toString().replace("-","");
- }
-
- }
}
diff --git a/providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java b/providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java
index 3ef5ffa..5b1c1f2 100644
--- a/providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java
+++ b/providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java
@@ -19,30 +19,32 @@
package org.jclouds.glesys.compute.options;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.glesys.features.ServerApi;
+import org.jclouds.glesys.domain.ServerSpec;
+import com.google.common.base.Objects.ToStringHelper;
import com.google.common.net.InetAddresses;
/**
* Contains options supported by the
* {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and
- * {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} operations on the
- * <em>glesys</em> provider.
+ * {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)}
+ * operations on the <em>glesys</em> provider.
*
- * <h2>Usage</h2> The recommended way to instantiate a {@link GleSYSTemplateOptions} object is to
- * statically import {@code GleSYSTemplateOptions.*} and invoke a static creation method followed by
- * an instance mutator (if needed):
+ * <h2>Usage</h2> The recommended way to instantiate a
+ * {@link GleSYSTemplateOptions} object is to statically import
+ * {@code GleSYSTemplateOptions.*} and invoke a static creation method followed
+ * by an instance mutator (if needed):
* <p>
*
* <pre>
* import static org.jclouds.compute.options.GleSYSTemplateOptions.Builder.*;
* ComputeService api = // get connection
- * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
+ * templateBuilder.options(rootPassword("caQu5rou"));
* Set<? extends NodeMetadata> set = api.createNodesInGroup(tag, 2, templateBuilder.build());
* </pre>
*
@@ -50,7 +52,20 @@
*/
public class GleSYSTemplateOptions extends TemplateOptions implements Cloneable {
+ /**
+ * The IP address to assign to the new node instance. If set to "
+ * <code>any</code>" the node will be automatically assigned a free IP
+ * address.
+ */
protected String ip = "any";
+ /**
+ * The password to set for the root user on the created server instance. If
+ * left unspecified, a random password will be assigned.
+ */
+ protected String rootPassword = null;
+
+ /** The monthly data transfer limit (in GB) for the server. */
+ protected int transferGB = 50;
@Override
public GleSYSTemplateOptions clone() {
@@ -63,39 +78,106 @@
public void copyTo(TemplateOptions to) {
super.copyTo(to);
if (to instanceof GleSYSTemplateOptions) {
- GleSYSTemplateOptions eTo = GleSYSTemplateOptions.class.cast(to);
- eTo.ip(ip);
+ GleSYSTemplateOptions copy = GleSYSTemplateOptions.class.cast(to);
+ copy.ip(ip);
+ copy.rootPassword(rootPassword);
+ copy.transferGB(transferGB);
}
}
/**
+ * Sets the IP address to assign to the new server instance. If set to "
+ * <code>any</code>" the server will be automatically assigned a free IP
+ * address.
*
* @see ServerApi#createWithHostnameAndRootPassword
* @see InetAddresses#isInetAddress
*/
- public TemplateOptions ip(String ip) {
- if (ip != null)
- checkArgument("any".equals(ip) || InetAddresses.isInetAddress(ip), "ip %s is not valid", ip);
+ public GleSYSTemplateOptions ip(String ip) {
+ checkNotNull(ip);
+ checkArgument("any".equals(ip) || InetAddresses.isInetAddress(ip), "ip %s is not valid", ip);
this.ip = ip;
return this;
}
+ /**
+ * @return the IP address to assign to the new server instance.
+ */
public String getIp() {
return ip;
}
- public static final GleSYSTemplateOptions NONE = new GleSYSTemplateOptions();
+ /**
+ * Sets the password for the root user on the created server instance. If
+ * left unspecified, a random password will be assigned.
+ *
+ * @see ServerApi#createWithHostnameAndRootPassword
+ */
+ public GleSYSTemplateOptions rootPassword(String rootPassword) {
+ checkNotNull(rootPassword, "root password cannot be null");
+ this.rootPassword = rootPassword;
+ return this;
+ }
+
+ /**
+ * @return the password set for the root user or <code>null</code> if none is
+ * set (and a random password will be assigned).
+ */
+ public String getRootPassword() {
+ return rootPassword;
+ }
+
+ /**
+ * @return <code>true</code> if a root password has been specified.
+ */
+ public boolean hasRootPassword() {
+ return rootPassword != null;
+ }
+
+ /**
+ * Sets the monthly data transfer limit (in GB) for the server.
+ *
+ * @see ServerSpec#getTransferGB()
+ */
+ public GleSYSTemplateOptions transferGB(int transferGB) {
+ checkArgument(transferGB >= 0, "transferGB value must be >= 0", transferGB);
+ this.transferGB = transferGB;
+ return this;
+ }
+
+ /**
+ * @return the monthly data transfer limit (in GB) for the server.
+ */
+ public int getTransferGB() {
+ return transferGB;
+ }
public static class Builder {
/**
- * @see #ip
+ * @see GleSYSTemplateOptions#ip
*/
public static GleSYSTemplateOptions ip(String ip) {
GleSYSTemplateOptions options = new GleSYSTemplateOptions();
return GleSYSTemplateOptions.class.cast(options.ip(ip));
}
+ /**
+ * @see GleSYSTemplateOptions#rootPassword
+ */
+ public static GleSYSTemplateOptions rootPassword(String rootPassword) {
+ GleSYSTemplateOptions options = new GleSYSTemplateOptions();
+ return GleSYSTemplateOptions.class.cast(options.rootPassword(rootPassword));
+ }
+
+ /**
+ * @see GleSYSTemplateOptions#transferGB
+ */
+ public static GleSYSTemplateOptions transferGB(int transferGB) {
+ GleSYSTemplateOptions options = new GleSYSTemplateOptions();
+ return GleSYSTemplateOptions.class.cast(options.transferGB(transferGB));
+ }
+
// methods that only facilitate returning the correct object type
/**
@@ -113,7 +195,7 @@
GleSYSTemplateOptions options = new GleSYSTemplateOptions();
return GleSYSTemplateOptions.class.cast(options.blockOnPort(port, seconds));
}
-
+
/**
* @see TemplateOptions#userMetadata(Map)
*/
@@ -180,4 +262,18 @@
public GleSYSTemplateOptions userMetadata(String key, String value) {
return GleSYSTemplateOptions.class.cast(super.userMetadata(key, value));
}
+
+ @Override
+ public ToStringHelper string() {
+ ToStringHelper stringHelper = super.string();
+
+ stringHelper.add("transferGB", this.transferGB);
+ stringHelper.add("ip", this.ip);
+ if (this.hasRootPassword()) {
+ stringHelper.add("rootPasswordPresent", true);
+ }
+
+ return stringHelper;
+ }
+
}
diff --git a/providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java b/providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java
index 1029395..9fe26d7 100644
--- a/providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java
+++ b/providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java
@@ -25,14 +25,12 @@
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.glesys.GleSYSApiMetadata;
-import org.jclouds.glesys.compute.config.GleSYSComputeServiceContextModule.PasswordProvider;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.BaseRestApiExpectTest;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
-import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Module;
@@ -57,15 +55,6 @@
return createInjector(fn, module, props).getInstance(ComputeService.class);
}
- protected PasswordProvider passwordGenerator() {
- // make sure we can predict passwords generated for createServer requests
- return new PasswordProvider() {
- public String get() {
- return "foo";
- }
- };
- }
-
protected Injector injectorForKnownArgumentsAndConstantPassword() {
return injectorForKnownArgumentsAndConstantPassword(ImmutableMap.<HttpRequest, HttpResponse> of());
}
@@ -95,14 +84,7 @@
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(),
HttpResponse.builder().statusCode(204)
.payload(payloadFromResource("/server_allowed_arguments.json")).build())
- .putAll(requestsResponses).build(), new AbstractModule() {
-
- @Override
- protected void configure() {
- bind(PasswordProvider.class).toInstance(passwordGenerator());
- }
-
- }).getContext();
+ .putAll(requestsResponses).build()).getContext();
}
protected ComputeServiceContext computeContextForKnownArgumentsAndConstantPassword() {
diff --git a/providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java b/providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java
index b74c90e..894973e 100644
--- a/providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java
+++ b/providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java
@@ -19,6 +19,8 @@
package org.jclouds.glesys.compute.options;
import static org.jclouds.glesys.compute.options.GleSYSTemplateOptions.Builder.ip;
+import static org.jclouds.glesys.compute.options.GleSYSTemplateOptions.Builder.rootPassword;
+import static org.jclouds.glesys.compute.options.GleSYSTemplateOptions.Builder.transferGB;
import static org.testng.Assert.assertEquals;
import org.jclouds.compute.options.TemplateOptions;
@@ -57,8 +59,72 @@
assertEquals(options.as(GleSYSTemplateOptions.class).getIp(), "1.1.1.1");
}
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullIpThrowsNPE() {
+ new GleSYSTemplateOptions().ip(null);
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testInvalidIpThrowsIllegalArgument() {
+ new GleSYSTemplateOptions().ip("1.1.1");
+ }
+
@Test(expectedExceptions = IllegalArgumentException.class)
public void testipIsInvalidThrowsIllegalArgument() {
new GleSYSTemplateOptions().ip("foo");
}
+
+ @Test
+ public void testDefaultRootPassword() {
+ TemplateOptions options = new GleSYSTemplateOptions();
+ assertEquals(options.as(GleSYSTemplateOptions.class).getRootPassword(), null);
+ }
+
+ @Test
+ public void testRootPassword() {
+ TemplateOptions options = new GleSYSTemplateOptions().rootPassword("secret");
+ assertEquals(options.as(GleSYSTemplateOptions.class).getRootPassword(), "secret");
+ }
+
+ @Test
+ public void testRootPasswordStatic() {
+ TemplateOptions options = rootPassword("secret");
+ assertEquals(options.as(GleSYSTemplateOptions.class).getRootPassword(), "secret");
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void testNullRootPasswordThrowsNPE() {
+ new GleSYSTemplateOptions().rootPassword(null);
+ }
+
+ @Test
+ public void testDefaultTranferGB() {
+ TemplateOptions options = new GleSYSTemplateOptions();
+ assertEquals(options.as(GleSYSTemplateOptions.class).getTransferGB(), 50);
+ }
+
+ @Test
+ public void testTransferGB() {
+ TemplateOptions options = new GleSYSTemplateOptions().transferGB(75);
+ assertEquals(options.as(GleSYSTemplateOptions.class).getTransferGB(), 75);
+ }
+
+ @Test
+ public void testTransferGBStatic() {
+ TemplateOptions options = transferGB(75);
+ assertEquals(options.as(GleSYSTemplateOptions.class).getTransferGB(), 75);
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNegativeTransferGBThrowsException() {
+ new GleSYSTemplateOptions().transferGB(-1);
+ }
+
+ @Test
+ public void testClone() {
+ GleSYSTemplateOptions clone = transferGB(75).rootPassword("root").ip("1.1.1.1").clone();
+ assertEquals(clone.getTransferGB(), 75);
+ assertEquals(clone.getRootPassword(), "root");
+ assertEquals(clone.getIp(), "1.1.1.1");
+ }
}