modules/common/cassandra-auth/pom.xml
| 27 +++
modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticator.java
| 78 ++++++++++
modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticatorMBean.java
| 10 +
modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml
| 8 +
modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/cassandra-jvm.properties
| 2
modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/rhq.cassandra.yaml
| 2
modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/CassandraClusterManager.java
| 20 ++
modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
| 28 +++
modules/common/pom.xml
| 1
9 files changed, 174 insertions(+), 2 deletions(-)
New commits:
commit b63c38cb0c19cd062d14c5e025164021f1e946cc
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jul 20 09:53:10 2013 -0400
turn on internode authentication
This enabled internode authentication in cassandra.yaml and the cassandra-auth
module is packaged with our Cassandra distro. The authentication config file is
automatically updated for integrated tests. There is still work to be done for
multi-node dev-container (and production) deployments.
diff --git a/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml
b/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml
index 2bde394..c12c567 100644
--- a/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml
+++ b/modules/common/cassandra-ccm/cassandra-ccm-core/pom.xml
@@ -113,6 +113,11 @@
<artifactId>snappy-java</artifactId>
<version>${cassandra.snappy.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-cassandra-auth</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
<executions>
<execution>
@@ -166,12 +171,15 @@
<delete
file="${cassandra.dir}/lib/snappy-java-1.0.4.1.jar"/>
<copy
file="${settings.localRepository}/org/xerial/snappy/snappy-java/${cassandra.snappy.version}/snappy-java-${cassandra.snappy.version}.jar"
todir="${cassandra.dir}/lib"/>
+ <copy
file="${settings.localRepository}/org/rhq/rhq-cassandra-auth/${project.version}/rhq-cassandra-auth-${project.version}.jar"
+ todir="${cassandra.dir}/lib"/>
<move file="${project.build.outputDirectory}/cassandra/conf"
todir="${cassandra.dir}"/>
<delete file="${cassandra.dir}/bin/cassandra"/>
<move
file="${project.build.outputDirectory}/cassandra/bin/cassandra"
todir="${cassandra.dir}/bin"/>
<delete
dir="${project.build.outputDirectory}/cassandra"/>
<delete dir="${cassandra.dir}/javadoc"/>
<delete file="${cassandra.dir}/conf/cassandra-env.sh"/>
+ <touch
file="${cassandra.dir}/conf/rhq-storage-auth.conf"/>
<zip basedir="${cassandra.dir}"
destfile="${cassandra.distro.zip}"/>
<delete dir="${cassandra.dir}"/>
diff --git
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/cassandra-jvm.properties
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/cassandra-jvm.properties
index 612c65e..1faee9d 100644
---
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/cassandra-jvm.properties
+++
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/cassandra-jvm.properties
@@ -17,9 +17,9 @@ heap_dump_dir=""
thread_stack_size="-Xss180k"
-java_agent=""
# Enable jamm when running on Java 6 patch version 23 or higher.
#java_agent="-javaagent:$CASSANDRA_HOME/lib/jamm-0.2.5.jar"
+java_agent=
# GC tuning options
#
diff --git
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/rhq.cassandra.yaml
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/rhq.cassandra.yaml
index 298db9d..da09e92 100644
---
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/rhq.cassandra.yaml
+++
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/bundle/cassandra/conf/rhq.cassandra.yaml
@@ -323,7 +323,7 @@ listen_address: ${rhq.cassandra.listen.address}
# Internode authentication backend, implementing IInternodeAuthenticator;
# used to allow/disallow connections from peer nodes.
-# internode_authenticator: org.apache.cassandra.auth.AllowAllInternodeAuthenticator
+internode_authenticator: org.rhq.cassandra.auth.RhqInternodeAuthenticator
# Whether to start the native transport server.
# Currently, only the thrift server is started by default because the native
diff --git
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/CassandraClusterManager.java
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/CassandraClusterManager.java
index 338ef3a..edf1430 100644
---
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/CassandraClusterManager.java
+++
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/CassandraClusterManager.java
@@ -30,7 +30,9 @@ import static org.rhq.core.util.StringUtil.collectionToString;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
+import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -50,6 +52,7 @@ import org.rhq.core.system.ProcessExecution;
import org.rhq.core.system.ProcessExecutionResults;
import org.rhq.core.system.SystemInfo;
import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.util.StringUtil;
import org.rhq.core.util.file.FileUtil;
import org.rhq.core.util.stream.StreamUtil;
@@ -138,6 +141,8 @@ public class CassandraClusterManager {
storageNode.setCqlPort(nodeOptions.getNativeTransportPort());
nodes.add(storageNode);
+ updateStorageAuthConf(basedir);
+
installedNodeDirs.add(basedir);
} catch (Exception e) {
log.error("Failed to install node at " + basedir);
@@ -152,6 +157,21 @@ public class CassandraClusterManager {
return nodes;
}
+ private void updateStorageAuthConf(File basedir) {
+ File confDir = new File(basedir, "conf");
+ File authFile = new File(confDir, "rhq-storage-auth.conf");
+ authFile.delete();
+
+ Set<String> addresses =
calculateLocalIPAddresses(deploymentOptions.getNumNodes());
+
+ try {
+ StreamUtil.copy(new StringReader(StringUtil.collectionToString(addresses,
"\n")),
+ new FileWriter(authFile), true);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to update " + authFile);
+ }
+ }
+
private Set<String> calculateLocalIPAddresses(int numNodes) {
Set<String> addresses = new HashSet<String>();
diff --git
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
index b222c82..b01ebe9 100644
---
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
+++
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
@@ -160,11 +160,6 @@ public class Deployer {
return Integer.parseInt(javaVersion.substring(startIndex + 1,
javaVersion.length()));
}
- private boolean isLaterThanJava1_6() {
- String javaVersion = System.getProperty("java.version");
- return javaVersion.compareTo("1.6.0") > 0;
- }
-
public void updateFilePerms() {
File deployDir = new File(deploymentOptions.getBasedir());
File binDir = new File(deployDir, "bin");
commit 890a378fc11b04f3e7af64babfbfd1a7e306b7cd
Author: John Sanda <jsanda(a)redhat.com>
Date: Sat Jul 20 07:56:14 2013 -0400
initial commit for cassandra-auth module
This is the first cut at our IInternodeAuthenticator. It loads IP addresses
from a config file. There is a JMX operation to reload the config file that can
be used after the config file is updated.
diff --git a/modules/common/cassandra-auth/pom.xml
b/modules/common/cassandra-auth/pom.xml
new file mode 100644
index 0000000..c53c752
--- /dev/null
+++ b/modules/common/cassandra-auth/pom.xml
@@ -0,0 +1,27 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-common-parent</artifactId>
+ <version>4.9.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>rhq-cassandra-auth</artifactId>
+ <name>RHQ Cassandra Authentication</name>
+
+ <properties>
+ <moduleName>org.rhq.${project.artifactId}</moduleName>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cassandra</groupId>
+ <artifactId>cassandra-all</artifactId>
+ <version>${cassandra.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git
a/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticator.java
b/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticator.java
new file mode 100644
index 0000000..56980f1
--- /dev/null
+++
b/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticator.java
@@ -0,0 +1,78 @@
+package org.rhq.cassandra.auth;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.cassandra.auth.IInternodeAuthenticator;
+import org.apache.cassandra.exceptions.ConfigurationException;
+
+/**
+ * @author John Sanda
+ */
+public class RhqInternodeAuthenticator implements IInternodeAuthenticator,
RhqInternodeAuthenticatorMBean {
+
+ private final String MBEAN_NAME = "org.rhq.cassandra.auth:type=" +
RhqInternodeAuthenticator.class.getSimpleName();
+
+ private final String CONF_FILE = "rhq-storage-auth.conf";
+
+ private File authConfFile;
+
+ private Set<InetAddress> addresses = new HashSet<InetAddress>();
+
+ public RhqInternodeAuthenticator() {
+ try {
+ authConfFile = new File(getClass().getResource("/" +
CONF_FILE).toURI());
+ if (!authConfFile.exists()) {
+ throw new RuntimeException(authConfFile + " does not exist");
+ }
+
+ reloadConfiguration();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Failed to load " + CONF_FILE, e);
+ }
+
+ try {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName nameObj = new ObjectName(MBEAN_NAME);
+ mbs.registerMBean(this, nameObj);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to register MBean " +
MBEAN_NAME, e);
+ }
+ }
+
+ @Override
+ public boolean authenticate(InetAddress address, int port) {
+ return addresses.contains(address);
+ }
+
+ @Override
+ public void reloadConfiguration() {
+ try {
+ addresses.clear();
+
+ BufferedReader reader = new BufferedReader(new FileReader(authConfFile));
+ String line = reader.readLine();
+
+ while (line != null) {
+ addresses.add(InetAddress.getByName(line));
+ line = reader.readLine();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to load addresses from " +
authConfFile, e);
+ }
+ }
+
+ @Override
+ public void validateConfiguration() throws ConfigurationException {
+ }
+}
diff --git
a/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticatorMBean.java
b/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticatorMBean.java
new file mode 100644
index 0000000..5e20389
--- /dev/null
+++
b/modules/common/cassandra-auth/src/main/java/org/rhq/cassandra/auth/RhqInternodeAuthenticatorMBean.java
@@ -0,0 +1,10 @@
+package org.rhq.cassandra.auth;
+
+/**
+ * @author John Sanda
+ */
+public interface RhqInternodeAuthenticatorMBean {
+
+ public void reloadConfiguration();
+
+}
diff --git a/modules/common/pom.xml b/modules/common/pom.xml
index bcbf862..7d12500 100644
--- a/modules/common/pom.xml
+++ b/modules/common/pom.xml
@@ -30,6 +30,7 @@
<module>ant-bundle</module>
<module>drift</module>
<module>jboss-as-dmr-client</module>
+ <module>cassandra-auth</module>
<module>cassandra-util</module>
<module>cassandra-jmx</module>
<module>cassandra-schema</module>
commit 8cf740355dfab9832b904984aaba4e52bf759951
Author: John Sanda <jsanda(a)redhat.com>
Date: Fri Jul 19 22:18:23 2013 -0400
add logic to enable jamm java agent, which mirrors logic in cassandra-env.sh
diff --git
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
index 1e31e14..b222c82 100644
---
a/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
+++
b/modules/common/cassandra-ccm/cassandra-ccm-core/src/main/java/org/rhq/cassandra/Deployer.java
@@ -125,6 +125,13 @@ public class Deployer {
properties.setProperty("thread_stack_size", "-Xss" +
deploymentOptions.getStackSize());
properties.setProperty("jmx_port",
deploymentOptions.getJmxPort().toString());
+ String javaVersion = System.getProperty("java.version");
+ // The check here is taken right from cassandra-env.sh
+ if ((!isOpenJDK() || javaVersion.compareTo("1.6.0") > 0) ||
+ (javaVersion.equals("1.6.0") && getJavaPatchVersion()
> 23)) {
+ properties.put("java_agent",
"-javaagent:$CASSANDRA_HOME/lib/jamm-0.2.5.jar");
+ }
+
propertiesUpdater.update(properties);
} catch (IOException e) {
log.error("An error occurred while updating " + jvmPropsFile, e);
@@ -132,6 +139,32 @@ public class Deployer {
}
}
+ private boolean isOpenJDK() {
+ String javaVMName = System.getProperty("java.vm.name");
+ return javaVMName.startsWith("OpenJDK");
+ }
+
+ private boolean isJava1_6() {
+ String javaVersion = System.getProperty("java.version");
+ return javaVersion.startsWith("1.6.0");
+ }
+
+ private int getJavaPatchVersion() {
+ String javaVersion = System.getProperty("java.version");
+ int startIndex = javaVersion.indexOf('_');
+
+ if (startIndex == -1) {
+ return 0;
+ }
+
+ return Integer.parseInt(javaVersion.substring(startIndex + 1,
javaVersion.length()));
+ }
+
+ private boolean isLaterThanJava1_6() {
+ String javaVersion = System.getProperty("java.version");
+ return javaVersion.compareTo("1.6.0") > 0;
+ }
+
public void updateFilePerms() {
File deployDir = new File(deploymentOptions.getBasedir());
File binDir = new File(deployDir, "bin");