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@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@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%22%3E + + <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@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");
rhq-commits@lists.fedorahosted.org