#!/bin/bash


#TODO Move this into the init script and ensure it only runs when something is wrong with configuraiton

while getopts "i" opt;
do
    case $opt in
        i)
            interactive=true
    esac
done

${interactive:=false}

if $interactive
then
    dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    cd $dir
    answers_file="puppetdb-ssl-setup-answers.txt"
    if [ -f "$answers_file" ]
    then
        echo "Reading answers file '$answers_file'"
        . $answers_file
    fi

    vars=( agent_confdir agent_vardir puppetdb_confdir )
    prompts=( "Puppet Agent confdir" "Puppet Agent vardir" "PuppetDB confdir" )

    for (( i=0; i<${#vars[@]}; i++ ))
    do
        read -p "${prompts[$i]} [${!vars[$i]}]: " input
        export ${vars[$i]}=${input:-${!vars[$i]}}
    done

    cat /dev/null > $answers_file
    for (( i=0; i<${#vars[@]}; i++ ))
    do
        echo "${vars[$i]}=${!vars[$i]}" >> $answers_file
    done
else
    # This should be run on the host with PuppetDB
    PATH=/opt/puppet/bin:$PATH
    agent_confdir=`puppet agent --configprint confdir`
    agent_vardir=`puppet agent --configprint vardir`

    if [ -d "/etc/puppetlabs/puppetdb" ] ; then
      puppetdb_confdir="/etc/puppetlabs/puppetdb"
      user=pe-puppetdb
    else
      puppetdb_confdir="/etc/puppetdb"
      user=puppetdb
    fi
fi

set -e

fqdn=`facter fqdn`
# use hostname if fqdn is not available
if [ ! -n "$fqdn" ] ; then
  fqdn=`facter hostname`
fi

mycertname=`puppet master --confdir=$agent_confdir --vardir=$agent_vardir --configprint  certname`
mycert=`puppet master --confdir=$agent_confdir --vardir=$agent_vardir --configprint  hostcert`
myca=`puppet master --confdir=$agent_confdir --vardir=$agent_vardir --configprint localcacert`
privkey=`puppet master --confdir=$agent_confdir --vardir=$agent_vardir --configprint hostprivkey`

pw_file=${puppetdb_confdir}/ssl/puppetdb_keystore_pw.txt

if [ -f $pw_file ]; then
  password=`cat $pw_file`
else
  password=`export LC_ALL=C; dd if=/dev/urandom count=20 2> /dev/null | tr -cd '[:alnum:]' | head -c 25`
  tmpdir=`mktemp -t -d tmp.puppetdbXXXXX`
  rm -rf $tmpdir
  mkdir -p $tmpdir
  cp $myca $tmpdir/ca.pem
  cp $privkey $tmpdir/privkey.pem
  cp $mycert $tmpdir/pubkey.pem

  cd $tmpdir
  keytool -import -alias "PuppetDB CA" -keystore truststore.jks -storepass "$password" -trustcacerts -file ca.pem -noprompt
  cat privkey.pem pubkey.pem > temp.pem
  echo "$password" | openssl pkcs12 -export -in temp.pem -out puppetdb.p12 -name $fqdn -passout fd:0
  keytool -importkeystore -destkeystore keystore.jks -srckeystore puppetdb.p12 -srcstoretype PKCS12 -alias $fqdn -deststorepass "$password" -srcstorepass "$password"

  rm -rf $puppetdb_confdir/ssl
  mkdir -p $puppetdb_confdir/ssl
  cp -pr *jks $puppetdb_confdir/ssl
  echo $password > ${puppetdb_confdir}/ssl/puppetdb_keystore_pw.txt
fi

jettyfile="${puppetdb_confdir}/conf.d/jetty.ini"
if [ -f "$jettyfile" ] ; then
  if grep "ssl-host" ${jettyfile} > /dev/null; then
    sed -e 's/^ssl-host.*/ssl-host = '"$fqdn"'/' ${jettyfile} > ${jettyfile}.tmp
    mv ${jettyfile}.tmp ${jettyfile}
  else
    echo "$jettyfile exists, but could not find ssl-host setting. Please update that setting to the desired hostname that puppetdb should listen on (e.g.: '`facter fqdn`)."
  fi

  if grep "key-password" ${jettyfile} >/dev/null && grep "trust-password" ${jettyfile} >/dev/null; then
    sed -e 's/^key-password.*/key-password = '"$password"'/' ${jettyfile} > ${tmpdir}/tmp.jetty
    sed -e 's/^trust-password.*/trust-password = '"$password"'/' ${tmpdir}/tmp.jetty > ${jettyfile}
  else
    echo "$jettyfile exists, but could not find key-password and trust-password settings. Please update those settings to the password contained in ${puppetdb_confdir}/ssl/puppetdb_keystore_pw.txt"
  fi
else
  echo "Please update your key-password and trust-password settings to the password contained in ${puppetdb_confdir}/ssl/puppetdb_keystore_pw.txt"
fi

chmod 600 ${puppetdb_confdir}/ssl/*
chmod 700 ${puppetdb_confdir}/ssl
chown -R ${user}:${user} ${puppetdb_confdir}/ssl
rm -rf $tmpdir

if $interactive
then
    echo "Certificate generation complete.  You will need to make sure that the puppetdb.conf"
    echo " file on your puppet master looks like this:"
    echo "    [main]"
    echo "    server = ${mycertname}"
    echo "    port   = 8081"
    echo
    echo " And that the config.ini (or other .ini) on your puppetdb system contains the"
    echo "  following:"
    echo
    echo "    [jetty]"
    echo "    #host           = localhost"
    echo "    port           = 8080"
    echo "    ssl-host       = ${fqdn}"
    echo "    ssl-port       = 8081"
    echo "    keystore       = ${puppetdb_confdir}/ssl/keystore.jks"
    echo "    truststore     = ${puppetdb_confdir}/ssl/truststore.jks"
    echo "    key-password   = ${password}"
    echo "    trust-password = ${password}"
fi
