cloudservers and aws-ec2 work with tags now

This commit is contained in:
Adrian Cole 2012-05-18 19:56:20 -07:00
parent c9096ba460
commit 38bfb906d1
7 changed files with 96 additions and 11 deletions

View File

@ -20,6 +20,7 @@ package org.jclouds.cloudservers.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue;
import java.util.Map;
import java.util.NoSuchElementException;
@ -108,7 +109,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
builder.hostname(from.getName());
builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description(
from.getHostId()).parent(location.get()).build());
builder.userMetadata(from.getMetadata());
addMetadataAndParseTagsFromCommaDelimitedValue(builder, from.getMetadata());
builder.group(parseGroupFromName(from.getName()));
builder.imageId(from.getImageId() + "");
builder.operatingSystem(parseOperatingSystem(from));

View File

@ -21,6 +21,7 @@ package org.jclouds.cloudservers.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata;
import static org.jclouds.cloudservers.options.ListOptions.Builder.withDetails;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -59,11 +60,13 @@ public class CloudServersComputeServiceAdapter implements ComputeServiceAdapter<
Template template) {
Server server = client
.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer.parseInt(template
.getHardware().getProviderId()), withMetadata(template.getOptions().getUserMetadata()));
.getHardware().getProviderId()), withMetadata(metadataAndTagsAsCommaDelimitedValue(template.getOptions())));
return new NodeAndInitialCredentials<Server>(server, server.getId() + "", LoginCredentials.builder().password(
server.getAdminPass()).build());
}
@Override
public Iterable<Flavor> listHardwareProfiles() {

View File

@ -19,12 +19,15 @@
package org.jclouds.compute.util;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
import static com.google.common.base.Throwables.getStackTraceAsString;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.size;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.*;
import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash;
import java.net.URI;
@ -39,10 +42,12 @@ import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.net.IPSocket;
import org.jclouds.rest.Providers;
@ -50,8 +55,12 @@ import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableMap.Builder;
/**
*
@ -200,6 +209,49 @@ public class ComputeServiceUtils {
checkState(size(concat(node.getPublicAddresses(), node.getPrivateAddresses())) > 0,
"node does not have IP addresses configured: " + node);
}
/**
* For cloud apis that have a pattern of using empty strings as tags, return a map that contains
* that.
*/
public static Map<String, String> metadataAndTagsAsValuesOfEmptyString(TemplateOptions options) {
Builder<String, String> builder = ImmutableMap.<String, String> builder();
builder.putAll(options.getUserMetadata());
for (String tag : options.getTags())
builder.put(tag, "");
return builder.build();
}
/**
* @see #metadataAndTagsAsValuesOfEmptyString
*/
public static NodeMetadataBuilder addMetadataAndParseTagsFromValuesOfEmptyString(NodeMetadataBuilder builder,
Map<String, String> map) {
return builder.tags(filterValues(map, equalTo("")).keySet()).userMetadata(filterValues(map, not(equalTo(""))));
}
/**
* For cloud apis that need to namespace tags as the value of the key {@code jclouds.tags}
*/
public static Map<String, String> metadataAndTagsAsCommaDelimitedValue(TemplateOptions options) {
Builder<String, String> builder = ImmutableMap.<String, String> builder();
builder.putAll(options.getUserMetadata());
if (options.getTags().size() > 0)
builder.put("jclouds.tags", Joiner.on(',').join(options.getTags()));
return builder.build();
}
/**
* @see #metadataAndTagsAsCommaDelimitedValue
*/
public static NodeMetadataBuilder addMetadataAndParseTagsFromCommaDelimitedValue(NodeMetadataBuilder builder,
Map<String, String> map) {
String tagString = map.get("jclouds.tags");
if (tagString != null)
builder.tags(Splitter.on(',').split(tagString));
builder.userMetadata(filterKeys(map, not(equalTo("jclouds.tags"))));
return builder;
}
public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, String in,
Map<OsFamily, Map<String, String>> osVersionMap) {

View File

@ -20,6 +20,7 @@ package org.jclouds.compute.util;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import static org.jclouds.compute.util.ComputeServiceUtils.parseVersionOrReturnEmptyString;
import static org.jclouds.compute.util.ComputeServiceUtils.*;
import static org.testng.Assert.assertEquals;
import java.net.URI;
@ -27,13 +28,16 @@ import java.util.Map;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.http.HttpRequest;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
/**
@ -53,6 +57,30 @@ public class ComputeServiceUtilsTest {
assertEquals(parseGroupFromName("gogrid--849"), "gogrid-");
}
@Test
public void testMetadataAndTagsAsValuesOfEmptyString() {
TemplateOptions options = TemplateOptions.Builder.tags(ImmutableSet.of("tag")).userMetadata(ImmutableMap.<String, String>of("foo", "bar"));
assertEquals(metadataAndTagsAsValuesOfEmptyString(options), ImmutableMap.<String, String>of("foo", "bar", "tag", ""));
}
@Test
public void testMetadataAndTagsAsCommaDelimitedValue() {
TemplateOptions options = TemplateOptions.Builder.tags(ImmutableSet.of("tag")).userMetadata(ImmutableMap.<String, String>of("foo", "bar"));
assertEquals(metadataAndTagsAsCommaDelimitedValue(options), ImmutableMap.<String, String>of("foo", "bar", "jclouds.tags", "tag"));
}
@Test
public void testMetadataAndTagsAsValuesOfEmptyStringNoTags() {
TemplateOptions options = TemplateOptions.Builder.userMetadata(ImmutableMap.<String, String>of("foo", "bar"));
assertEquals(metadataAndTagsAsValuesOfEmptyString(options), ImmutableMap.<String, String>of("foo", "bar"));
}
@Test
public void testMetadataAndTagsAsCommaDelimitedValueNoTags() {
TemplateOptions options = TemplateOptions.Builder.userMetadata(ImmutableMap.<String, String>of("foo", "bar"));
assertEquals(metadataAndTagsAsCommaDelimitedValue(options), ImmutableMap.<String, String>of("foo", "bar"));
}
@Test
public void testParseVersionOrReturnEmptyStringUbuntu1004() {
assertEquals(parseVersionOrReturnEmptyString(OsFamily.UBUNTU, "Ubuntu 10.04", map), "10.04");

View File

@ -18,9 +18,7 @@
*/
package org.jclouds.aws.ec2.compute.functions;
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Maps.filterValues;
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromValuesOfEmptyString;
import java.util.Map;
import java.util.Set;
@ -85,8 +83,8 @@ public class AWSRunningInstanceToNodeMetadata extends RunningInstanceToNodeMetad
@Override
protected NodeMetadataBuilder buildInstance(RunningInstance instance, NodeMetadataBuilder builder) {
AWSRunningInstance awsInstance = AWSRunningInstance.class.cast(instance);
Map<String, String> tags = awsInstance.getTags();
return super.buildInstance(instance, builder).name(tags.get("Name")).tags(
filterValues(tags, equalTo("")).keySet()).userMetadata(filterValues(tags, not(equalTo(""))));
builder.name(awsInstance.getTags().get("Name"));
addMetadataAndParseTagsFromValuesOfEmptyString(builder, awsInstance.getTags());
return super.buildInstance(instance, builder);
}
}

View File

@ -21,6 +21,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 static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_GENERATE_INSTANCE_NAMES;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsValuesOfEmptyString;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@ -100,6 +101,7 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT
@Override
protected Iterable<? extends RunningInstance> createNodesInRegionAndZone(String region, String zone, String group,
int count, Template template, RunInstancesOptions instanceOptions) {
Map<String, String> tags = metadataAndTagsAsValuesOfEmptyString(template.getOptions());
Float spotPrice = getSpotPriceOrNull(template.getOptions());
if (spotPrice != null) {
LaunchSpecification spec = AWSRunInstancesOptions.class.cast(instanceOptions).getLaunchSpecificationBuilder()
@ -108,12 +110,11 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT
if (logger.isDebugEnabled())
logger.debug(">> requesting %d spot instances region(%s) price(%f) spec(%s) options(%s)", count, region,
spotPrice, spec, options);
return addTagsToInstancesInRegion(template.getOptions().getUserMetadata(), transform(client
return addTagsToInstancesInRegion(tags, transform(client
.getSpotInstanceServices().requestSpotInstancesInRegion(region, spotPrice, count, spec, options),
spotConverter), region, group);
} else {
return addTagsToInstancesInRegion(template.getOptions().getUserMetadata(), super.createNodesInRegionAndZone(
return addTagsToInstancesInRegion(tags, super.createNodesInRegionAndZone(
region, zone, group, count, template, instanceOptions), region, group);
}

View File

@ -106,6 +106,7 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
Date before = new Date();
ImmutableMap<String, String> userMetadata = ImmutableMap.<String, String> of("Name", group);
ImmutableSet<String> tags = ImmutableSet. of(group);
// note that if you change the location, you must also specify image parameters
Template template = client.templateBuilder().locationId(region).osFamily(AMZN_LINUX).os64Bit(true).build();
@ -142,6 +143,7 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
assertEquals(first.getName(), group);
checkUserMetadataInNodeEquals(first, userMetadata);
checkTagsInNodeEquals(first, tags);
assert first.getCredentials() != null : first;
assert first.getCredentials().identity != null : first;