#!/bin/bash
#
# sccl_add_node
#
# Zertifikat und Key fuer einen SCCL-Cluster-Knoten anlegen
###########################################################
#
cd ${0%/*}
if [[ $PWD != */bin ]]
 then
  cd bin
fi
#
BASEDIR=/etc/sccl
SCCLBINDIR=bin
#
unset PASSWORD FORCE LOCAL
while getopts c:d:jlp:P:-:? op
 do
  case "$op" in
   l) LOCAL=1;;
   p) PASSWORD="-passin pass:$OPTARG";;
   P) PASSWORD="-passin pass:$(<$OPTARG)";;
   -) case "$OPTARG" in
       force) FORCE=1;;
        *) echo "usage: $0 [--force] [-j|-l] [-p <CA-Key-PWD>|-P <CA-Key-PWD-File>] <Node Name>"
           exit 1;;
      esac;;
   *) echo "usage: $0 [--force] [-j|-l] [-p <CA-Key-PWD>|-P <CA-Key-PWD-File>] <Node Name>"
      exit 1;;
  esac
done
#
shift $(( $OPTIND - 1))
#
if [[ ! -w $BASEDIR/sccl.conf ]]
 then
  echo "$BASEDIR/sccl.conf nicht gefunden oder kein Schreibrecht"
  exit 1
fi
#
. $BASEDIR/sccl.conf
#
if [[ -z "$CLUSTER" ]]
 then
  echo "Clustername nicht konfiguriert"
  exit 1
fi
#
if [[ ! -f /etc/sccl/certs/private/${CLUSTER}-cakey.pem ]]
 then
  echo "CA-Key nicht gefunden. Neue Knoten können nur auf dem Masterknoten"
  echo "oder Knoten, auf die per 'sccl_dist_config -m' die Masterdaten kopiert wurden,"
  echo "generiert werden."
  exit 1
fi
#
if [[ -z "$PASSWORD" && -f $BASEDIR/capwd.dat ]]
 then
  PASSWORD="-passin pass:$(<$BASEDIR/capwd.dat)"
fi
#
if [[ -z "$1" ]]
 then
  echo "usage: $0 <node-name>"
  exit 1
fi
#
NODENAME="`echo $1 | tr '[:upper:]' '[:lower:]'`"
#
. $BASEDIR/certs.conf
#
if [[ -z "$PASSWORD" && -f $BASEDIR/certs/capwd.dat ]]
 then
  PWD=$(<$BASEDIR/certs/capwd.dat)
  if [[ -n "$PWD" ]]
   then
    PASSWORD="-passin pass:$PWD"
  fi
fi
#
if [[ ! -d $BASEDIR/certs/private ]]
 then
  mkdir -m 755 $BASEDIR/certs/private
fi
#
if [[ -f $BASEDIR/certs/private/${CLUSTER}-${NODENAME%%.*}-key.pem || -f certs/${CLUSTER}-${NODENAME%%.*}-cert.pem ]]
 then
  echo "Der Key fuer $NODENAME ist schon angelegt."
  if [[ -z "$FORCE" ]]
   then
    echo "$0 --force <Client> legt den Key neu an."
    exit 1
  fi
fi
#
echo "SCCL-Node-Zertifikat erstellen"
echo
openssl req -new -newkey rsa:2048 -batch -subj "/C=$DE/ST=$STATE/L=$CITY/O=$COMPANY/OU=$OU/CN=$NODENAME/emailAddress=$EMAIL" -out $BASEDIR/certs/certs/${CLUSTER}-${NODENAME%%.*}-csr.pem -nodes -keyout $BASEDIR/certs/private/${CLUSTER}-${NODENAME%%.*}-key.pem -days 3650
#
openssl x509 -req $PASSWORD -in $BASEDIR/certs/certs/${CLUSTER}-${NODENAME%%.*}-csr.pem -out $BASEDIR/certs/certs/${CLUSTER}-${NODENAME%%.*}-cert.pem -CA $BASEDIR/certs/${CLUSTER}-ca.pem -CAkey $BASEDIR/certs/private/${CLUSTER}-cakey.pem -CAserial $BASEDIR/certs/serial -days 3650
rm $BASEDIR/certs/certs/${CLUSTER}-${NODENAME%%.*}-csr.pem
#
if [[ -z "$LOCAL" ]]
 then
  if ! grep -q "^NODES=.*[\"[:blank:]]$NODENAME[\"[:blank:]]" $BASEDIR/sccl.conf
   then
    sed -i "s/^NODES=\"\\([^\"]*\\)\"/NODES=\"\\1 $NODENAME\"/" $BASEDIR/sccl.conf
  fi
  #
  ./sccl_update_ips -l
  ./sccl_dist_config $BASEDIR/sccl.conf $U2WHOSTSDAT
  #
  if [[ -d $BASEDIR/scripts ]]
   then
    SCRIPTS=scripts
  else
    SCRIPTS=''
  fi
  tar cvfz /tmp/${CLUSTER}-${NODENAME}.tgz -C $BASEDIR sccl.conf adminpwd.dat userpwd.dat ${PACKAGES##*/} ${RESOURCES##*/} ${U2WPWDDAT##*/} ${U2WHOSTSDAT##*/} $SCRIPTS certs/${CLUSTER}-ca.pem certs/private/${CLUSTER}-${NODENAME%%.*}-key.pem certs/certs/${CLUSTER}-${NODENAME%%.*}-cert.pem 2>/dev/null
  #
  MYTIMESTAMP=`date '+%s'`
  if RET=`httpget -s -u 'join' -p 'tocluster' -Sf -Sa $SCCLBASEDIR/data/JOINCLUSTER-ca.pem -Sk $SCCLBASEDIR/data/JOINCLUSTER-server-key.pem -Sc $SCCLBASEDIR/data/JOINCLUSTER-server-cert.pem -mf /tmp/${CLUSTER}-${NODENAME}.tgz -mn SCCLDATA ${NODENAME}:${U2WPORT} "join_to_cluster.s2w?joinnode=$NODENAME&timestamp=$MYTIMESTAMP"`
   then
    if [[ `echo "$RET" | tail -1` = 'JOINED' ]]
     then
      rm /tmp/${CLUSTER}-${NODENAME}.tgz
      echo "Der Knoten ist hinzugefuegt."
      echo "$RET" | fgrep 'WARNING'
      exit 0
    else
      echo "Der Join hat nicht geklappt: $RET"
    fi
  fi
  echo "Der Join kann manuell erfolgen, indem die Datei /tmp/${CLUSTER}-${NODENAME}.tgz"
  echo "Auf dem neuen Knoten unter $BASEDIR entpackt wird."
else
  ./sccl_update_ips -l
fi
