If group name can't be parsed from a group ID, try the key name

When the security group is not generated by jclouds (e.g. when
using a custom group, or when in a VPC which generally requires
its own security groups), the group name to launch nodes into is
lost, since it is parsed from the generated security group ID.

This patch introduces a very local workaround: try to parse the
name from the key name, which if generated by jclouds has a format
that is very similar to the generated security group ID.

While probably not the ideal solution for persisting the group
name either (using user metadata might be), this fixes a blocking
issue for scenarios where you can't use a generated security group
ID (using a VPC in our case), but you can use a generated key pair
name.

Also it shouldn't interfere with existing usage: if a name can be
parsed from the security group, that is used, and if the key name
is not generated, the behaviour remains as it currently is (group
name is null if it can't be parsed from the security group).
This commit is contained in:
Fabian Steeg 2012-02-29 14:34:09 +01:00
parent 918affff17
commit 474aa52da9
2 changed files with 35 additions and 7 deletions

View File

@ -62,6 +62,7 @@ import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.util.concurrent.UncheckedExecutionException; import com.google.common.util.concurrent.UncheckedExecutionException;
@ -186,21 +187,28 @@ public class RunningInstanceToNodeMetadata implements Function<RunningInstance,
@VisibleForTesting @VisibleForTesting
String getGroupForInstance(final RunningInstance instance) { String getGroupForInstance(final RunningInstance instance) {
String group = parseGroupFrom(instance, instance.getGroupIds());
if(group == null && instance.getKeyName() != null) {
// when not using a generated security group, e.g. in VPC, try from key:
group = parseGroupFrom(instance, Sets.newHashSet(instance.getKeyName()));
}
return group;
}
private String parseGroupFrom(final RunningInstance instance, final Set<String> data) {
String group = null; String group = null;
try { try {
group = Iterables.getOnlyElement(Iterables.filter(instance.getGroupIds(), new Predicate<String>() { group = Iterables.getOnlyElement(Iterables.filter(data, new Predicate<String>() {
@Override @Override
public boolean apply(String input) { public boolean apply(String input) {
return input.startsWith("jclouds#") && input.endsWith("#" + instance.getRegion()); return input.startsWith("jclouds#") && input.contains("#" + instance.getRegion());
} }
})).split("#")[1];
})).substring(8).replaceAll("#" + instance.getRegion() + "$", "");
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
logger.debug("no group parsed from %s's security groups: %s", instance.getId(), instance.getGroupIds()); logger.debug("no group parsed from %s's data: %s", instance.getId(), data);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.debug("too many groups match %s; %s's security groups: %s", "jclouds#", instance.getId(), instance logger.debug("too many groups match %s; %s's data: %s", "jclouds#", instance.getId(), data);
.getGroupIds());
} }
return group; return group;
} }

View File

@ -217,6 +217,20 @@ public class RunningInstanceToNodeMetadataTest {
.hardware(m1_small32().build()).location(provider).build()); .hardware(m1_small32().build()).location(provider).build());
} }
@Test
public void testGroupNameIsSetWhenCustomKeyNameIsSetAndSecurityGroupIsGenerated() {
checkGroupName(RunningInstance.builder().instanceId("id").imageId("image").instanceType("m1.small")
.instanceState(InstanceState.RUNNING).region("us-east-1").keyName("custom-key")
.groupId("jclouds#groupname#us-east-1").build());
}
@Test
public void testGroupNameIsSetWhenCustomSecurityGroupIsSetAndKeyNameIsGenerated() {
checkGroupName(RunningInstance.builder().instanceId("id").imageId("image").instanceType("m1.small")
.instanceState(InstanceState.RUNNING).region("us-east-1").groupId("custom-sec")
.keyName("jclouds#groupname#us-east-1#23").build());
}
protected RunningInstance firstInstanceFromResource(String resource) { protected RunningInstance firstInstanceFromResource(String resource) {
RunningInstance server = Iterables.get(Iterables.get(DescribeInstancesResponseHandlerTest RunningInstance server = Iterables.get(Iterables.get(DescribeInstancesResponseHandlerTest
.parseRunningInstances(resource), 0), 0); .parseRunningInstances(resource), 0), 0);
@ -239,6 +253,12 @@ public class RunningInstanceToNodeMetadataTest {
return createNodeParser(hardware, locations, credentialStore, instanceToNodeState, instanceToImage); return createNodeParser(hardware, locations, credentialStore, instanceToNodeState, instanceToImage);
} }
private void checkGroupName(RunningInstance instance) {
assertEquals("groupname", createNodeParser(ImmutableSet.<Hardware> of(), ImmutableSet
.<Location> of(), ImmutableSet.<Image> of(), ImmutableMap.<String, Credentials> of())
.apply(instance).getGroup());
}
private RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware, private RunningInstanceToNodeMetadata createNodeParser(final ImmutableSet<Hardware> hardware,
final ImmutableSet<Location> locations, Map<String, Credentials> credentialStore, final ImmutableSet<Location> locations, Map<String, Credentials> credentialStore,
Map<InstanceState, NodeState> instanceToNodeState, LoadingCache<RegionAndName, Image> instanceToImage) { Map<InstanceState, NodeState> instanceToNodeState, LoadingCache<RegionAndName, Image> instanceToImage) {