Author: kve
Date: Fri Sep 16 11:28:07 2011
New Revision: 1171511
URL: http://svn.apache.org/viewvc?rev=1171511&view=rev
Log:
WHIRR-371. Allow defining additional firewall rules
Modified:
whirr/trunk/CHANGES.txt
whirr/trunk/core/src/main/java/org/apache/whirr/ClusterSpec.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
whirr/trunk/core/src/main/java/org/apache/whirr/service/FirewallManager.java
whirr/trunk/core/src/test/java/org/apache/whirr/ClusterSpecTest.java
whirr/trunk/src/site/xdoc/configuration-guide.xml
Modified: whirr/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/whirr/trunk/CHANGES.txt?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
--- whirr/trunk/CHANGES.txt (original)
+++ whirr/trunk/CHANGES.txt Fri Sep 16 11:28:07 2011
@@ -16,6 +16,8 @@ Trunk (unreleased changes)
WHIRR-357. Run elasticsearch as a non-root-user (asavu)
+ WHIRR-371. Allow defining additional firewall rules (kve)
+
BUG FIXES
WHIRR-377. Fix broken CLI logging config. (asavu via tomwhite)
Modified: whirr/trunk/core/src/main/java/org/apache/whirr/ClusterSpec.java
URL:
http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/ClusterSpec.java?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
--- whirr/trunk/core/src/main/java/org/apache/whirr/ClusterSpec.java (original)
+++ whirr/trunk/core/src/main/java/org/apache/whirr/ClusterSpec.java Fri Sep 16
11:28:07 2011
@@ -22,22 +22,16 @@ import static com.google.common.base.Pre
import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.whirr.util.KeyPair.sameKeyPair;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
-import com.jcraft.jsch.KeyPair;
-
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
@@ -51,6 +45,16 @@ import org.jclouds.predicates.validators
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.KeyPair;
+
/**
* This class represents the specification of a cluster. It is used to describe
* the properties of a cluster before it is launched.
@@ -159,6 +163,12 @@ public class ClusterSpec {
CLIENT_CIDRS(String.class, true, "A comma-separated list of CIDR" +
" blocks. E.g. 208.128.0.0/11,108.128.0.0/11"),
+ FIREWALL_RULES(String.class, true, "A comma-separated list of port" +
+ " numbers. E.g. 8080,8181"),
+
+ FIREWALL_RULES_ROLE(String.class, true, "A comma-separated list of port" +
+ " numbers. E.g. 8080,8181. Replace 'role' with an actual role name"),
+
VERSION(String.class, false, ""),
RUN_URL_BASE(String.class, false, "The base URL for forming run " +
@@ -273,6 +283,8 @@ public class ClusterSpec {
private int hardwareMinRam;
private List<String> clientCidrs;
+ private Map<String, List<String>> firewallRules;
+
private String version;
private String runUrlBase;
@@ -331,7 +343,19 @@ public class ClusterSpec {
setLocationId(getString(Property.LOCATION_ID));
setBlobStoreLocationId(getString(Property.BLOBSTORE_LOCATION_ID));
setClientCidrs(getList(Property.CLIENT_CIDRS));
+
+ Map<String, List<String>> fr = new HashMap<String, List<String>>();
+ String firewallPrefix = Property.FIREWALL_RULES.getConfigName();
+ Pattern firewallRuleKeyPattern =
Pattern.compile("^".concat(Pattern.quote(firewallPrefix).concat("(?:-(.+))?$")));
+ for (String key: Iterators.toArray(config.getKeys(), String.class)) {
+ Matcher m = firewallRuleKeyPattern.matcher(key);
+ if (!m.matches()) continue;
+ String role = m.group(1);
+ fr.put(role, config.getList(key));
+ }
+ setFirewallRules(fr);
+
setVersion(getString(Property.VERSION));
setRunUrlBase(getString(Property.RUN_URL_BASE));
}
@@ -592,6 +616,10 @@ public class ClusterSpec {
return clientCidrs;
}
+ public Map<String, List<String>> getFirewallRules() {
+ return firewallRules;
+ }
+
public String getVersion() {
return version;
}
@@ -772,6 +800,10 @@ public class ClusterSpec {
this.clientCidrs = clientCidrs;
}
+ public void setFirewallRules(Map<String,List<String>> firewallRules) {
+ this.firewallRules = firewallRules;
+ }
+
public void setVersion(String version) {
this.version = version;
}
@@ -806,6 +838,18 @@ public class ClusterSpec {
return c;
}
+ public Configuration getConfigurationForKeysMatching(Pattern pattern) {
+ Configuration c = new PropertiesConfiguration();
+ for (@SuppressWarnings("unchecked")
+ Iterator<String> it = config.getKeys(); it.hasNext(); ) {
+ String key = it.next();
+ if (pattern.matcher(key).matches()) {
+ c.setProperty(key, config.getProperty(key));
+ }
+ }
+ return c;
+ }
+
/**
* @return the directory for storing cluster-related files
*/
Modified:
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java
URL:
http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
---
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java
(original)
+++
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ConfigureClusterAction.java
Fri Sep 16 11:28:07 2011
@@ -20,13 +20,8 @@ package org.apache.whirr.actions;
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-
import java.io.IOException;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -38,6 +33,7 @@ import org.apache.whirr.InstanceTemplate
import org.apache.whirr.RolePredicates;
import org.apache.whirr.service.ClusterActionEvent;
import org.apache.whirr.service.ClusterActionHandler;
+import org.apache.whirr.service.FirewallManager.Rule;
import org.apache.whirr.service.jclouds.StatementBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
@@ -50,6 +46,14 @@ import org.jclouds.scriptbuilder.domain.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.primitives.Ints;
+
/**
* A {@link org.apache.whirr.ClusterAction} for running a configuration script
on instances
* in the cluster after it has been bootstrapped.
@@ -72,8 +76,10 @@ public class ConfigureClusterAction exte
@Override
protected void doAction(Map<InstanceTemplate, ClusterActionEvent> eventMap)
throws IOException {
-
+
for (Entry<InstanceTemplate, ClusterActionEvent> entry :
eventMap.entrySet()) {
+ applyFirewallRules(entry.getValue());
+
ClusterSpec clusterSpec = entry.getValue().getClusterSpec();
Cluster cluster = entry.getValue().getCluster();
@@ -175,4 +181,33 @@ public class ConfigureClusterAction exte
}
};
}
+
+ /**
+ * Apply the firewall rules specified via configuration.
+ */
+ private void applyFirewallRules(ClusterActionEvent event) throws IOException
{
+ ClusterSpec clusterSpec = event.getClusterSpec();
+
+ Map<String, List<String>> firewallRules = clusterSpec.getFirewallRules();
+ for (String role: firewallRules.keySet()) {
+ Rule rule = Rule.create();
+
+ if (role == null) {
+ rule.destination(event.getCluster().getInstances());
+ } else {
+ rule.destination(RolePredicates.role(role));
+ }
+
+ List<String> ports = firewallRules.get(role);
+ rule.ports(Ints.toArray(Collections2.transform(ports, new
Function<String,Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return Integer.valueOf(input);
+ }
+ })));
+
+ event.getFirewallManager().addRule(rule);
+ }
+ }
+
}
Modified:
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
URL:
http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
---
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
(original)
+++
whirr/trunk/core/src/main/java/org/apache/whirr/actions/ScriptBasedClusterAction.java
Fri Sep 16 11:28:07 2011
@@ -59,8 +59,8 @@ public abstract class ScriptBasedCluster
for (InstanceTemplate instanceTemplate :
clusterSpec.getInstanceTemplates()) {
StatementBuilder statementBuilder = new StatementBuilder();
- ComputeServiceContext computServiceContext =
getCompute().apply(clusterSpec);
- FirewallManager firewallManager = new
FirewallManager(computServiceContext,
+ ComputeServiceContext computeServiceContext =
getCompute().apply(clusterSpec);
+ FirewallManager firewallManager = new
FirewallManager(computeServiceContext,
clusterSpec, newCluster);
ClusterActionEvent event = new ClusterActionEvent(getAction(),
Modified:
whirr/trunk/core/src/main/java/org/apache/whirr/service/FirewallManager.java
URL:
http://svn.apache.org/viewvc/whirr/trunk/core/src/main/java/org/apache/whirr/service/FirewallManager.java?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
---
whirr/trunk/core/src/main/java/org/apache/whirr/service/FirewallManager.java
(original)
+++
whirr/trunk/core/src/main/java/org/apache/whirr/service/FirewallManager.java
Fri Sep 16 11:28:07 2011
@@ -18,10 +18,6 @@
package org.apache.whirr.service;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
import java.io.IOException;
import java.util.Collections;
import java.util.List;
@@ -35,6 +31,10 @@ import org.jclouds.compute.ComputeServic
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
public class FirewallManager {
public static class Rule {
Modified: whirr/trunk/core/src/test/java/org/apache/whirr/ClusterSpecTest.java
URL:
http://svn.apache.org/viewvc/whirr/trunk/core/src/test/java/org/apache/whirr/ClusterSpecTest.java?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
--- whirr/trunk/core/src/test/java/org/apache/whirr/ClusterSpecTest.java
(original)
+++ whirr/trunk/core/src/test/java/org/apache/whirr/ClusterSpecTest.java Fri
Sep 16 11:28:07 2011
@@ -321,5 +321,18 @@ public class ClusterSpecTest {
assertThat(spec.copy(), is(spec));
assertThat(spec.copy().hashCode(), is(spec.hashCode()));
}
+
+ @Test
+ public void testFirewallRules() throws Exception {
+ PropertiesConfiguration conf = new
PropertiesConfiguration("whirr-core-test.properties");
+ conf.setProperty("whirr.firewall-rules", "8000,8001");
+ conf.setProperty("whirr.firewall-rules-serviceA", "9000,9001");
+ ClusterSpec spec = ClusterSpec.withTemporaryKeys(
+ conf);
+
+ Map<String, List<String>> firewallRules = spec.getFirewallRules();
+
assertThat(firewallRules.get(null).equals(Lists.<String>newArrayList("8000","8001")),
is(true));
+
assertThat(firewallRules.get("serviceA").equals(Lists.<String>newArrayList("9000","9001")),
is(true));
+ }
}
Modified: whirr/trunk/src/site/xdoc/configuration-guide.xml
URL:
http://svn.apache.org/viewvc/whirr/trunk/src/site/xdoc/configuration-guide.xml?rev=1171511&r1=1171510&r2=1171511&view=diff
==============================================================================
--- whirr/trunk/src/site/xdoc/configuration-guide.xml (original)
+++ whirr/trunk/src/site/xdoc/configuration-guide.xml Fri Sep 16 11:28:07 2011
@@ -547,6 +547,26 @@ xsi:schemaLocation="http://maven.apache.
CIDR</a>blocks. E.g.
<tt>208.128.0.0/11,108.128.0.0/11</tt></td>
</tr>
+ <tr valign="top">
+ <td>
+ <tt>whirr.firewall-rules</tt>
+ </td>
+ <td>
+ <tt>--firewall-rules</tt>
+ </td>
+ <td>none</td>
+ <td>A comma-separated list of port numbers to open. E.g.
<tt>8080,8181</tt>.</td>
+ </tr>
+ <tr valign="top">
+ <td>
+ <tt>whirr.firewall-rules-{role}</tt>
+ </td>
+ <td>
+ <tt>--firewall-rules-{role}</tt>
+ </td>
+ <td>none</td>
+ <td>A comma-separated list of port numbers to open on instances with a
specific role. Replace {role} the actual role name. E.g.
<tt>whirr.firewall-rules-hbase-master=10101</tt>.</td>
+ </tr>
</table>
<p>
<a name="cloud-provider-config"></a>