mirror of https://github.com/apache/jclouds.git
Issue 713:support userMetadata in createNodesInGroup in byon, cloudservers, and aws-ec2
This commit is contained in:
parent
031ee4bee5
commit
842da34982
|
@ -20,10 +20,13 @@ package org.jclouds.byon;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -48,6 +51,7 @@ public class Node {
|
|||
private int loginPort = 22;
|
||||
private String group;
|
||||
private Set<String> tags = ImmutableSet.of();
|
||||
private Map<String, String> metadata = ImmutableMap.<String, String>of();
|
||||
private String username;
|
||||
private String credential;
|
||||
private URI credentialUrl;
|
||||
|
@ -118,6 +122,11 @@ public class Node {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder metadata(Map<String, String> metadata) {
|
||||
this.metadata = ImmutableMap.copyOf(metadata);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder username(String username) {
|
||||
this.username = username;
|
||||
return this;
|
||||
|
@ -140,13 +149,14 @@ public class Node {
|
|||
|
||||
public Node build() {
|
||||
return new Node(id, name, description, hostname, locationId, osArch, osFamily, osDescription, osVersion,
|
||||
os64Bit, loginPort, group, tags, username, credential, credentialUrl, sudoPassword);
|
||||
os64Bit, loginPort, group, tags, metadata, username, credential, credentialUrl, sudoPassword);
|
||||
}
|
||||
}
|
||||
|
||||
public Node(String id, String name, String description, String hostname, String locationId, String osArch,
|
||||
String osFamily, String osDescription, String osVersion, boolean os64Bit, int loginPort, String group,
|
||||
Iterable<String> tags, String username, String credential, URI credentialUrl, String sudoPassword) {
|
||||
Iterable<String> tags, Map<String, String> metadata, String username, String credential, URI credentialUrl,
|
||||
String sudoPassword) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
|
@ -160,6 +170,7 @@ public class Node {
|
|||
this.loginPort = loginPort;
|
||||
this.group = group;
|
||||
this.tags = ImmutableSet.copyOf(tags);
|
||||
this.metadata = ImmutableMap.copyOf(metadata);
|
||||
this.username = username;
|
||||
this.credential = credential;
|
||||
this.credentialUrl = credentialUrl;
|
||||
|
@ -179,6 +190,7 @@ public class Node {
|
|||
private final boolean os64Bit;
|
||||
private final String group;
|
||||
private final Set<String> tags;
|
||||
private final Map<String, String> metadata;
|
||||
private final String username;
|
||||
private final String credential;
|
||||
private final URI credentialUrl;
|
||||
|
@ -239,6 +251,10 @@ public class Node {
|
|||
return tagSet;
|
||||
}
|
||||
|
||||
public Map<String, String> getMetadata() {
|
||||
return Maps.newLinkedHashMap(this.metadata);
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
@ -269,12 +285,12 @@ public class Node {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add(
|
||||
"locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily).add(
|
||||
"osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit).add("group", group)
|
||||
.add("loginPort", loginPort).add("tags", tags).add("username", username).add("hasCredential",
|
||||
credential != null || credentialUrl != null).add("hasSudoPassword", sudoPassword != null)
|
||||
.toString();
|
||||
return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description)
|
||||
.add("locationId", locationId).add("hostname", hostname).add("osArch", osArch).add("osFamily", osFamily)
|
||||
.add("osDescription", osDescription).add("osVersion", osVersion).add("os64Bit", os64Bit)
|
||||
.add("group", group).add("loginPort", loginPort).add("tags", tags).add("metadata", metadata)
|
||||
.add("username", username).add("hasCredential", credential != null || credentialUrl != null)
|
||||
.add("hasSudoPassword", sudoPassword != null).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.byon.domain;
|
|||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.byon.Node;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
@ -34,6 +35,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Closeables;
|
||||
|
||||
/**
|
||||
|
@ -54,6 +56,8 @@ import com.google.common.io.Closeables;
|
|||
* group: hadoop
|
||||
* tags:
|
||||
* - vanilla
|
||||
* metadata:
|
||||
* key1: val1
|
||||
* username: kelvin
|
||||
* credential: password_or_rsa
|
||||
* or
|
||||
|
@ -78,6 +82,7 @@ public class YamlNode {
|
|||
public boolean os_64bit;
|
||||
public String group;
|
||||
public List<String> tags = Lists.newArrayList();
|
||||
public Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||
public String username;
|
||||
public String credential;
|
||||
public String credential_url;
|
||||
|
@ -91,7 +96,7 @@ public class YamlNode {
|
|||
return Node.builder().id(arg0.id).name(arg0.name).description(arg0.description).locationId(arg0.location_id)
|
||||
.hostname(arg0.hostname).osArch(arg0.os_arch).osFamily(arg0.os_family).osDescription(
|
||||
arg0.os_description).osVersion(arg0.os_version).os64Bit(arg0.os_64bit).group(arg0.group)
|
||||
.loginPort(arg0.login_port).tags(arg0.tags).username(arg0.username).credential(arg0.credential).credentialUrl(
|
||||
.loginPort(arg0.login_port).tags(arg0.tags).metadata(arg0.metadata).username(arg0.username).credential(arg0.credential).credentialUrl(
|
||||
arg0.credential_url != null ? URI.create(arg0.credential_url) : null).sudoPassword(
|
||||
arg0.sudo_password).build();
|
||||
}
|
||||
|
@ -152,6 +157,8 @@ public class YamlNode {
|
|||
prettier.put("group", in.group);
|
||||
if (in.tags.size() != 0)
|
||||
prettier.put("tags", in.tags);
|
||||
if (in.metadata.size() != 0)
|
||||
prettier.put("metadata", in.metadata);
|
||||
if (in.username != null)
|
||||
prettier.put("username", in.username);
|
||||
if (in.credential != null)
|
||||
|
@ -193,6 +200,7 @@ public class YamlNode {
|
|||
yaml.login_port = arg0.getLoginPort();
|
||||
yaml.group = arg0.getGroup();
|
||||
yaml.tags = ImmutableList.copyOf(arg0.getTags());
|
||||
yaml.metadata = ImmutableMap.copyOf(arg0.getMetadata());
|
||||
yaml.username = arg0.getUsername();
|
||||
yaml.credential = arg0.getCredential();
|
||||
yaml.credential_url = arg0.getCredentialUrl() != null ? arg0.getCredentialUrl().toASCIIString() : null;
|
||||
|
|
|
@ -84,6 +84,7 @@ public class NodeToNodeMetadata implements Function<Node, NodeMetadata> {
|
|||
builder.location(findLocationWithId(from.getLocationId()));
|
||||
builder.group(from.getGroup());
|
||||
builder.tags(from.getTags());
|
||||
builder.userMetadata(from.getMetadata());
|
||||
builder.operatingSystem(OperatingSystem.builder().arch(from.getOsArch()).family(
|
||||
OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription())
|
||||
.version(from.getOsVersion()).build());
|
||||
|
|
|
@ -85,6 +85,7 @@ public class NodeToNodeMetadataTest {
|
|||
.loginPort(loginPort)
|
||||
.hostname("cluster-" + id + ".mydomain.com")
|
||||
.location(location)
|
||||
.userMetadata(ImmutableMap.of("Name", "foo"))
|
||||
.state(NodeState.RUNNING)
|
||||
.operatingSystem(
|
||||
OperatingSystem.builder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3")
|
||||
|
|
|
@ -34,23 +34,23 @@ import com.google.common.collect.ImmutableMap;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class NodesFromYamlTest {
|
||||
public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n").append(
|
||||
"MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n").append(
|
||||
"u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n").append(
|
||||
"lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n")
|
||||
public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n")
|
||||
.append("MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n")
|
||||
.append("u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n")
|
||||
.append("lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n")
|
||||
.toString();
|
||||
|
||||
public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, 22, "hadoop", ImmutableList.of("vanilla"),
|
||||
"myUser", key, null, "happy bear");
|
||||
"cluster-1.mydomain.com", null, "x86", "rhel", "redhat", "5.3", false, 22, "hadoop",
|
||||
ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
|
||||
|
||||
public static final Node TEST2 = new Node("cluster-1", "cluster-1", "accounting analytics cluster",
|
||||
"cluster-1.mydomain.com", "virginia", "x86", "rhel", "redhat", "5.3", false, 22, "hadoop",
|
||||
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||
ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
|
||||
|
||||
public static final Node TEST3 = new Node("cluster-2", "cluster-2", "accounting analytics cluster",
|
||||
"cluster-2.mydomain.com", "maryland", "x86", "rhel", "redhat", "5.3", false, 2022, "hadoop",
|
||||
ImmutableList.of("vanilla"), "myUser", key, null, "happy bear");
|
||||
ImmutableList.of("vanilla"), ImmutableMap.of("Name", "foo"), "myUser", key, null, "happy bear");
|
||||
|
||||
@Test
|
||||
public void testNodesParse() throws Exception {
|
||||
|
|
|
@ -10,6 +10,8 @@ nodes:
|
|||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
metadata:
|
||||
Name: foo
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
|
|
|
@ -11,6 +11,8 @@ nodes:
|
|||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
metadata:
|
||||
Name: foo
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
|
@ -33,6 +35,8 @@ nodes:
|
|||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
metadata:
|
||||
Name: foo
|
||||
username: myUser
|
||||
credential: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
|
|
|
@ -10,6 +10,8 @@ nodes:
|
|||
group: hadoop
|
||||
tags:
|
||||
- vanilla
|
||||
metadata:
|
||||
Name: foo
|
||||
username: myUser
|
||||
credential_url: classpath:///testkey.txt
|
||||
sudo_password: happy bear
|
||||
|
|
|
@ -19,18 +19,19 @@
|
|||
package org.jclouds.cloudservers.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.cloudservers.CloudServersClient;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.cloudservers.CloudServersClient;
|
||||
import org.jclouds.cloudservers.domain.Server;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
|
@ -53,8 +54,9 @@ public class CloudServersCreateNodeWithGroupEncodedIntoName implements CreateNod
|
|||
|
||||
@Override
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
|
||||
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer
|
||||
.parseInt(template.getHardware().getProviderId()));
|
||||
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()),
|
||||
Integer.parseInt(template.getHardware().getProviderId()),
|
||||
withMetadata(template.getOptions().getUserMetadata()));
|
||||
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
|
||||
return serverToNodeMetadata.apply(from);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,13 @@ public class CloudSigmaComputeServiceLiveTest extends BaseComputeServiceLiveTest
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// cloudsigma does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
|
||||
// hostname is not predictable based on node metadata
|
||||
assert execResponse.getOutput().trim().equals("ubuntu");
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.jclouds.rest.RestContext;
|
|||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
|
@ -50,6 +51,12 @@ public class DeltacloudComputeServiceLiveTest extends BaseComputeServiceLiveTest
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// deltacloud does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
RestContext<DeltacloudClient, DeltacloudAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||
|
|
|
@ -89,6 +89,11 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
if (instance == null || instance.getId() == null)
|
||||
return null;
|
||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||
builder = buildInstance(instance, builder);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected NodeMetadataBuilder buildInstance(RunningInstance instance, NodeMetadataBuilder builder) {
|
||||
builder.providerId(instance.getId());
|
||||
builder.id(instance.getRegion() + "/" + instance.getId());
|
||||
String group = getGroupForInstance(instance);
|
||||
|
@ -116,8 +121,7 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
|
|||
} catch (UncheckedExecutionException e) {
|
||||
logger.debug("error getting image for %s: %s", regionAndName, e);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected void addCredentialsForInstance(NodeMetadataBuilder builder, RunningInstance instance) {
|
||||
|
|
|
@ -23,10 +23,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
|
@ -35,6 +34,7 @@ import org.jclouds.ec2.domain.BlockDeviceMapping.MapEphemeralDeviceToDevice;
|
|||
import org.jclouds.ec2.domain.BlockDeviceMapping.MapNewVolumeToDevice;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping.UnmapDeviceNamed;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
|
||||
|
@ -42,11 +42,11 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on the "ec2" provider.
|
||||
* <h2>
|
||||
* Usage</h2> The recommended way to instantiate a EC2TemplateOptions object is to statically import
|
||||
* EC2TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
|
||||
* needed):
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on
|
||||
* the "ec2" provider. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a EC2TemplateOptions object is
|
||||
* to statically import EC2TemplateOptions.* and invoke a static creation method
|
||||
* followed by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.*;
|
||||
|
@ -292,13 +292,20 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withDetails
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static EC2TemplateOptions withDetails() {
|
||||
public static EC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.withMetadata());
|
||||
return EC2TemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static EC2TemplateOptions userMetadata(String key, String value) {
|
||||
EC2TemplateOptions options = new EC2TemplateOptions();
|
||||
return EC2TemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
@ -370,14 +377,6 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
|
|||
return EC2TemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public EC2TemplateOptions withMetadata() {
|
||||
return EC2TemplateOptions.class.cast(super.withMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -427,15 +426,32 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return groupNames the user specified to run instances with, or zero length set to create an
|
||||
* implicit group
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public EC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return EC2TemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public EC2TemplateOptions userMetadata(String key, String value) {
|
||||
return EC2TemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return groupNames the user specified to run instances with, or zero
|
||||
* length set to create an implicit group
|
||||
*/
|
||||
public Set<String> getGroups() {
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return keyPair to use when running the instance or null, to generate a keypair.
|
||||
* @return keyPair to use when running the instance or null, to generate a
|
||||
* keypair.
|
||||
*/
|
||||
public String getKeyPair() {
|
||||
return keyPair;
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.jclouds.sshj.config.SshjSshClientModule;
|
|||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -73,6 +74,14 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// normal ec2 does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testCorrectAuthException")
|
||||
public void testImagesResolveCorrectly() {
|
||||
Template defaultTemplate = client.templateBuilder().build();
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +41,13 @@ public class ElasticStackComputeServiceLiveTest extends BaseComputeServiceLiveTe
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// elasticstack does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testOptionToNotBlock() {
|
||||
// start call is blocking anyway.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.openstack.nova.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.openstack.nova.options.CreateServerOptions.Builder.withMetadata;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -53,7 +54,8 @@ public class NovaCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGro
|
|||
|
||||
@Override
|
||||
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
|
||||
Server from = client.createServer(name, template.getImage().getId(), template.getHardware().getId());
|
||||
Server from = client.createServer(name, template.getImage().getId(), template.getHardware().getId(),
|
||||
withMetadata(template.getOptions().getUserMetadata()));
|
||||
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
|
||||
return serverToNodeMetadata.apply(from);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
|
|
|
@ -50,6 +50,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import net.schmizz.sshj.userauth.UserAuthException;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
|
@ -352,13 +353,6 @@ public class NovaComputeServiceLiveTest extends ComputeBase {
|
|||
//checkHttpGet(node);
|
||||
}
|
||||
|
||||
@Test(timeOut = 60000)
|
||||
public void testTemplateOptions() throws Exception {
|
||||
TemplateOptions options = new TemplateOptions().withMetadata();
|
||||
Template t = getDefaultTemplateBuilder().smallest().options(options).build();
|
||||
assert t.getOptions().isIncludeMetadata() : "The metadata option should be 'true' " + "for the created template";
|
||||
}
|
||||
|
||||
public void testListImages() throws Exception {
|
||||
for (Image image : computeService.listImages()) {
|
||||
assert image.getProviderId() != null : image;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.vcloud.compute.options;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
|
@ -164,11 +165,19 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withDetails
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static VCloudTemplateOptions withDetails() {
|
||||
public static VCloudTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.withMetadata());
|
||||
return VCloudTemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static VCloudTemplateOptions userMetadata(String key, String value) {
|
||||
VCloudTemplateOptions options = new VCloudTemplateOptions();
|
||||
return VCloudTemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -270,11 +279,19 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions withMetadata() {
|
||||
return VCloudTemplateOptions.class.cast(super.withMetadata());
|
||||
public VCloudTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return VCloudTemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public VCloudTemplateOptions userMetadata(String key, String value) {
|
||||
return VCloudTemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -317,7 +334,7 @@ public class VCloudTemplateOptions extends TemplateOptions implements Cloneable
|
|||
+ ", ipAddressAllocationMode=" + ipAddressAllocationMode + ", inboundPorts="
|
||||
+ Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey="
|
||||
+ (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
+ ", userMetadata: " + userMetadata + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.jclouds.vcloud.VCloudClient;
|
|||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -40,7 +41,7 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true)
|
||||
@Test(groups = "live", enabled = true, singleThreaded = true)
|
||||
public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
|
||||
public VCloudComputeServiceLiveTest() {
|
||||
|
@ -52,6 +53,13 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// vcloud does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory(setupRestProperties())
|
||||
|
|
|
@ -22,16 +22,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on the
|
||||
* "trmk-vcloudexpress" provider. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a TerremarkVCloudTemplateOptions object is to
|
||||
* statically import TerremarkVCloudTemplateOptions.* and invoke a static creation method followed
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on
|
||||
* the "trmk-vcloudexpress" provider. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a
|
||||
* TerremarkVCloudTemplateOptions object is to statically import
|
||||
* TerremarkVCloudTemplateOptions.* and invoke a static creation method followed
|
||||
* by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
|
@ -157,13 +159,20 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions implements C
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withDetails
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static TerremarkVCloudTemplateOptions withDetails() {
|
||||
public static TerremarkVCloudTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions();
|
||||
return TerremarkVCloudTemplateOptions.class.cast(options.withMetadata());
|
||||
return TerremarkVCloudTemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static TerremarkVCloudTemplateOptions userMetadata(String key, String value) {
|
||||
TerremarkVCloudTemplateOptions options = new TerremarkVCloudTemplateOptions();
|
||||
return TerremarkVCloudTemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
@ -178,9 +187,10 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions implements C
|
|||
|
||||
/**
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
|
@ -241,15 +251,23 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions implements C
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata
|
||||
* @see TemplateOptions#userMetadata
|
||||
*/
|
||||
@Override
|
||||
public TerremarkVCloudTemplateOptions withMetadata() {
|
||||
return TerremarkVCloudTemplateOptions.class.cast(super.withMetadata());
|
||||
public TerremarkVCloudTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return TerremarkVCloudTemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return keyPair to use when running the instance or null, to generate a keypair.
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TerremarkVCloudTemplateOptions userMetadata(String key, String value) {
|
||||
return TerremarkVCloudTemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return keyPair to use when running the instance or null, to generate a
|
||||
* keypair.
|
||||
*/
|
||||
public String getSshKeyFingerprint() {
|
||||
return keyPair;
|
||||
|
@ -295,7 +313,7 @@ public class TerremarkVCloudTemplateOptions extends TemplateOptions implements C
|
|||
return "TerremarkVCloudTemplateOptions [keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", inboundPorts="
|
||||
+ Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey="
|
||||
+ (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
+ ", userMetadata: " + userMetadata + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
@ -34,12 +35,14 @@ import org.jclouds.util.Strings2;
|
|||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNodesWithTag} operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to statically import
|
||||
* TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
|
||||
* needed):
|
||||
* Contains options supported in the {@code ComputeService#runNodesWithTag}
|
||||
* operation. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a TemplateOptions object is to
|
||||
* statically import TemplateOptions.* and invoke a static creation method
|
||||
* followed by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.compute.options.TemplateOptions.Builder.*;
|
||||
|
@ -71,8 +74,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
to.authorizePublicKey(this.getPublicKey());
|
||||
if (this.getPort() != -1)
|
||||
to.blockOnPort(this.getPort(), this.getSeconds());
|
||||
if (this.isIncludeMetadata())
|
||||
to.withMetadata();
|
||||
if (this.getUserMetadata().size() > 0)
|
||||
to.userMetadata(this.getUserMetadata());
|
||||
if (this.getTags().size() > 0)
|
||||
to.tags(getTags());
|
||||
if (!this.shouldBlockUntilRunning())
|
||||
|
@ -266,19 +269,34 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
throw new IllegalArgumentException("privateKey is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIncludeMetadata() {
|
||||
return delegate.isIncludeMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions runScript(byte[] script) {
|
||||
throw new IllegalArgumentException("script is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions withMetadata() {
|
||||
throw new IllegalArgumentException("metadata is immutable");
|
||||
public Set<String> getTags() {
|
||||
return delegate.getTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions tags(Iterable<String> tags) {
|
||||
throw new IllegalArgumentException("tags are immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
throw new IllegalArgumentException("userMetadata is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateOptions userMetadata(String key, String value) {
|
||||
throw new IllegalArgumentException("userMetadata is immutable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return delegate.getUserMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -293,10 +311,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
|
||||
protected String publicKey;
|
||||
|
||||
protected boolean includeMetadata;
|
||||
|
||||
protected boolean blockUntilRunning = true;
|
||||
|
||||
protected Map<String, String> userMetadata = Maps.newLinkedHashMap();
|
||||
|
||||
public int[] getInboundPorts() {
|
||||
return inboundPorts;
|
||||
}
|
||||
|
@ -317,10 +335,6 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return publicKey;
|
||||
}
|
||||
|
||||
public boolean isIncludeMetadata() {
|
||||
return includeMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#blockUntilRunning(boolean)
|
||||
*/
|
||||
|
@ -334,7 +348,9 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
|
||||
/**
|
||||
* <p/>
|
||||
* please use alternative that uses the {@link org.jclouds.scriptbuilder.domain.Statement} object
|
||||
* please use alternative that uses the
|
||||
* {@link org.jclouds.scriptbuilder.domain.Statement} object
|
||||
*
|
||||
* @see TemplateOptions#runScript(Statement)
|
||||
* @see org.jclouds.io.Payloads
|
||||
*/
|
||||
|
@ -357,8 +373,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* This script will be executed as the root user upon system startup. This script gets a
|
||||
* prologue, so no #!/bin/bash required, path set up, etc
|
||||
* This script will be executed as the root user upon system startup. This
|
||||
* script gets a prologue, so no #!/bin/bash required, path set up, etc
|
||||
*
|
||||
*/
|
||||
public TemplateOptions runScript(Statement script) {
|
||||
|
@ -442,11 +458,6 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TemplateOptions withMetadata() {
|
||||
this.includeMetadata = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder extends org.jclouds.compute.options.RunScriptOptions.Builder {
|
||||
|
||||
public static TemplateOptions nameTask(String name) {
|
||||
|
@ -535,7 +546,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* please use alternative that uses the {@link org.jclouds.io.Payload} object
|
||||
* please use alternative that uses the {@link org.jclouds.io.Payload}
|
||||
* object
|
||||
*
|
||||
* @see org.jclouds.io.Payloads
|
||||
* @see #installPrivateKey(Payload)
|
||||
|
@ -556,7 +568,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* please use alternative that uses the {@link org.jclouds.io.Payload} object
|
||||
* please use alternative that uses the {@link org.jclouds.io.Payload}
|
||||
* object
|
||||
*
|
||||
* @see org.jclouds.io.Payloads
|
||||
* @see #authorizePublicKey(Payload)
|
||||
|
@ -576,9 +589,20 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return options.authorizePublicKey(rsaKey);
|
||||
}
|
||||
|
||||
public static TemplateOptions withDetails() {
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.withMetadata();
|
||||
return options.userMetadata(userMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static TemplateOptions userMetadata(String key, String value) {
|
||||
TemplateOptions options = new TemplateOptions();
|
||||
return options.userMetadata(key, value);
|
||||
}
|
||||
|
||||
public static TemplateOptions blockOnComplete(boolean value) {
|
||||
|
@ -592,8 +616,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
public String toString() {
|
||||
return "[inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey="
|
||||
+ (publicKey != null) + ", runScript=" + (script != null) + ", blockUntilRunning=" + blockUntilRunning
|
||||
+ ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds
|
||||
+ ", metadata/details: " + includeMetadata + "]";
|
||||
+ ", blockOnComplete=" + blockOnComplete + ", port:seconds=" + port + ":" + seconds + ", userMetadata: "
|
||||
+ userMetadata + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -613,14 +637,43 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userMetadata
|
||||
* user-defined metadata to assign to this server
|
||||
*/
|
||||
public TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
this.userMetadata.putAll(checkNotNull(userMetadata, "userMetadata"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param key
|
||||
* key to place into the metadata map
|
||||
* @param value
|
||||
* value to associate with that key
|
||||
*/
|
||||
public TemplateOptions userMetadata(String key, String value) {
|
||||
this.userMetadata.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #userMetadata(Map)
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
return userMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (blockUntilRunning ? 1231 : 1237);
|
||||
result = prime * result + Arrays.hashCode(inboundPorts);
|
||||
result = prime * result + (includeMetadata ? 1231 : 1237);
|
||||
result = prime * result + port;
|
||||
result = prime * result + ((userMetadata == null) ? 0 : userMetadata.hashCode());
|
||||
result = prime * result + ((privateKey == null) ? 0 : privateKey.hashCode());
|
||||
result = prime * result + ((publicKey == null) ? 0 : publicKey.hashCode());
|
||||
result = prime * result + ((script == null) ? 0 : script.hashCode());
|
||||
|
@ -641,7 +694,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
|
|||
return false;
|
||||
if (!Arrays.equals(inboundPorts, other.inboundPorts))
|
||||
return false;
|
||||
if (includeMetadata != other.includeMetadata)
|
||||
if (userMetadata == null) {
|
||||
if (other.userMetadata != null)
|
||||
return false;
|
||||
} else if (!userMetadata.equals(other.userMetadata))
|
||||
return false;
|
||||
if (port != other.port)
|
||||
return false;
|
||||
|
|
|
@ -92,6 +92,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
|||
// using a predictable name so tests will pass
|
||||
builder.hostname(group);
|
||||
builder.tags(template.getOptions().getTags());
|
||||
builder.userMetadata(template.getOptions().getUserMetadata());
|
||||
builder.group(group);
|
||||
builder.location(location.get());
|
||||
builder.imageId(template.getImage().getId());
|
||||
|
|
|
@ -50,11 +50,11 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
@ -96,6 +96,7 @@ import com.google.common.base.Function;
|
|||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Guice;
|
||||
|
@ -531,7 +532,8 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assertEquals(toDestroy, destroyed.size());
|
||||
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), inGroup(group))) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
assertEquals(context.getCredentialStore().get("node#" + node.getId()), null);
|
||||
assert context.getCredentialStore().get("node#" + node.getId()) == null : "credential should have been null for "
|
||||
+ "node#" + node.getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,12 +597,16 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
try {
|
||||
ImmutableMap<String, String> userMetadata = ImmutableMap.<String, String> of("Name", group);
|
||||
long startSeconds = currentTimeMillis();
|
||||
NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, inboundPorts(22, 8080).blockOnPort(22,
|
||||
300)));
|
||||
NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1,
|
||||
inboundPorts(22, 8080).blockOnPort(22, 300)
|
||||
.userMetadata(userMetadata)));
|
||||
final String nodeId = node.getId();
|
||||
long createSeconds = (currentTimeMillis() - startSeconds) / 1000;
|
||||
|
||||
checkUserMetadataInNodeEquals(node, userMetadata);
|
||||
|
||||
getAnonymousLogger().info(
|
||||
format("<< available node(%s) os(%s) in %ss", node.getId(), node.getOperatingSystem(), createSeconds));
|
||||
|
||||
|
@ -656,11 +662,9 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
}
|
||||
|
||||
@Test(enabled = true/* , dependsOnMethods = "testCompareSizes" */)
|
||||
public void testTemplateOptions() throws Exception {
|
||||
TemplateOptions options = new TemplateOptions().withMetadata();
|
||||
Template t = client.templateBuilder().smallest().options(options).build();
|
||||
assert t.getOptions().isIncludeMetadata() : "The metadata option should be 'true' " + "for the created template";
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(userMetadata) : String.format("node userMetadata did not match %s %s",
|
||||
userMetadata, node);
|
||||
}
|
||||
|
||||
public void testListImages() throws Exception {
|
||||
|
|
|
@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
|
@ -57,7 +58,7 @@ public abstract class ResourceMetadataBuilder<T extends Enum<T>> {
|
|||
}
|
||||
|
||||
public ResourceMetadataBuilder<T> userMetadata(Map<String, String> userMetadata) {
|
||||
this.userMetadata = checkNotNull(userMetadata, "userMetadata");
|
||||
this.userMetadata = ImmutableMap.copyOf(checkNotNull(userMetadata, "userMetadata"));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -34,12 +35,16 @@ import org.jclouds.Constants;
|
|||
import org.jclouds.aws.ec2.AWSEC2Client;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup;
|
||||
import org.jclouds.aws.ec2.domain.PlacementGroup.State;
|
||||
import org.jclouds.aws.util.AWSUtils;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
@ -62,9 +67,12 @@ import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
|||
import org.jclouds.util.Preconditions2;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
|
@ -91,7 +99,8 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client,
|
||||
Cache<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Cache<RegionAndName, String> securityGroupMap,
|
||||
Cache<RegionAndName, KeyPair> credentialsMap,
|
||||
@Named("SECURITY") Cache<RegionAndName, String> securityGroupMap,
|
||||
@Named("PLACEMENT") Cache<RegionAndName, String> placementGroupMap,
|
||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
|
@ -104,6 +113,50 @@ public class AWSEC2ComputeService extends EC2ComputeService {
|
|||
this.placementGroupDeleted = placementGroupDeleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, final Template template)
|
||||
throws RunNodesException {
|
||||
Set<? extends NodeMetadata> nodes = super.createNodesInGroup(group, count, template);
|
||||
// tags from spot requests do not propagate to running instances
|
||||
// automatically
|
||||
if (templateWasASpotRequestWithUserMetadata(template)) {
|
||||
addTagsToNodesFromUserMetadataInTemplate(nodes, template);
|
||||
nodes = addUserMetadataFromTemplateOptionsToNodes(template, nodes);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
protected void addTagsToNodesFromUserMetadataInTemplate(Set<? extends NodeMetadata> nodes, final Template template) {
|
||||
String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
|
||||
ec2Client.getTagServices().createTagsInRegion(region, transform(nodes, new Function<NodeMetadata, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(NodeMetadata arg0) {
|
||||
return arg0.getProviderId();
|
||||
}
|
||||
|
||||
}), template.getOptions().getUserMetadata());
|
||||
}
|
||||
|
||||
protected boolean templateWasASpotRequestWithUserMetadata(final Template template) {
|
||||
return template.getOptions().getUserMetadata().size() > 0
|
||||
&& AWSEC2TemplateOptions.class.cast(template.getOptions()).getSpotPrice() != null;
|
||||
}
|
||||
|
||||
protected Set<? extends NodeMetadata> addUserMetadataFromTemplateOptionsToNodes(final Template template,
|
||||
Set<? extends NodeMetadata> nodes) {
|
||||
nodes = ImmutableSet.copyOf(Iterables.transform(nodes, new Function<NodeMetadata, NodeMetadata>() {
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(NodeMetadata arg0) {
|
||||
return NodeMetadataBuilder.fromNodeMetadata(arg0).userMetadata(template.getOptions().getUserMetadata())
|
||||
.build();
|
||||
}
|
||||
|
||||
}));
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void deletePlacementGroup(String region, String group) {
|
||||
Preconditions2.checkNotEmpty(group, "group");
|
||||
|
|
|
@ -23,16 +23,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.ec2.domain.BlockDeviceMapping;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.util.Preconditions2;
|
||||
|
||||
|
@ -40,11 +40,11 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on the "ec2" provider.
|
||||
* <h2>
|
||||
* Usage</h2> The recommended way to instantiate a AWSEC2TemplateOptions object is to statically
|
||||
* import AWSEC2TemplateOptions.* and invoke a static creation method followed by an instance
|
||||
* mutator (if needed):
|
||||
* Contains options supported in the {@code ComputeService#runNode} operation on
|
||||
* the "ec2" provider. <h2>
|
||||
* Usage</h2> The recommended way to instantiate a AWSEC2TemplateOptions object
|
||||
* is to statically import AWSEC2TemplateOptions.* and invoke a static creation
|
||||
* method followed by an instance mutator (if needed):
|
||||
* <p/>
|
||||
* <code>
|
||||
* import static org.jclouds.aws.ec2.compute.options.AWSEC2TemplateOptions.Builder.*;
|
||||
|
@ -175,10 +175,6 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
return groupIds;
|
||||
}
|
||||
|
||||
public void setGroupIds(Set<String> groupIds) {
|
||||
this.groupIds = groupIds;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
|
@ -344,14 +340,6 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
return options.authorizePublicKey(rsaKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withDetails
|
||||
*/
|
||||
public static AWSEC2TemplateOptions withDetails() {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.withMetadata();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#spotPrice
|
||||
*/
|
||||
|
@ -375,6 +363,22 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return options.spotOptions(spotOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static AWSEC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static AWSEC2TemplateOptions userMetadata(String key, String value) {
|
||||
AWSEC2TemplateOptions options = new AWSEC2TemplateOptions();
|
||||
return AWSEC2TemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
// methods that only facilitate returning the correct object type
|
||||
|
@ -387,6 +391,22 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
return AWSEC2TemplateOptions.class.cast(super.blockDeviceMappings(blockDeviceMappings));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions userMetadata(String key, String value) {
|
||||
return AWSEC2TemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -530,14 +550,6 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
return AWSEC2TemplateOptions.class.cast(super.runScript(script));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public AWSEC2TemplateOptions withMetadata() {
|
||||
return AWSEC2TemplateOptions.class.cast(super.withMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -587,7 +599,8 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
|||
}
|
||||
|
||||
/**
|
||||
* @return placementGroup to use when running the instance or null, to generate a placementGroup.
|
||||
* @return placementGroup to use when running the instance or null, to
|
||||
* generate a placementGroup.
|
||||
*/
|
||||
public String getPlacementGroup() {
|
||||
return placementGroup;
|
||||
|
|
|
@ -66,4 +66,8 @@ public class AWSRunningInstanceToNodeMetadata extends RunningInstanceToNodeMetad
|
|||
builder.credentials(creds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NodeMetadataBuilder buildInstance(RunningInstance instance, NodeMetadataBuilder builder) {
|
||||
return super.buildInstance(instance, builder).userMetadata(AWSRunningInstance.class.cast(instance).getTags());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -50,7 +51,6 @@ import org.jclouds.logging.Logger;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -72,8 +72,7 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT
|
|||
AWSEC2Client client,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
|
||||
AWSEC2InstancePresent instancePresent,
|
||||
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||
AWSEC2InstancePresent instancePresent, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
|
||||
Cache<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
|
||||
ComputeUtils utils, SpotInstanceRequestToAWSRunningInstance spotConverter) {
|
||||
super(client, templateBuilderProvider, createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, instancePresent,
|
||||
|
@ -93,14 +92,34 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT
|
|||
logger.debug(">> requesting %d spot instances region(%s) price(%f) spec(%s) options(%s)", count, region,
|
||||
spotPrice, spec, options);
|
||||
|
||||
return Iterables.transform(client.getSpotInstanceServices().requestSpotInstancesInRegion(region, spotPrice,
|
||||
count, spec, options), spotConverter);
|
||||
return addTagsToInstancesInRegion(
|
||||
template.getOptions().getUserMetadata(),
|
||||
transform(
|
||||
client.getSpotInstanceServices().requestSpotInstancesInRegion(region, spotPrice, count, spec,
|
||||
options), spotConverter), region);
|
||||
} else {
|
||||
return super.createNodesInRegionAndZone(region, zone, count, template, instanceOptions);
|
||||
return addTagsToInstancesInRegion(template.getOptions().getUserMetadata(),
|
||||
super.createNodesInRegionAndZone(region, zone, count, template, instanceOptions), region);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Iterable<? extends RunningInstance> addTagsToInstancesInRegion(Map<String, String> metadata,
|
||||
Iterable<? extends RunningInstance> iterable, String region) {
|
||||
if (metadata.size() > 0) {
|
||||
client.getTagServices().createTagsInRegion(region,
|
||||
transform(iterable, new Function<RunningInstance, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(RunningInstance arg0) {
|
||||
return arg0.getId();
|
||||
}
|
||||
|
||||
}), metadata);
|
||||
}
|
||||
return iterable;
|
||||
}
|
||||
|
||||
private Float getSpotPriceOrNull(TemplateOptions options) {
|
||||
return options instanceof AWSEC2TemplateOptions ? AWSEC2TemplateOptions.class.cast(options).getSpotPrice() : null;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,18 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
private String spotInstanceRequestId;
|
||||
private String vpcId;
|
||||
private Map<String, String> securityGroupIdToNames = Maps.newLinkedHashMap();
|
||||
private Map<String, String> tags = Maps.newLinkedHashMap();
|
||||
|
||||
public Builder tags(Map<String, String> tags) {
|
||||
this.tags = ImmutableMap.copyOf(checkNotNull(tags, "tags"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tag(String key, String value) {
|
||||
if (key != null && value != null)
|
||||
this.tags.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder securityGroupIdToNames(Map<String, String> securityGroupIdToNames) {
|
||||
this.securityGroupIdToNames = ImmutableMap.copyOf(checkNotNull(securityGroupIdToNames,
|
||||
|
@ -231,7 +243,7 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone,
|
||||
virtualizationType, platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType,
|
||||
rootDeviceName, ebsBlockDevices, monitoringState, placementGroup, productCodes, subnetId,
|
||||
spotInstanceRequestId, vpcId);
|
||||
spotInstanceRequestId, vpcId, tags);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -247,6 +259,7 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
@Nullable
|
||||
private final String vpcId;
|
||||
private final Map<String, String> securityGroupIdToNames;
|
||||
private final Map<String, String> tags;
|
||||
|
||||
protected AWSRunningInstance(String region, Map<String, String> securityGroupIdToNames, String amiLaunchIndex,
|
||||
String dnsName, String imageId, String instanceId, InstanceState instanceState, String instanceType,
|
||||
|
@ -254,7 +267,7 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
String virtualizationType, String platform, String privateDnsName, String privateIpAddress, String ramdiskId,
|
||||
String reason, RootDeviceType rootDeviceType, String rootDeviceName, Map<String, BlockDevice> ebsBlockDevices,
|
||||
MonitoringState monitoringState, String placementGroup, Iterable<String> productCodes, String subnetId,
|
||||
String spotInstanceRequestId, String vpcId) {
|
||||
String spotInstanceRequestId, String vpcId, Map<String, String> tags) {
|
||||
super(region, securityGroupIdToNames.values(), amiLaunchIndex, dnsName, imageId, instanceId, instanceState,
|
||||
instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone, virtualizationType, platform,
|
||||
privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, ebsBlockDevices);
|
||||
|
@ -266,6 +279,7 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
this.vpcId = vpcId;
|
||||
this.securityGroupIdToNames = ImmutableMap.<String, String> copyOf(checkNotNull(securityGroupIdToNames,
|
||||
"securityGroupIdToNames"));
|
||||
this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags"));
|
||||
}
|
||||
|
||||
public Map<String, String> getSecurityGroupIdToNames() {
|
||||
|
@ -317,6 +331,13 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
return subnetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* tags that are present in the instance
|
||||
*/
|
||||
public Map<String, String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
@ -326,6 +347,7 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode());
|
||||
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
|
||||
result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode());
|
||||
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -363,6 +385,11 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
return false;
|
||||
} else if (!vpcId.equals(other.vpcId))
|
||||
return false;
|
||||
if (tags == null) {
|
||||
if (other.tags != null)
|
||||
return false;
|
||||
} else if (!tags.equals(other.tags))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -375,7 +402,8 @@ public class AWSRunningInstance extends RunningInstance {
|
|||
+ ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName=" + rootDeviceName
|
||||
+ ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + ", monitoringState="
|
||||
+ monitoringState + ", placementGroup=" + placementGroup + ", productCodes=" + productCodes
|
||||
+ ", spotInstanceRequestId=" + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId + "]";
|
||||
+ ", spotInstanceRequestId=" + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId
|
||||
+ ", tags=" + tags + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,12 +18,16 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -51,6 +55,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
private Type type;
|
||||
private Date validFrom;
|
||||
private Date validUntil;
|
||||
private Map<String, String> tags = Maps.newLinkedHashMap();
|
||||
|
||||
public Builder clear() {
|
||||
this.region = null;
|
||||
|
@ -69,6 +74,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
this.type = null;
|
||||
this.validFrom = null;
|
||||
this.validUntil = null;
|
||||
tags = Maps.newLinkedHashMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -77,6 +83,16 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder tags(Map<String, String> tags) {
|
||||
this.tags = ImmutableMap.copyOf(checkNotNull(tags, "tags"));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder tag(String key, String value) {
|
||||
if (key != null && value != null)
|
||||
this.tags.put(key, value);
|
||||
return this;
|
||||
}
|
||||
public Builder availabilityZoneGroup(String availabilityZoneGroup) {
|
||||
this.availabilityZoneGroup = availabilityZoneGroup;
|
||||
return this;
|
||||
|
@ -155,7 +171,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
public SpotInstanceRequest build() {
|
||||
return new SpotInstanceRequest(region, availabilityZoneGroup, launchedAvailabilityZone, createTime, faultCode,
|
||||
faultMessage, instanceId, launchGroup, launchSpecification, productDescription, id, spotPrice, state,
|
||||
type, validFrom, validUntil);
|
||||
type, validFrom, validUntil, tags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,11 +233,12 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
private final Type type;
|
||||
private final Date validFrom;
|
||||
private final Date validUntil;
|
||||
private final Map<String, String> tags;
|
||||
|
||||
public SpotInstanceRequest(String region, String availabilityZoneGroup, @Nullable String launchedAvailabilityZone,
|
||||
Date createTime, String faultCode, String faultMessage, String instanceId, String launchGroup,
|
||||
LaunchSpecification launchSpecification, String productDescription, String id, float spotPrice, State state,
|
||||
Type type, Date validFrom, Date validUntil) {
|
||||
Type type, Date validFrom, Date validUntil, Map<String, String> tags) {
|
||||
this.region = checkNotNull(region, "region");
|
||||
this.availabilityZoneGroup = availabilityZoneGroup;
|
||||
this.launchedAvailabilityZone = launchedAvailabilityZone;
|
||||
|
@ -238,6 +255,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
this.type = checkNotNull(type, "type");
|
||||
this.validFrom = validFrom;
|
||||
this.validUntil = validUntil;
|
||||
this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -307,6 +325,13 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
return validUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* tags that are present in the instance
|
||||
*/
|
||||
public Map<String, String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
@ -327,6 +352,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((validFrom == null) ? 0 : validFrom.hashCode());
|
||||
result = prime * result + ((validUntil == null) ? 0 : validUntil.hashCode());
|
||||
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -410,6 +436,11 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
return false;
|
||||
} else if (!validUntil.equals(other.validUntil))
|
||||
return false;
|
||||
if (tags == null) {
|
||||
if (other.tags != null)
|
||||
return false;
|
||||
} else if (!tags.equals(other.tags))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -420,7 +451,7 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
|||
+ faultMessage + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup + ", launchSpecification="
|
||||
+ launchSpecification + ", productDescription=" + productDescription + ", id=" + id + ", spotPrice="
|
||||
+ spotPrice + ", state=" + state + ", type=" + type + ", validFrom=" + validFrom + ", validUntil="
|
||||
+ validUntil + "]";
|
||||
+ validUntil + ", tags=" + tags + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,6 +45,7 @@ public class SpotInstanceRequestToAWSRunningInstance implements Function<SpotIns
|
|||
builder.instanceId(request.getId());
|
||||
builder.instanceState(InstanceState.PENDING);
|
||||
builder.region(request.getRegion());
|
||||
builder.tags(request.getTags());
|
||||
LaunchSpecification spec = request.getLaunchSpecification();
|
||||
builder.availabilityZone(spec.getAvailabilityZone());
|
||||
// TODO convert
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.util;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -34,10 +34,7 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
public class TagFilters {
|
||||
public static enum FilterName {
|
||||
KEY,
|
||||
RESOURCE_ID,
|
||||
RESOURCE_TYPE,
|
||||
VALUE;
|
||||
KEY, RESOURCE_ID, RESOURCE_TYPE, VALUE;
|
||||
|
||||
public String value() {
|
||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
|
||||
|
@ -58,22 +55,7 @@ public class TagFilters {
|
|||
}
|
||||
|
||||
public static enum ResourceType {
|
||||
CUSTOMER_GATEWAY,
|
||||
DHCP_OPTIONS,
|
||||
IMAGE,
|
||||
INSTANCE,
|
||||
INTERNET_GATEWAY,
|
||||
NETWORK_ACL,
|
||||
RESERVED_INSTANCES,
|
||||
ROUTE_TABLE,
|
||||
SECURITY_GROUP,
|
||||
SNAPSHOT,
|
||||
SPOT_INSTANCES_REQUEST,
|
||||
SUBNET,
|
||||
VOLUME,
|
||||
VPC,
|
||||
VPN_CONNECTION,
|
||||
VPN_GATEWAY;
|
||||
CUSTOMER_GATEWAY, DHCP_OPTIONS, IMAGE, INSTANCE, INTERNET_GATEWAY, NETWORK_ACL, RESERVED_INSTANCES, ROUTE_TABLE, SECURITY_GROUP, SNAPSHOT, SPOT_INSTANCES_REQUEST, SUBNET, VOLUME, VPC, VPN_CONNECTION, VPN_GATEWAY;
|
||||
|
||||
public String value() {
|
||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
|
||||
|
@ -301,7 +283,8 @@ public class TagFilters {
|
|||
|
||||
private void putAll(FilterName key, Iterable<?> values) {
|
||||
if (values == null || Iterables.isEmpty(values)) {
|
||||
// If we add an empty or null set of values, replace the value in the map entirely
|
||||
// If we add an empty or null set of values, replace the value in the
|
||||
// map entirely
|
||||
map.put(key, ImmutableSet.of());
|
||||
} else {
|
||||
// Add the values, to a new set if required
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -27,6 +30,8 @@ import org.jclouds.date.DateService;
|
|||
import org.jclouds.ec2.domain.Reservation;
|
||||
import org.jclouds.ec2.domain.RunningInstance;
|
||||
import org.jclouds.location.Region;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provider;
|
||||
|
@ -42,6 +47,9 @@ import com.google.inject.Provider;
|
|||
public class AWSDescribeInstancesResponseHandler extends
|
||||
BaseAWSReservationHandler<Set<Reservation<? extends RunningInstance>>> {
|
||||
private Set<Reservation<? extends RunningInstance>> reservations = Sets.newLinkedHashSet();
|
||||
private boolean inTagSet;
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
@Inject
|
||||
AWSDescribeInstancesResponseHandler(DateService dateService, @Region String defaultRegion,
|
||||
|
@ -49,6 +57,28 @@ public class AWSDescribeInstancesResponseHandler extends
|
|||
super(dateService, defaultRegion, builderProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
|
||||
super.startElement(uri, localName, qName, attrs);
|
||||
if (equalsOrSuffix(qName, "tagSet")) {
|
||||
inTagSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (equalsOrSuffix(qName, "tagSet")) {
|
||||
inTagSet = false;
|
||||
} else if (inTagSet) {
|
||||
if (equalsOrSuffix(qName, "key")) {
|
||||
key = currentOrNull(currentText);
|
||||
} else if (equalsOrSuffix(qName, "value")) {
|
||||
value = currentOrNull(currentText);
|
||||
}
|
||||
}
|
||||
super.endElement(uri, name, qName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Reservation<? extends RunningInstance>> getResult() {
|
||||
return reservations;
|
||||
|
@ -62,6 +92,10 @@ public class AWSDescribeInstancesResponseHandler extends
|
|||
protected void inItem() {
|
||||
if (endOfReservationItem()) {
|
||||
reservations.add(super.newReservation());
|
||||
} else if (inTagSet) {
|
||||
builder.tag(key, value);
|
||||
key = null;
|
||||
value = null;
|
||||
} else {
|
||||
super.inItem();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.xml;
|
||||
|
||||
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
|
||||
|
@ -40,6 +43,9 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
|||
protected final Builder builder;
|
||||
protected boolean inLaunchSpecification;
|
||||
protected final LaunchSpecificationHandler launchSpecificationHandler;
|
||||
private boolean inTagSet;
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
@Inject
|
||||
public SpotInstanceHandler(DateService dateService, @Region String defaultRegion,
|
||||
|
@ -50,11 +56,6 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
|||
this.builder = builder;
|
||||
}
|
||||
|
||||
protected String currentOrNull() {
|
||||
String returnVal = currentText.toString().trim();
|
||||
return returnVal.equals("") ? null : returnVal;
|
||||
}
|
||||
|
||||
public SpotInstanceRequest getResult() {
|
||||
try {
|
||||
String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null;
|
||||
|
@ -67,52 +68,67 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
|||
}
|
||||
|
||||
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||
if (qName.equals("launchSpecification")) {
|
||||
if (equalsOrSuffix(qName, "launchSpecification")) {
|
||||
inLaunchSpecification = true;
|
||||
} else if (equalsOrSuffix(qName, "tagSet")) {
|
||||
inTagSet = true;
|
||||
}
|
||||
if (inLaunchSpecification)
|
||||
launchSpecificationHandler.startElement(uri, name, qName, attrs);
|
||||
}
|
||||
|
||||
public void endElement(String uri, String name, String qName) {
|
||||
if (equalsOrSuffix(qName, "tagSet")) {
|
||||
inTagSet = false;
|
||||
} else if (inTagSet) {
|
||||
if (equalsOrSuffix(qName, "key")) {
|
||||
key = currentOrNull(currentText);
|
||||
} else if (equalsOrSuffix(qName, "value")) {
|
||||
value = currentOrNull(currentText);
|
||||
}
|
||||
}
|
||||
if (qName.equals("launchSpecification")) {
|
||||
inLaunchSpecification = false;
|
||||
builder.launchSpecification(launchSpecificationHandler.getResult());
|
||||
} else if (qName.equals("item") && inTagSet) {
|
||||
builder.tag(key, value);
|
||||
key = null;
|
||||
value = null;
|
||||
}
|
||||
if (inLaunchSpecification) {
|
||||
launchSpecificationHandler.endElement(uri, name, qName);
|
||||
} else if (qName.equals("spotInstanceRequestId")) {
|
||||
builder.id(currentOrNull());
|
||||
builder.id(currentOrNull(currentText));
|
||||
} else if (qName.equals("instanceId")) {
|
||||
builder.instanceId(currentOrNull());
|
||||
builder.instanceId(currentOrNull(currentText));
|
||||
} else if (qName.equals("launchedAvailabilityZone")) {
|
||||
builder.launchedAvailabilityZone(currentOrNull());
|
||||
builder.launchedAvailabilityZone(currentOrNull(currentText));
|
||||
} else if (qName.equals("availabilityZoneGroup")) {
|
||||
builder.availabilityZoneGroup(currentOrNull());
|
||||
builder.availabilityZoneGroup(currentOrNull(currentText));
|
||||
} else if (qName.equals("launchGroup")) {
|
||||
builder.launchGroup(currentOrNull());
|
||||
builder.launchGroup(currentOrNull(currentText));
|
||||
} else if (qName.equals("code")) {
|
||||
builder.faultCode(currentOrNull());
|
||||
builder.faultCode(currentOrNull(currentText));
|
||||
} else if (qName.equals("message")) {
|
||||
builder.faultMessage(currentOrNull());
|
||||
builder.faultMessage(currentOrNull(currentText));
|
||||
} else if (qName.equals("spotPrice")) {
|
||||
String price = currentOrNull();
|
||||
String price = currentOrNull(currentText);
|
||||
if (price != null)
|
||||
builder.spotPrice(Float.parseFloat(price));
|
||||
} else if (qName.equals("type")) {
|
||||
String type = currentOrNull();
|
||||
String type = currentOrNull(currentText);
|
||||
if (type != null)
|
||||
builder.type(SpotInstanceRequest.Type.fromValue(type));
|
||||
} else if (qName.equals("state")) {
|
||||
String state = currentOrNull();
|
||||
String state = currentOrNull(currentText);
|
||||
if (state != null)
|
||||
builder.state(SpotInstanceRequest.State.fromValue(state));
|
||||
} else if (qName.equals("createTime")) {
|
||||
String createTime = currentOrNull();
|
||||
String createTime = currentOrNull(currentText);
|
||||
if (createTime != null)
|
||||
builder.createTime(dateService.iso8601DateParse(createTime));
|
||||
} else if (qName.equals("productDescription")) {
|
||||
builder.productDescription(currentOrNull());
|
||||
builder.productDescription(currentOrNull(currentText));
|
||||
}
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.jclouds.rest.RestContextFactory;
|
|||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
@ -66,8 +67,15 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
group = "ec2";
|
||||
}
|
||||
|
||||
// aws-ec2 supports userMetadata
|
||||
@Override
|
||||
@Test(enabled = false, dependsOnMethods = "testCompareSizes")
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(userMetadata) : String.format("node userMetadata did not match %s %s",
|
||||
userMetadata, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test(dependsOnMethods = "testCompareSizes")
|
||||
public void testExtendedOptionsAndLogin() throws Exception {
|
||||
AWSSecurityGroupClient securityGroupClient = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getSecurityGroupServices();
|
||||
|
@ -84,6 +92,9 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
|
||||
Date before = new Date();
|
||||
|
||||
ImmutableMap<String, String> userMetadata = ImmutableMap.<String, String> of("Name", group);
|
||||
|
||||
options.userMetadata(userMetadata);
|
||||
options.as(AWSEC2TemplateOptions.class).enableMonitoring();
|
||||
options.as(AWSEC2TemplateOptions.class).spotPrice(0.3f);
|
||||
|
||||
|
@ -113,6 +124,9 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
|
||||
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
||||
NodeMetadata first = Iterables.get(nodes, 0);
|
||||
|
||||
checkUserMetadataInNodeEquals(first, userMetadata);
|
||||
|
||||
assert first.getCredentials() != null : first;
|
||||
assert first.getCredentials().identity != null : first;
|
||||
|
||||
|
@ -159,46 +173,4 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = "testCompareSizes")
|
||||
public void testSubnetId() throws Exception {
|
||||
|
||||
String subnetId = System.getProperty("test.subnetId");
|
||||
if (subnetId == null) {
|
||||
// Skip test and return
|
||||
return;
|
||||
}
|
||||
|
||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||
.getInstanceServices();
|
||||
|
||||
String group = this.group + "g";
|
||||
|
||||
TemplateOptions options = client.templateOptions();
|
||||
|
||||
options.as(AWSEC2TemplateOptions.class).subnetId(subnetId).spotPrice(0.3f);
|
||||
|
||||
String startedId = null;
|
||||
String nodeId = null;
|
||||
try {
|
||||
|
||||
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
||||
|
||||
NodeMetadata first = Iterables.get(nodes, 0);
|
||||
assert first.getCredentials() != null : first;
|
||||
assert first.getCredentials().identity != null : first;
|
||||
|
||||
startedId = Iterables.getOnlyElement(nodes).getProviderId();
|
||||
nodeId = Iterables.getOnlyElement(nodes).getId();
|
||||
|
||||
AWSRunningInstance instance = AWSRunningInstance.class.cast(getInstance(instanceClient, startedId));
|
||||
|
||||
assertEquals(instance.getSubnetId(), subnetId);
|
||||
|
||||
} finally {
|
||||
if (nodeId != null)
|
||||
client.destroyNode(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class AWSRunningInstanceToNodeMetadataTest {
|
|||
"/dev/sda1",
|
||||
new BlockDevice("vol-5829fc32", Attachment.Status.ATTACHED, dateService
|
||||
.iso8601DateParse("2011-08-16T13:41:19.000Z"), true))
|
||||
.virtualizationType("paravirtual").build(),//
|
||||
.virtualizationType("paravirtual").tag("Name", "foo").build(),//
|
||||
new AWSRunningInstance.Builder().region(defaultRegion).instanceId("i-931444f2").imageId("ami-63be790a")
|
||||
.instanceState(InstanceState.RUNNING).privateDnsName("ip-10-212-185-8.ec2.internal").dnsName(
|
||||
"ec2-50-19-207-248.compute-1.amazonaws.com").keyName(
|
||||
|
@ -107,10 +107,12 @@ public class AWSRunningInstanceToNodeMetadataTest {
|
|||
.iso8601DateParse("2011-08-16T13:41:19.000Z"), true)).virtualizationType(
|
||||
"paravirtual").build());
|
||||
|
||||
assertEquals(parser.apply(Iterables.get(contents, 0)), new NodeMetadataBuilder().state(NodeState.RUNNING).group(
|
||||
"zkclustertest").hostname("ip-10-212-81-7").privateAddresses(ImmutableSet.of("10.212.81.7"))
|
||||
.publicAddresses(ImmutableSet.of("174.129.173.155")).imageId("us-east-1/ami-63be790a").id(
|
||||
"us-east-1/i-911444f0").providerId("i-911444f0").build());
|
||||
assertEquals(
|
||||
parser.apply(Iterables.get(contents, 0)).toString(),
|
||||
new NodeMetadataBuilder().state(NodeState.RUNNING).group("zkclustertest").hostname("ip-10-212-81-7")
|
||||
.privateAddresses(ImmutableSet.of("10.212.81.7")).publicAddresses(ImmutableSet.of("174.129.173.155"))
|
||||
.imageId("us-east-1/ami-63be790a").id("us-east-1/i-911444f0").providerId("i-911444f0")
|
||||
.userMetadata(ImmutableMap.of("Name", "foo")).build().toString());
|
||||
assertEquals(parser.apply(Iterables.get(contents, 1)), new NodeMetadataBuilder().state(NodeState.RUNNING).group(
|
||||
"zkclustertest").hostname("ip-10-212-185-8").privateAddresses(ImmutableSet.of("10.212.185.8"))
|
||||
.publicAddresses(ImmutableSet.of("50.19.207.248")).imageId("us-east-1/ami-63be790a").id(
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.jclouds.aws.ec2.domain.AWSRunningInstance;
|
|||
import org.jclouds.aws.ec2.domain.LaunchSpecification;
|
||||
import org.jclouds.aws.ec2.domain.MonitoringState;
|
||||
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
|
||||
import org.jclouds.aws.ec2.functions.SpotInstanceRequestToAWSRunningInstance;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.ec2.domain.InstanceState;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -34,40 +33,51 @@ import org.testng.annotations.Test;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||
// NOTE:without testName, this will not call @Before* and fail w/NPE during
|
||||
// surefire
|
||||
@Test(groups = "unit", testName = "SpotInstanceRequestToAWSRunningInstanceTest")
|
||||
public class SpotInstanceRequestToAWSRunningInstanceTest {
|
||||
|
||||
public void testConvert() {
|
||||
|
||||
SpotInstanceRequest input = SpotInstanceRequest.builder().region("us-east-1").id("sir-228e6406")
|
||||
.spotPrice(0.001f).type(SpotInstanceRequest.Type.ONE_TIME).state(SpotInstanceRequest.State.OPEN)
|
||||
SpotInstanceRequest input = SpotInstanceRequest
|
||||
.builder()
|
||||
.region("us-east-1")
|
||||
.id("sir-228e6406")
|
||||
.spotPrice(0.001f)
|
||||
.type(SpotInstanceRequest.Type.ONE_TIME)
|
||||
.state(SpotInstanceRequest.State.OPEN)
|
||||
.launchSpecification(
|
||||
LaunchSpecification.builder().imageId("ami-595a0a1c").securityGroupName("default").instanceType(
|
||||
"m1.large").mapNewVolumeToDevice("/dev/sda1", 1, true).mapEBSSnapshotToDevice(
|
||||
"/dev/sda2", "snap-1ea27576", 1, true).mapEphemeralDeviceToDevice("/dev/sda3", "vre1")
|
||||
.monitoringEnabled(false).build()).createTime(
|
||||
new SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
|
||||
.productDescription("Linux/UNIX").build();
|
||||
LaunchSpecification.builder().imageId("ami-595a0a1c").securityGroupName("default")
|
||||
.instanceType("m1.large").mapNewVolumeToDevice("/dev/sda1", 1, true)
|
||||
.mapEBSSnapshotToDevice("/dev/sda2", "snap-1ea27576", 1, true)
|
||||
.mapEphemeralDeviceToDevice("/dev/sda3", "vre1").monitoringEnabled(false).build())
|
||||
.createTime(new SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
|
||||
.productDescription("Linux/UNIX").tag("foo", "bar").build();
|
||||
|
||||
assertEquals(new SpotInstanceRequestToAWSRunningInstance().apply(input), AWSRunningInstance.builder().region(
|
||||
"us-east-1").instanceId("sir-228e6406").spotInstanceRequestId("sir-228e6406").instanceState(
|
||||
InstanceState.PENDING).imageId("ami-595a0a1c").groupId("default").instanceType("m1.large")
|
||||
assertEquals(
|
||||
new SpotInstanceRequestToAWSRunningInstance().apply(input),
|
||||
AWSRunningInstance.builder().region("us-east-1").instanceId("sir-228e6406")
|
||||
.spotInstanceRequestId("sir-228e6406").instanceState(InstanceState.PENDING).imageId("ami-595a0a1c")
|
||||
.groupId("default").instanceType("m1.large").tag("foo", "bar")
|
||||
.monitoringState(MonitoringState.PENDING).build());
|
||||
}
|
||||
|
||||
public void testConvertWhenNotOpenReturnsNull() {
|
||||
|
||||
assertEquals(new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder()
|
||||
.region("us-east-1").id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME).state(
|
||||
SpotInstanceRequest.State.ACTIVE).build()), null);
|
||||
assertEquals(
|
||||
new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder().region("us-east-1")
|
||||
.id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME).state(SpotInstanceRequest.State.ACTIVE)
|
||||
.build()), null);
|
||||
|
||||
assertEquals(new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder()
|
||||
.region("us-east-1").id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME).state(
|
||||
SpotInstanceRequest.State.CANCELLED).build()), null);
|
||||
assertEquals(
|
||||
new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder().region("us-east-1")
|
||||
.id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME)
|
||||
.state(SpotInstanceRequest.State.CANCELLED).build()), null);
|
||||
|
||||
assertEquals(new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder()
|
||||
.region("us-east-1").id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME).state(
|
||||
SpotInstanceRequest.State.UNRECOGNIZED).build()), null);
|
||||
assertEquals(
|
||||
new SpotInstanceRequestToAWSRunningInstance().apply(SpotInstanceRequest.builder().region("us-east-1")
|
||||
.id("sir-228e6406").type(SpotInstanceRequest.Type.ONE_TIME)
|
||||
.state(SpotInstanceRequest.State.UNRECOGNIZED).build()), null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.services;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import static org.testng.Assert.*;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
@ -53,7 +54,7 @@ import com.google.inject.Module;
|
|||
*
|
||||
* @author grkvlt@apache.org
|
||||
*/
|
||||
@Test(groups = "live", sequential = true)
|
||||
@Test(groups = "live", singleThreaded = true)
|
||||
public class TagClientLiveTest {
|
||||
|
||||
private TagClient client;
|
||||
|
|
|
@ -90,39 +90,56 @@ public class AWSDescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest
|
|||
|
||||
Set<Reservation<AWSRunningInstance>> contents = ImmutableSet.of(new Reservation<AWSRunningInstance>(
|
||||
defaultRegion, ImmutableSet.of("jclouds#ec2-s#us-east-1"), ImmutableSet.of(
|
||||
new AWSRunningInstance.Builder().region(defaultRegion).instanceId("i-911444f0").imageId(
|
||||
"ami-63be790a").instanceState(InstanceState.RUNNING).privateDnsName(
|
||||
"ip-10-212-81-7.ec2.internal").dnsName("ec2-174-129-173-155.compute-1.amazonaws.com")
|
||||
.keyName("jclouds#zkclustertest#us-east-1#23").amiLaunchIndex("0").instanceType(
|
||||
"t1.micro").launchTime(
|
||||
dateService.iso8601DateParse("2011-08-16T13:40:50.000Z")).availabilityZone(
|
||||
"us-east-1c").kernelId("aki-427d952b").monitoringState(
|
||||
MonitoringState.DISABLED).privateIpAddress("10.212.81.7").ipAddress(
|
||||
"174.129.173.155").securityGroupIdToNames(
|
||||
ImmutableMap.<String, String> of("sg-ef052b86",
|
||||
"jclouds#zkclustertest#us-east-1")).rootDeviceType(
|
||||
RootDeviceType.EBS).rootDeviceName("/dev/sda1").device(
|
||||
new AWSRunningInstance.Builder()
|
||||
.region(defaultRegion)
|
||||
.instanceId("i-911444f0")
|
||||
.imageId("ami-63be790a")
|
||||
.instanceState(InstanceState.RUNNING)
|
||||
.privateDnsName("ip-10-212-81-7.ec2.internal")
|
||||
.dnsName("ec2-174-129-173-155.compute-1.amazonaws.com")
|
||||
.keyName("jclouds#zkclustertest#us-east-1#23")
|
||||
.amiLaunchIndex("0")
|
||||
.instanceType("t1.micro")
|
||||
.launchTime(dateService.iso8601DateParse("2011-08-16T13:40:50.000Z"))
|
||||
.availabilityZone("us-east-1c")
|
||||
.kernelId("aki-427d952b")
|
||||
.monitoringState(MonitoringState.DISABLED)
|
||||
.privateIpAddress("10.212.81.7")
|
||||
.ipAddress("174.129.173.155")
|
||||
.securityGroupIdToName("sg-ef052b86", "jclouds#zkclustertest#us-east-1")
|
||||
.tag("Name", "ec2-o")
|
||||
.rootDeviceType(RootDeviceType.EBS)
|
||||
.rootDeviceName("/dev/sda1")
|
||||
.device(
|
||||
"/dev/sda1",
|
||||
new BlockDevice("vol-5829fc32", Attachment.Status.ATTACHED, dateService
|
||||
.iso8601DateParse("2011-08-16T13:41:19.000Z"), true))
|
||||
.virtualizationType("paravirtual").build(),//
|
||||
new AWSRunningInstance.Builder().region(defaultRegion).instanceId("i-931444f2").imageId(
|
||||
"ami-63be790a").instanceState(InstanceState.RUNNING).privateDnsName(
|
||||
"ip-10-212-185-8.ec2.internal").dnsName("ec2-50-19-207-248.compute-1.amazonaws.com")
|
||||
.keyName("jclouds#zkclustertest#us-east-1#23").amiLaunchIndex("0").instanceType(
|
||||
"t1.micro").launchTime(
|
||||
dateService.iso8601DateParse("2011-08-16T13:40:50.000Z")).availabilityZone(
|
||||
"us-east-1c").kernelId("aki-427d952b").monitoringState(
|
||||
MonitoringState.DISABLED).privateIpAddress("10.212.185.8").ipAddress(
|
||||
"50.19.207.248").securityGroupIdToNames(
|
||||
ImmutableMap.<String, String> of("sg-ef052b86",
|
||||
"jclouds#zkclustertest#us-east-1")).rootDeviceType(
|
||||
RootDeviceType.EBS).rootDeviceName("/dev/sda1").device(
|
||||
new AWSRunningInstance.Builder()
|
||||
.region(defaultRegion)
|
||||
.instanceId("i-931444f2")
|
||||
.imageId("ami-63be790a")
|
||||
.instanceState(InstanceState.RUNNING)
|
||||
.privateDnsName("ip-10-212-185-8.ec2.internal")
|
||||
.dnsName("ec2-50-19-207-248.compute-1.amazonaws.com")
|
||||
.keyName("jclouds#zkclustertest#us-east-1#23")
|
||||
.amiLaunchIndex("0")
|
||||
.instanceType("t1.micro")
|
||||
.launchTime(dateService.iso8601DateParse("2011-08-16T13:40:50.000Z"))
|
||||
.availabilityZone("us-east-1c")
|
||||
.kernelId("aki-427d952b")
|
||||
.monitoringState(MonitoringState.DISABLED)
|
||||
.privateIpAddress("10.212.185.8")
|
||||
.ipAddress("50.19.207.248")
|
||||
.securityGroupIdToNames(
|
||||
ImmutableMap.<String, String> of("sg-ef052b86", "jclouds#zkclustertest#us-east-1"))
|
||||
.rootDeviceType(RootDeviceType.EBS)
|
||||
.rootDeviceName("/dev/sda1")
|
||||
.device(
|
||||
"/dev/sda1",
|
||||
new BlockDevice("vol-5029fc3a", Attachment.Status.ATTACHED, dateService
|
||||
.iso8601DateParse("2011-08-16T13:41:19.000Z"), true))
|
||||
.virtualizationType("paravirtual").build()), defaultRegion, defaultRegion,
|
||||
defaultRegion));
|
||||
.virtualizationType("paravirtual").build()), defaultRegion, defaultRegion, defaultRegion));
|
||||
|
||||
Set<Reservation<? extends RunningInstance>> result = parseAWSRunningInstances("/describe_instances_latest.xml");
|
||||
|
||||
|
|
|
@ -108,10 +108,11 @@ public class SpotInstanceHandlerTest extends BaseEC2HandlerTest {
|
|||
.launchedAvailabilityZone("us-east-1b")
|
||||
.launchSpecification(
|
||||
LaunchSpecification.builder().imageId("ami-8e1fece7")
|
||||
.securityGroupIdToName("sg-83e1c4eb", "jclouds#adriancole-ec2unssh#us-east-1").instanceType("t1.micro")
|
||||
.monitoringEnabled(false).keyName("jclouds#adriancole-ec2unssh").build())
|
||||
.securityGroupIdToName("sg-83e1c4eb", "jclouds#adriancole-ec2unssh#us-east-1")
|
||||
.instanceType("t1.micro").monitoringEnabled(false).keyName("jclouds#adriancole-ec2unssh")
|
||||
.build())
|
||||
.createTime(new SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
|
||||
.productDescription("Linux/UNIX").build();
|
||||
.productDescription("Linux/UNIX").tag("Name", "ec2-o").build();
|
||||
SpotInstanceHandler handler = injector.getInstance(SpotInstanceHandler.class);
|
||||
addDefaultRegionToHandler(handler);
|
||||
SpotInstanceRequest result = factory.create(handler).parse(is);
|
||||
|
|
|
@ -61,6 +61,12 @@
|
|||
<virtualizationType>paravirtual</virtualizationType>
|
||||
<clientToken/>
|
||||
<hypervisor>xen</hypervisor>
|
||||
<tagSet>
|
||||
<item>
|
||||
<key>Name</key>
|
||||
<value>ec2-o</value>
|
||||
</item>
|
||||
</tagSet>
|
||||
</item>
|
||||
<item>
|
||||
<instanceId>i-931444f2</instanceId>
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
<instanceId>i-ef308e8e</instanceId>
|
||||
<createTime>2011-07-29T05:27:39.000Z</createTime>
|
||||
<productDescription>Linux/UNIX</productDescription>
|
||||
<tagSet>
|
||||
<item>
|
||||
<key>Name</key>
|
||||
<value>ec2-o</value>
|
||||
</item>
|
||||
</tagSet>
|
||||
<launchedAvailabilityZone>us-east-1b</launchedAvailabilityZone>
|
||||
</item>
|
||||
</spotInstanceRequestSet>
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.testng.annotations.Test;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true, testName = "CloudServersUSComputeServiceLiveTest")
|
||||
@Test(groups = "live", singleThreaded = true, testName = "CloudServersUSComputeServiceLiveTest")
|
||||
public class CloudServersUSComputeServiceLiveTest extends CloudServersComputeServiceLiveTest {
|
||||
|
||||
public CloudServersUSComputeServiceLiveTest() {
|
||||
|
|
|
@ -18,20 +18,24 @@
|
|||
*/
|
||||
package org.jclouds.gogrid.compute.options;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
|
||||
/**
|
||||
* Contains options supported by the {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)}
|
||||
* and {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)} operations on
|
||||
* the <em>gogrid</em> provider.
|
||||
* Contains options supported by the
|
||||
* {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and
|
||||
* {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)}
|
||||
* operations on the <em>gogrid</em> 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):
|
||||
* <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>
|
||||
*
|
||||
* <pre>
|
||||
* import static org.jclouds.compute.options.GoGridTemplateOptions.Builder.*;
|
||||
* ComputeService client = // get connection
|
||||
|
@ -109,11 +113,19 @@ public class GoGridTemplateOptions extends TemplateOptions implements Cloneable
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static GoGridTemplateOptions withMetadata() {
|
||||
public static GoGridTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
GoGridTemplateOptions options = new GoGridTemplateOptions();
|
||||
return GoGridTemplateOptions.class.cast(options.withMetadata());
|
||||
return GoGridTemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static GoGridTemplateOptions userMetadata(String key, String value) {
|
||||
GoGridTemplateOptions options = new GoGridTemplateOptions();
|
||||
return GoGridTemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,10 +199,18 @@ public class GoGridTemplateOptions extends TemplateOptions implements Cloneable
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public GoGridTemplateOptions withMetadata() {
|
||||
return GoGridTemplateOptions.class.cast(super.withMetadata());
|
||||
public GoGridTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return GoGridTemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public GoGridTemplateOptions userMetadata(String key, String value) {
|
||||
return GoGridTemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.rest.RestContext;
|
|||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -56,6 +57,13 @@ public class GoGridComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// gogrid does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
|
||||
// hostname is not predictable based on node metadata
|
||||
}
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
package org.jclouds.rimuhosting.miro.compute;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
|
@ -38,6 +41,13 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes
|
|||
group = "rimuhosting.jclouds";
|
||||
}
|
||||
|
||||
// rimuhosting does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JschSshClientModule getSshModule() {
|
||||
return new JschSshClientModule();
|
||||
|
|
|
@ -22,14 +22,18 @@ import java.util.Properties;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Takes a long time to list nodes. Average response time is about 10-15 seconds per vm.
|
||||
* Hence this test does not complete and is disabled until performance improves.
|
||||
* Takes a long time to list nodes. Average response time is about 10-15 seconds
|
||||
* per vm. Hence this test does not complete and is disabled until performance
|
||||
* improves.
|
||||
*
|
||||
* @author Kedar Dave
|
||||
*
|
||||
*/
|
||||
|
@ -45,6 +49,14 @@ public class VPDCComputeServiceLiveTestDisabled extends BaseComputeServiceLiveTe
|
|||
group = "savvis-symphonyvpdc";
|
||||
}
|
||||
|
||||
// savvis does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = super.setupProperties();
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
package org.jclouds.slicehost.compute;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* Generally disabled, as it incurs higher fees.
|
||||
|
@ -39,6 +42,12 @@ public class SlicehostComputeServiceLiveTest extends BaseComputeServiceLiveTest
|
|||
return new SshjSshClientModule();
|
||||
}
|
||||
|
||||
// slicehost does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||
public void testSuspendResume() throws Exception {
|
||||
super.testSuspendResume();
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.jclouds.softlayer.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.io.Payload;
|
||||
|
@ -31,12 +33,13 @@ import com.google.common.net.InternetDomainName;
|
|||
/**
|
||||
* Contains options supported by the
|
||||
* {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and
|
||||
* {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)} operations on the
|
||||
* <em>gogrid</em> provider.
|
||||
* {@link ComputeService#runNodesWithTag(String, int, TemplateOptions)}
|
||||
* operations on the <em>gogrid</em> provider.
|
||||
*
|
||||
* <h2>Usage</h2> The recommended way to instantiate a {@link SoftLayerTemplateOptions} object is to
|
||||
* statically import {@code SoftLayerTemplateOptions.*} and invoke a static creation method followed
|
||||
* by an instance mutator (if needed):
|
||||
* <h2>Usage</h2> The recommended way to instantiate a
|
||||
* {@link SoftLayerTemplateOptions} object is to statically import
|
||||
* {@code SoftLayerTemplateOptions.*} and invoke a static creation method
|
||||
* followed by an instance mutator (if needed):
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
|
@ -69,8 +72,8 @@ public class SoftLayerTemplateOptions extends TemplateOptions implements Cloneab
|
|||
}
|
||||
|
||||
/**
|
||||
* will replace the default domain used when ordering virtual guests. Note this needs to contain
|
||||
* a public suffix!
|
||||
* will replace the default domain used when ordering virtual guests. Note
|
||||
* this needs to contain a public suffix!
|
||||
*
|
||||
* @see VirtualGuestClient#orderVirtualGuest
|
||||
* @see InternetDomainName#hasPublicSuffix
|
||||
|
@ -144,11 +147,19 @@ public class SoftLayerTemplateOptions extends TemplateOptions implements Cloneab
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
* @see TemplateOptions#userMetadata(Map)
|
||||
*/
|
||||
public static SoftLayerTemplateOptions withMetadata() {
|
||||
public static SoftLayerTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.withMetadata());
|
||||
return SoftLayerTemplateOptions.class.cast(options.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#userMetadata(String, String)
|
||||
*/
|
||||
public static SoftLayerTemplateOptions userMetadata(String key, String value) {
|
||||
SoftLayerTemplateOptions options = new SoftLayerTemplateOptions();
|
||||
return SoftLayerTemplateOptions.class.cast(options.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,10 +233,18 @@ public class SoftLayerTemplateOptions extends TemplateOptions implements Cloneab
|
|||
}
|
||||
|
||||
/**
|
||||
* @see TemplateOptions#withMetadata()
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions withMetadata() {
|
||||
return SoftLayerTemplateOptions.class.cast(super.withMetadata());
|
||||
public SoftLayerTemplateOptions userMetadata(Map<String, String> userMetadata) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.userMetadata(userMetadata));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SoftLayerTemplateOptions userMetadata(String key, String value) {
|
||||
return SoftLayerTemplateOptions.class.cast(super.userMetadata(key, value));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.jclouds.trmk.vcloud_0_8.domain.VApp;
|
|||
import org.jclouds.trmk.vcloud_0_8.reference.VCloudConstants;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
|
@ -66,6 +67,13 @@ public class TerremarkECloudComputeServiceLiveTest extends BaseComputeServiceLiv
|
|||
group = "te";
|
||||
}
|
||||
|
||||
// terremark does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
Template template = super.buildTemplate(templateBuilder);
|
||||
|
|
|
@ -35,12 +35,14 @@ import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
|
|||
import org.jclouds.trmk.vcloud_0_8.domain.VApp;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true)
|
||||
@Test(groups = "live", enabled = true, singleThreaded = true)
|
||||
public class TerremarkVCloudExpressComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
public TerremarkVCloudExpressComputeServiceLiveTest() {
|
||||
provider = "trmk-vcloudexpress";
|
||||
|
@ -60,6 +62,13 @@ public class TerremarkVCloudExpressComputeServiceLiveTest extends BaseComputeSer
|
|||
return template;
|
||||
}
|
||||
|
||||
// terremark does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testListImages() throws Exception {
|
||||
for (Image image : client.listImages()) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Properties;
|
|||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
@ -32,10 +33,12 @@ import org.jclouds.servermanager.ServerManager;
|
|||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true)
|
||||
@Test(groups = "live", enabled = true, singleThreaded = true)
|
||||
public class ServerManagerComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
public ServerManagerComputeServiceLiveTest() {
|
||||
provider = "servermanager";
|
||||
|
@ -66,6 +69,13 @@ public class ServerManagerComputeServiceLiveTest extends BaseComputeServiceLiveT
|
|||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
// servermanager does not support metadata
|
||||
@Override
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assert node.getUserMetadata().equals(ImmutableMap.<String, String> of()) : String.format(
|
||||
"node userMetadata did not match %s %s", userMetadata, node);
|
||||
}
|
||||
|
||||
public void testAssignability() throws Exception {
|
||||
@SuppressWarnings("unused")
|
||||
RestContext<ServerManager, ServerManager> goGridContext = new ComputeServiceContextFactory().createContext(
|
||||
|
|
Loading…
Reference in New Issue