You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/06/13 20:36:57 UTC
[09/16] git commit: Adding security groups to TemplateOptions,
adding listSecurityGroupsForNode to extension, tests, pain.
Adding security groups to TemplateOptions, adding listSecurityGroupsForNode to extension, tests, pain.
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/c4d34570
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/c4d34570
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/c4d34570
Branch: refs/heads/jclouds-101
Commit: c4d34570acd77bdda418c598c05b8f814b218bc0
Parents: 23f24cd
Author: Andrew Bayer <an...@gmail.com>
Authored: Wed Jun 12 15:40:09 2013 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Wed Jun 12 15:40:09 2013 -0700
----------------------------------------------------------------------
.../extensions/SecurityGroupExtension.java | 8 +++
.../compute/options/TemplateOptions.java | 60 +++++++++++++++++++-
.../stub/config/StubComputeServiceAdapter.java | 34 ++++++++++-
.../StubComputeServiceDependenciesModule.java | 19 +++++++
.../extensions/StubSecurityGroupExtension.java | 18 ++++--
.../BaseSecurityGroupExtensionLiveTest.java | 38 +++++++++++++
...ubSecurityGroupExtensionIntegrationTest.java | 14 ++++-
7 files changed, 181 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
index 24e162f..5676561 100644
--- a/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
+++ b/compute/src/main/java/org/jclouds/compute/extensions/SecurityGroupExtension.java
@@ -48,6 +48,14 @@ public interface SecurityGroupExtension {
*/
Set<SecurityGroup> listSecurityGroupsInLocation(Location location);
+
+ /**
+ * List security groups for a given instance given the instance's ID.
+ *
+ * @return The set of @{link SecurityGroup}s for the given instance..
+ */
+ Set<SecurityGroup> listSecurityGroupsForNode(String id);
+
/**
* Create a new @{link SecurityGroup} from the parameters given.
*
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
index 270633a..d17a6cd 100644
--- a/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
+++ b/compute/src/main/java/org/jclouds/compute/options/TemplateOptions.java
@@ -70,6 +70,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
to.inboundPorts(this.getInboundPorts());
if (this.getRunScript() != null)
to.runScript(this.getRunScript());
+ if (this.getGroups().size() > 0)
+ to.securityGroups(this.getGroups());
if (this.getPrivateKey() != null)
to.installPrivateKey(this.getPrivateKey());
if (this.getPublicKey() != null)
@@ -295,6 +297,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
@Override
+ public Set<String> getGroups() {
+ return delegate.getGroups();
+ }
+
+ @Override
+ public TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ throw new IllegalArgumentException("tags are immutable");
+ }
+
+ @Override
+ public TemplateOptions securityGroups(String... securityGroups) {
+ throw new IllegalArgumentException("tags are immutable");
+ }
+
+ @Override
public TemplateOptions userMetadata(Map<String, String> userMetadata) {
throw new IllegalArgumentException("userMetadata is immutable");
}
@@ -321,6 +338,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
protected Set<String> tags = ImmutableSet.of();
+ protected Set<String> securityGroups = ImmutableSet.of();
+
protected String privateKey;
protected String publicKey;
@@ -339,13 +358,13 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return super.equals(that) && equal(this.inboundPorts, that.inboundPorts) && equal(this.script, that.script)
&& equal(this.publicKey, that.publicKey) && equal(this.privateKey, that.privateKey)
&& equal(this.blockUntilRunning, that.blockUntilRunning) && equal(this.tags, that.tags)
- && equal(this.userMetadata, that.userMetadata);
+ && equal(this.securityGroups, that.securityGroups) && equal(this.userMetadata, that.userMetadata);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), inboundPorts, script, publicKey, privateKey, blockUntilRunning, tags,
- userMetadata);
+ securityGroups, userMetadata);
}
@Override
@@ -363,6 +382,8 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
toString.add("blockUntilRunning", blockUntilRunning);
if (tags.size() != 0)
toString.add("tags", tags);
+ if (securityGroups.size() != 0)
+ toString.add("securityGroups", securityGroups);
if (userMetadata.size() != 0)
toString.add("userMetadata", userMetadata);
return toString;
@@ -380,6 +401,10 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
return tags;
}
+ public Set<String> getGroups() {
+ return securityGroups;
+ }
+
public String getPrivateKey() {
return privateKey;
}
@@ -451,6 +476,21 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
/**
+ * assigns the created nodes to these security groups
+ */
+ public TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ this.securityGroups = ImmutableSet.copyOf(checkNotNull(securityGroups, "securityGroups"));
+ return this;
+ }
+
+ /**
+ * @see TemplateOptions#securityGroups(Iterable<String>)
+ */
+ public TemplateOptions securityGroups(String... securityGroups) {
+ return securityGroups(ImmutableSet.copyOf(securityGroups));
+ }
+
+ /**
* Opens the set of ports to public access.
*/
public TemplateOptions inboundPorts(int... ports) {
@@ -522,6 +562,22 @@ public class TemplateOptions extends RunScriptOptions implements Cloneable {
}
/**
+ * @see TemplateOptions#securityGroups
+ */
+ public static TemplateOptions securityGroups(Iterable<String> securityGroups) {
+ TemplateOptions options = new TemplateOptions();
+ return options.securityGroups(securityGroups);
+ }
+
+ /**
+ * @see TemplateOptions#securityGroups
+ */
+ public static TemplateOptions securityGroups(String... securityGroups) {
+ TemplateOptions options = new TemplateOptions();
+ return options.securityGroups(securityGroups);
+ }
+
+ /**
* @see TemplateOptions#blockUntilRunning(boolean)
*/
public static TemplateOptions blockUntilRunning(boolean blockUntilRunning) {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
index 925dc1a..22e7dcf 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java
@@ -41,13 +41,18 @@ import org.jclouds.compute.domain.NodeMetadata.Status;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.location.suppliers.all.JustProvider;
import org.jclouds.rest.ResourceNotFoundException;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
@@ -55,6 +60,7 @@ import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListeningExecutorService;
@@ -66,20 +72,25 @@ import com.google.common.util.concurrent.ListeningExecutorService;
public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter {
private final Supplier<Location> location;
private final ConcurrentMap<String, NodeMetadata> nodes;
+ private final Multimap<String, SecurityGroup> groupsForNodes;
private final ListeningExecutorService ioExecutor;
private final Provider<Integer> idProvider;
+ private final Provider<Integer> groupIdProvider;
private final String publicIpPrefix;
private final String privateIpPrefix;
private final String passwordPrefix;
private final Supplier<Set<? extends Location>> locationSupplier;
private final Map<OsFamily, Map<String, String>> osToVersionMap;
+ private final Optional<SecurityGroupExtension> securityGroupExtension;
@Inject
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor, Supplier<Location> location,
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
- JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap) {
+ JustProvider locationSupplier, Map<OsFamily, Map<String, String>> osToVersionMap,
+ Multimap<String, SecurityGroup> groupsForNodes, @Named("GROUP_ID") Provider<Integer> groupIdProvider,
+ Optional<SecurityGroupExtension> securityGroupExtension) {
this.nodes = nodes;
this.ioExecutor = ioExecutor;
this.location = location;
@@ -89,6 +100,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
this.passwordPrefix = passwordPrefix;
this.locationSupplier = locationSupplier;
this.osToVersionMap = osToVersionMap;
+ this.groupsForNodes = groupsForNodes;
+ this.groupIdProvider = groupIdProvider;
+ this.securityGroupExtension = securityGroupExtension;
}
protected void setStateOnNode(Status status, NodeMetadata node) {
@@ -133,6 +147,22 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
builder.credentials(LoginCredentials.builder().user("root").password(passwordPrefix + id).build());
NodeMetadata node = builder.build();
nodes.put(node.getId(), node);
+
+ if (template.getOptions().getGroups().size() > 0) {
+ final String groupId = Iterables.getFirst(template.getOptions().getGroups(), "0");
+ Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroups(),
+ new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ return input.getId().equals(groupId);
+ }
+ });
+
+ if (secGroup.isPresent()) {
+ groupsForNodes.put(node.getId(), secGroup.get());
+ }
+ }
+
setStateOnNodeAfterDelay(Status.RUNNING, node, 100);
return new NodeWithInitialCredentials(node);
}
@@ -195,6 +225,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
return;
setStateOnNodeAfterDelay(Status.PENDING, node, 0);
setStateOnNodeAfterDelay(Status.TERMINATED, node, 50);
+ groupsForNodes.removeAll(id);
+
ioExecutor.execute(new Runnable() {
@Override
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java
index b6f22cb..0d07bbe 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceDependenciesModule.java
@@ -43,6 +43,8 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
import com.google.common.net.HostAndPort;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -96,6 +98,23 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
return groupBacking.get(creds.get().identity);
}
+ protected static final LoadingCache<String, Multimap<String, SecurityGroup>> groupsForNodeBacking = CacheBuilder.newBuilder()
+ .build(new CacheLoader<String, Multimap<String, SecurityGroup>>() {
+
+ @Override
+ public Multimap<String, SecurityGroup> load(String arg0) throws Exception {
+ return LinkedHashMultimap.create();
+ }
+
+ });
+
+ @Provides
+ @Singleton
+ protected Multimap<String, SecurityGroup> provideGroupsForNode(@Provider Supplier<Credentials> creds)
+ throws ExecutionException {
+ return groupsForNodeBacking.get(creds.get().identity);
+ }
+
protected static final LoadingCache<String, AtomicInteger> nodeIds = CacheBuilder.newBuilder().build(
new CacheLoader<String, AtomicInteger>() {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
index f61cb84..b4c5b06 100644
--- a/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
+++ b/compute/src/main/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtension.java
@@ -55,22 +55,25 @@ import com.google.common.util.concurrent.ListeningExecutorService;
public class StubSecurityGroupExtension implements SecurityGroupExtension {
private final Supplier<Location> location;
- private final Provider<Integer> idProvider;
+ private final Provider<Integer> groupIdProvider;
private final Supplier<Set<? extends Location>> locationSupplier;
private final ListeningExecutorService ioExecutor;
private final ConcurrentMap<String, SecurityGroup> groups;
+ private final Multimap<String, SecurityGroup> groupsForNodes;
@Inject
public StubSecurityGroupExtension(ConcurrentMap<String, SecurityGroup> groups,
@Named(Constants.PROPERTY_IO_WORKER_THREADS) ListeningExecutorService ioExecutor,
Supplier<Location> location,
- @Named("GROUP_ID") Provider<Integer> idProvider,
- JustProvider locationSupplier) {
+ @Named("GROUP_ID") Provider<Integer> groupIdProvider,
+ JustProvider locationSupplier,
+ Multimap<String, SecurityGroup> groupsForNodes) {
this.groups = groups;
this.ioExecutor = ioExecutor;
this.location = location;
- this.idProvider = idProvider;
+ this.groupIdProvider = groupIdProvider;
this.locationSupplier = locationSupplier;
+ this.groupsForNodes = groupsForNodes;
}
@Override
@@ -87,12 +90,17 @@ public class StubSecurityGroupExtension implements SecurityGroupExtension {
}
}));
}
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String nodeId) {
+ return ImmutableSet.copyOf(groupsForNodes.get(nodeId));
+ }
@Override
public SecurityGroup createSecurityGroup(String name, Location location) {
SecurityGroupBuilder builder = new SecurityGroupBuilder();
- String id = idProvider.get() + "";
+ String id = groupIdProvider.get() + "";
builder.ids(id);
builder.name(name);
builder.location(location);
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java b/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
index ebb2a1a..c7fcb22 100644
--- a/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
+++ b/compute/src/test/java/org/jclouds/compute/extensions/internal/BaseSecurityGroupExtensionLiveTest.java
@@ -22,6 +22,7 @@ import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.util.Predicates2.retry;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.Set;
@@ -32,11 +33,14 @@ import javax.inject.Named;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.domain.SecurityGroupBuilder;
import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
+import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
@@ -77,6 +81,8 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
return view.getComputeService().templateBuilder().build();
}
+
+
@Test(groups = { "integration", "live" }, singleThreaded = true)
public void testCreateSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
@@ -207,6 +213,38 @@ public abstract class BaseSecurityGroupExtensionLiveTest extends BaseComputeServ
}
@Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testAddIpPermissionsFromSpec")
+ public void testCreateNodeWithSecurityGroup() throws RunNodesException, InterruptedException, ExecutionException {
+
+ ComputeService computeService = view.getComputeService();
+
+ Optional<SecurityGroupExtension> securityGroupExtension = computeService.getSecurityGroupExtension();
+
+ assertTrue(securityGroupExtension.isPresent(), "security group extension was not present");
+
+ Template template = view.getComputeService().templateBuilder()
+ .options(TemplateOptions.Builder.securityGroups(groupId))
+ .build();
+
+ NodeMetadata node = Iterables.getOnlyElement(computeService.createNodesInGroup("test-create-node-with-group", 1, template));
+
+ Set<SecurityGroup> groups = securityGroupExtension.get().listSecurityGroupsForNode(node.getId());
+
+ assertTrue(groups.size() > 0, "node has no groups");
+
+ Optional<SecurityGroup> secGroup = Iterables.tryFind(securityGroupExtension.get().listSecurityGroupsForNode(node.getId()),
+ new Predicate<SecurityGroup>() {
+ @Override
+ public boolean apply(SecurityGroup input) {
+ return input.getId().equals(groupId);
+ }
+ });
+
+ assertTrue(secGroup.isPresent());
+
+ computeService.destroyNode(node.getId());
+ }
+
+ @Test(groups = { "integration", "live" }, singleThreaded = true, dependsOnMethods = "testCreateNodeWithSecurityGroup")
public void testDeleteSecurityGroup() {
ComputeService computeService = view.getComputeService();
http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/c4d34570/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
----------------------------------------------------------------------
diff --git a/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
index 2266886..8c2b31c 100644
--- a/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
+++ b/compute/src/test/java/org/jclouds/compute/stub/extensions/StubSecurityGroupExtensionIntegrationTest.java
@@ -21,6 +21,7 @@ import static org.jclouds.util.Predicates2.retry;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import java.util.Properties;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
@@ -48,13 +49,22 @@ import com.google.common.collect.Iterables;
/**
* Base test for {@link SecurityGroupExtension} implementations.
*
- * @author David Alves
+ * @author Andrew Bayer
*
*/
-@Test(groups = { "integration", "live" }, testName="StubSecurityGroupExtensionIntegrationTest")
+@Test(groups = { "integration", "live" }, singleThreaded = true, testName="StubSecurityGroupExtensionIntegrationTest")
public class StubSecurityGroupExtensionIntegrationTest extends BaseSecurityGroupExtensionLiveTest {
public StubSecurityGroupExtensionIntegrationTest() {
provider = "stub";
}
+
+ @Override
+ protected Properties setupProperties() {
+ Properties overrides = super.setupProperties();
+ // This is a hack to make sure we get a different set of node IDs, nodes, groups, etc from StubComputeServiceIntegrationTest.
+ overrides.setProperty(provider + ".identity", "sec-stub");
+
+ return overrides;
+ }
}