#!/usr/bin/bash
#
# TODO: This script needs to be split in half so that the initial part which
#       updates the config can be run from an ExecStartPre and the second part
#       which runs SQL commands can be run from an ExecStartPost
#
#
#
SECNUM=1
function section { echo -e "\n\\033[1;4m$SECNUM.  $1\\033[0m"; SECNUM=$[SECNUM+1]; };
function item    { echo -e "\n\\033[1m$1\\033[0m"; };

# This doesn't do anything (yet)
FORCE=
if [ "$1" == "--force" ]; then
	FORCE="$1"
	shift
fi


CADIR=$1
if [ -z "$CADIR" ] || [ ! -d "$CADIR" ]; then
	echo "Usage: $0 [--force] /path/to/CADir [<this-host>] [<peer-host>]"
	exit 1
fi


# Default to the server's hostname
ACCOUNT=$2
[ -n "$ACCOUNT" ] || ACCOUNT=$(hostname)


# If there's only two hosts and we know who we are
# We can guess the peer (see "Starting Replication")
PEER=$3

# If unspecified we'll guess by assignment of
# sorted host names
SERVERID=$4


if [ ! -d "$CADIR/certs" ] || [ ! -f "$CADIR/certs/mysql-CA.crt" ]; then
	echo "$CADIR doesn't appear to be a mysql cluster CA!"
	echo "Did you run init-mysql-cluster?"
	exit 2
fi

FN="mysql-${ACCOUNT//.*}"
if [ ! -f "$CADIR/certs/${FN}.crt" ] || [ ! -f "$CADIR/keys/${FN}.key" ]; then
	echo "$CADIR doesn't appear to contain a certificate for $ACCOUNT"
	exit 3
fi


if [ -z "$SERVERID" ]; then
	if [ -f /etc/sysconfig/ng-kickstart ]; then
		source /etc/sysconfig/ng-kickstart
	fi
	if [ -n "$serverid" ]; then
		SERVERID=$serverid
	else
		i=0
		for crt in $(find $CADIR/certs/*.crt -not -name 'mysql-CA.crt' | sort); do
			CN=$(openssl x509 -in ${crt} -noout -subject | sed -re 's|^.*/CN=([^/]+)|\1|g')
			((i++))
			if [ "$CN" = "$ACCOUNT" ]; then
				SERVERID=$i
				break
			fi
		done
	fi
fi
if [ -z "$SERVERID" ]; then
	echo "MySQL ServerID not provided and couldn't be auto-configured"
	exit 4
fi

section "Installing Certifcates"
FN="mysql-${ACCOUNT//.*}"
item " * Installing certificate files"
install -b -v -m 0644 $CADIR/certs/mysql-CA.crt      /etc/pki/tls/certs/mysql.ca-bundle | sed -re 's/^/   /g'
install -b -v -m 0644 $CADIR/certs/${FN}.crt         /etc/pki/tls/certs/                | sed -re 's/^/   /g'
install -b -v -m 0640 -g mysql $CADIR/keys/${FN}.key /etc/pki/tls/private/              | sed -re 's/^/   /g'

# Make sure the config files exist
item " * Updating mysql configuration"
touch -a /etc/mysql/conf.d/60-ssl.cnf /etc/mysql/conf.d/70-replication.cnf /etc/mysql/conf.d/70-replication.cnf

echo "   Updating /etc/mysql/conf.d/60-ssl.cnf & /etc/mysql/conf.d/70-replication.cnf"


# Use augeas to update them
augtool --autosave <<-EOD | sed -re 's/^/   /g'
	set /augeas/load/MyCnf/lens MySQL.lns
	set /augeas/load/MyCnf/incl /root/.my.cnf
	load 

	set /files/etc/mysql/conf.d/60-ssl.cnf/target[.='mysqld'] 'mysqld'
	set /files/etc/mysql/conf.d/60-ssl.cnf/target[.='mysqld']/ssl-ca   /etc/pki/tls/certs/mysql.ca-bundle
	set /files/etc/mysql/conf.d/60-ssl.cnf/target[.='mysqld']/ssl-key  /etc/pki/tls/private/${FN}.key
	set /files/etc/mysql/conf.d/60-ssl.cnf/target[.='mysqld']/ssl-cert /etc/pki/tls/certs/${FN}.crt

	set /files/etc/mysql/conf.d/70-replication.cnf/target[.='mysqld'] 'mysqld'
	set /files/etc/mysql/conf.d/70-replication.cnf/target[.='mysqld']/bind-address '*'
	set /files/etc/mysql/conf.d/70-replication.cnf/target[.='mysqld']/server-id ${SERVERID}
	set /files/etc/mysql/conf.d/70-replication.cnf/target[.='mysqld']/report-host ${ACCOUNT}
	set /files/etc/mysql/conf.d/70-replication.cnf/target[.='mysqld']/auto_increment_offset ${SERVERID}

	set /files/root/.my.cnf/target[.='mysql'] 'mysql'
	set /files/root/.my.cnf/target[.='mysql']/ssl-cipher DHE-RSA-AES256-SHA
	set /files/root/.my.cnf/target[.='mysqldump'] 'mysqldump'
	set /files/root/.my.cnf/target[.='mysqldump']/ssl-cipher DHE-RSA-AES256-SHA
	set /files/root/.my.cnf/target[.='mysqladmin'] 'mysqladmin'
	set /files/root/.my.cnf/target[.='mysqladmin']/ssl-cipher DHE-RSA-AES256-SHA

EOD


#
# We need to restart mysqld here becuase the client will immediately pick up the ssl settings, but
# the server needs a restart first, otherwise all our grants etc will fail
#
systemctl restart mysqld

section "Updating mysql GRANTs"

# We (potentually) need all the hosts for the grants, so extract from the certificate
# Common Names in the CADIR
for i in $CADIR/certs/mysql-*.crt; do
  CN=$(openssl x509 -in ${i} -noout -subject | sed -re 's|^.*/CN=([^/]+)|\1|g')
  if [[ ! "$CN" =~ 'MySQL CA' ]]; then
    ACCOUNTS="$ACCOUNTS $CN"
  fi
done

# TODO: Can we just load this hash MySQL direct? it *MUST* match the MySQL root
#       password generated in init-mysql-server
ROOTPASS=$(/usr/libexec/ng-server-config/mk-auth-token mysql:root@localhost 16)
REPLPASS=$(/usr/libexec/ng-server-config/mk-auth-token mysql:replicate@localhost 16)
item " * Granting root privileges for replication peers"
for i in $ACCOUNTS; do
	echo "   GRANT ALL PRIVILEGES ON *.* TO 'root'@'$i' IDENTIFIED BY '$ROOTPASS' REQUIRE SSL;"
	mysql -NB -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'$i' IDENTIFIED BY '$ROOTPASS' REQUIRE SSL;"
done
item " * Granting replication slave privileges for replication peers"
for i in $ACCOUNTS; do
	echo "   GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'$i' IDENTIFIED BY '$REPLPASS' REQUIRE X509;"
	mysql -NB -e "GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'$i' IDENTIFIED BY '$REPLPASS' REQUIRE X509;"
done

section "Configuring replication slave (CHANGE MASTER)"
if [ -z "$PEER" ]; then
	PEER=$(echo "$ACCOUNTS" | sed -re "s/$ACCOUNT//g" | sed -re 's/(^ *| *$)//g')
fi

if [ -z "$PEER" ]; then
	echo "Peer server wasn't specified and couldn't be detected, skipping"
else
   # TODO: STOP SLAVE? or just check?
   echo -e "   CHANGE MASTER TO MASTER_HOST    = '${PEER}',\n" \
           "                 MASTER_USER       = 'replicate',\n" \
           "                 MASTER_PORT       = 3306,\n" \
           "                 MASTER_SSL        = 1,\n" \
           "                 MASTER_PASSWORD   = '${REPLPASS}',\n" \
           "                 MASTER_SSL_CA     = '/etc/pki/tls/certs/mysql.ca-bundle',\n" \
           "                 MASTER_SSL_CERT   = '/etc/pki/tls/certs/${FN}.crt',\n" \
           "                 MASTER_SSL_CIPHER = 'DHE-RSA-AES256-SHA',\n" \
           "                 MASTER_SSL_KEY    = '/etc/pki/tls/private/${FN}.key';\n" \
   | mysql -v -NB | sed -re 's/^/   /g'

	# Now actually start the replication
	mysql -NB -e 'START SLAVE';

fi






