#!/bin/bash
#   deploy -- set up a standard set of network services
#   Copyright (C) 2007  Gordon Messmer <gordon@dragonsdawn.net>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Turn on "extglob" for username matching when parsing args.
shopt -s extglob

# These are the services that we know how to configure.
# SERVICES="dhcp dns ntp syslog kerberos ldap nss email http sql wildfire samba monitoring backups directorymanager"
SERVICES="dhcp dns ntp syslog kerberos ldap nss email http sql wildfire"

# These are the values that we need from the user.
DOMAIN=""
NET="192.168.1.0"
PASSWORD=""
USER=""
WILDFIREPASS=""

function printhelp () {
	cat <<EOF
Use: setup.sh --domain=int.yourdomain.com --user=username [--network=192.168.1.0] [--password=mypass]
  --domain: top level domain used for hosts inside your network.
	It is recommended that you not use the same domain internally
	that you use for publicly exposed services.
  --network: the IPv4 network used for your hosts.
  --password: password used for any service's master password.  This
	includes the krb5 master password, and the directory's
	manager account.  If not given, one will be chosen and saved
	to "MASTER.PASSWORD.txt"
  --user: username of the first user created, which will have admin
	rights to all services.
EOF
	exit 1
}

# Parse command line options.  Set "NET" to a default
# value if none is given.
TEMP=`getopt -o d:n:p:u: -l domain:,network:,password:,user: -- "$@" 2>/dev/null`

if [ $? != 0 ] ; then printhelp ; fi

eval set -- "$TEMP"

while true ; do
	case "$1" in
		-d|--domain)
			case "$2" in
				*.*) DOMAIN="$2" ; shift 2 ;;
				*) echo -e "Invalid domain\n" 1>&2 ; printhelp ;;
			esac ;;
		-n|--network)
			case "$2" in
				*.*.*.*) NET="$2" ; shift 2 ;;
				*) echo -e "Invalid network\n" 1>&2 ; printhelp ;;
			esac ;;
		-p|--password)
			case "$2" in
				??????*) PASSWORD="$2" ; shift 2 ;;
				*) echo -e "Invalid password: must be at least 6 characters\n" 1>&2 ; printhelp ;;
			esac ;;
		-u|--user)
			case "$2" in
				+([[:alnum:]])) USER="$2" ; shift 2 ;;
				*) echo -e "Invalid username\n" 1>&2 ; printhelp ;;
			esac ;;
		--) shift ; break ;;
		*) printhelp ;;
	esac
done

# DOMAIN and USER are required input
test "x$DOMAIN" = x && printhelp
test "x$USER" = x && printhelp

# If PASSWORD isn't given, create one.
test "x$PASSWORD" = x && PASSWORD=`mkpasswd`

# Compute the remaining variables
HOST="`hostname -s`"
FQDN="`hostname -f`"
UPPERDOMAIN="`echo $DOMAIN | tr [[:lower:]] [[:upper:]]`"
TMPB1="${NET%%.*}"
TMPNET="${NET#*.}"
TMPB2="${TMPNET%%.*}"
TMPNET="${TMPNET#*.}"
TMPB3="${TMPNET%%.*}"
TMPNET="${TMPNET#*.}"
NET3="${NET%.*}"
REVERSENET3="$TMPB3.$TMPB2.$TMPB1"
SERVICEIP="${NET3}.1"
GATEWAY="${NET3}.1"
BASEDN="dc=${DOMAIN//./,dc=}"

export DOMAIN HOST FQDN UPPERDOMAIN NET3 REVERSENET3 SERVICEIP GATEWAY BASEDN PASSWORD USER

# During testing, create the directory for output:
test -d system || mkdir system

# Save the password
echo "$PASSWORD" > system/MASTER.PASSWORD.txt

# Loop through known services.  Install packages, then deploy
# their configuration files.
function install_pkg () {
	echo "up2date -i ""$*" >> system/install.cmds
}

function process_config () {
	OUTPUT_FILE="${1#*config/}"
	OUTPUT_FILE="system/${OUTPUT_FILE//://}"
	OUTPUT_DIR="${OUTPUT_FILE%/*}"
	mkdir -p "$OUTPUT_DIR"
	if test -L "$1" ; then
		LDEST="`find $1 -printf %l`"
		LDEST="${LDEST//://}"
		test -e "$OUTPUT_FILE" && rm "$OUTPUT_FILE"
		ln -s "$LDEST" "$OUTPUT_FILE"
		return
	fi
	sed -e "s/@DOMAIN@/$DOMAIN/g; s/@UPPERDOMAIN@/$UPPERDOMAIN/g;
		s/@HOST@/$HOST/g; s/@FQDN@/$FQDN/g;
		s/@NET@/$NET/g; s/@NET3@/$NET3/g;
		s/@REVERSENET3@/$REVERSENET3/g;
		s/@SERVICEIP@/$SERVICEIP/g; s/@GATEWAY@/$GATEWAY/g;
		s/@BASEDN@/$BASEDN/g;
		s/@USER@/$USER/g; s/@PASSWORD@/$PASSWORD/g;" < $1 > "$OUTPUT_FILE"
}

function run_postinstall () {
	cat "$1" >> system/install.cmds
}

for S in $SERVICES ; do
	[ -e "$S"/pkgs ] && install_pkg `cat "$S"/pkgs`
	[ -e "$S"/config ] && for conf in "$S"/config/* ; do
		process_config "$conf"
	done
	[ -e "$S"/postinstall.sh ] && run_postinstall "$S"/postinstall.sh
done


