#!/bin/bash
set -o pipefail
set -ex
#CASSANDRA_CONF_DIR="/etc/cassandra/"
CASSANDRA_CONF_FILE="cassandra.yaml"
HOSTNAME=$(cat /proc/sys/kernel/hostname)
#IP_ADDRESS=$(cat /etc/hosts | grep $HOSTNAME | awk '{print $1}' | head -n 1)
# usage prints info about required enviromental variables
# if $1 is passed, prints error message containing $1
function usage() {
if [ $# == 1 ]; then
echo >&2 "error: $1"
fi
echo "
You must specify the following environment variables:
CASSANDRA_ADMIN_PASSWORD"
echo "
For more information see /usr/share/container-scripts/cassandra/README.md
within the container or visit https://github.com/sclorg/cassandra-container/."
exit 1
}
# update cassandra config file (cassandra.yaml) based on the environment variables
# set by the user
function save_env_config_vars() {
# check whether the user mounted in his own config file
CONFIG_OWNER=$(ls -l "$CASSANDRA_CONF_DIR" | grep "$CASSANDRA_CONF_FILE" | awk '{print $3}')
if [ "$CONFIG_OWNER" == "cassandra" ]; then
# set the seeds for succesfull gossip initialization
# if the seeds were not set as the environment variable
if [ -z "$CASSANDRA_SEEDS" ]; then
# get the ip-address that the cassandra server is going to run on
#CASSANDRA_SEEDS=$(cassandra -f 2>/dev/null | grep :7000 | cut -d'/' -f2 | cut -d':' -f1)
# get the hostname of the machine that the cassandra server is going to run on
CASSANDRA_SEEDS="$HOSTNAME"
fi
# alter the seeds in the config file
sed -ri 's/(- seeds:).*/\1 "'"$HOSTNAME,$CASSANDRA_SEEDS"'"/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
# alter the rpc_address to allow external CQL client connections
sed -ri 's/(rpc_address:).*/\1 '"$HOSTNAME"'/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
# alter the listen_address to allow internode communication
sed -ri 's/(listen_address:).*/\1 '"$HOSTNAME"'/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
for yaml in \
cluster_name \
disk_optimization_strategy \
endpoint_snitch \
num_tokens \
rpc_address \
key_cache_size_in_mb \
concurrent_reads \
concurrent_writes \
memtable_allocation_type \
memtable_cleanup_threshold \
memtable_flush_writers \
concurrent_compactors \
compaction_throughput_mb_per_sec \
counter_cache_size_in_mb \
internode_compression \
gc_warn_threshold_in_ms \
; do
var="CASSANDRA_${yaml^^}"
val="${!var}"
if [ "$val" ]; then
sed -ri 's/^(# )?('"$yaml"':).*/\2 '"$val"'/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
fi
done
# hidden viariable (not originaly in config file)
CASSANDRA_AUTO_BOOTSTRAP="${CASSANDRA_AUTO_BOOTSTRAP:-false}"
echo "auto_bootstrap: ${CASSANDRA_AUTO_BOOTSTRAP}" >> "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
fi
}
# wait until the cassandra server accepts cqlsh connections
function wait_for_cql_listener_up() {
PORT=$(cat "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE" | grep native_transport_port | head -1 | cut -d' ' -f2)
while ! nc -z $HOSTNAME $PORT; do
sleep 1
done
}
# create an 'admin' user with password set by CASSANDRA_ADMIN_PASSWORD environmnet variable
function create_admin_user() {
# change the config
sed -ri 's/(^authenticator:).*/\1 PasswordAuthenticator/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
# echo config changed
# start cassandra with authentication
cassandra -R >/dev/null &
# echo starting server
# add admin super user with CASSANDRA_ADMIN_PASSWORD via the default super user
while ! cqlsh $HOSTNAME -u cassandra -p cassandra <<< "CREATE ROLE admin WITH PASSWORD = '$CASSANDRA_ADMIN_PASSWORD' \
AND SUPERUSER = true \
AND LOGIN = true;" >/dev/null 2>/dev/null; do
sleep 1
done
# echo admin super user created
# login as admin and drop the default super user
cqlsh $HOSTNAME -u admin -p "$CASSANDRA_ADMIN_PASSWORD" <<< "DROP ROLE cassandra;" >/dev/null
# echo cassandra super user dropped
# shut the cassandra down
#nodetool stopdaemon #2>/dev/null
pkill -f 'java.*cassandra'
sleep 3
# echo server stopped
# optionaly create a cqlshrc file with the login information
# NOT SUPPORTED YET
# if [ ! -d "/var/lib/cassandra/.cassandra" ]; then
# mkdir /var/lib/cassandra/.cassandra
# fi
# cat << 'EOF' >> /var/lib/cassandra/.cassandra/cqlshrc
# [authentication]
# username = admin
# password = "$CASSANDRA_ADMIN_PASSWORD"
# EOF
# chmod 440 /var/lib/cassandra/.cassandra/cqlshrc
# echo cqlshrc file with the credentials created
# hide the admin password
unset CASSANDRA_ADMIN_PASSWORD
# echo password var dropped
}
# turn on the authorization
function turn_authorization_on() {
# change the config
sed -ri 's/(^authorizer:).*/\1 CassandraAuthorizer/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
# echo config changed
}
# set authenticator to PasswordAuthenticator
function set_password_authenticator {
sed -ri 's/(^authenticator:).*/\1 PasswordAuthenticator/' "$CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE"
}
# check if authorization is on
function is_authorization_on() {
result=`grep authorizer: $CASSANDRA_CONF_DIR$CASSANDRA_CONF_FILE|cut -d' ' -f2`
if [ "$result" == "CassandraAuthorizer" ]; then
return 0
fi
return 1
}
# turn on the JMX authentication using Cassandra's internal authentication and authorization
function turn_on_jmx_authentication() {
# disable JMX local
JMX_LOCAL=no
echo jmx_local: $JMX_LOCAL
# so far this is not working because cassandra-env.sh file is not modifiable (sits in scripts directory)
# update the config file cassandra-env.sh
sed -ri 's/^(.*jmxremote\.password)/#\1/' "/usr/share/cassandra/cassandra-env.sh"
sed -ri 's/^#(.*config=CassandraLogin.*$)/\1/' "/usr/share/cassandra/cassandra-env.sh"
sed -ri 's/^#(.*auth\.login.*$)/\1/' "/usr/share/cassandra/cassandra-env.sh"
sed -ri 's/^#(.*AuthorizationProxy.*$)/\1/' "/usr/share/cassandra/cassandra-env.sh"
echo config updated
}