terom@525: #!/bin/bash terom@525: # vim: set ft=sh : terom@525: terom@525: set -ue terom@525: terom@525: ROOT=$(pwd) terom@525: terom@530: BIN=bin terom@525: PROCESS_ZONE=$BIN/process-zone terom@525: EXPAND_ZONE=$BIN/expand-zone terom@530: UPDATE_SERIAL=$BIN/update-serial terom@525: terom@530: SETTINGS=settings terom@530: ZONES=zones terom@530: SERIALS=serials terom@525: terom@525: PROCESS_ARGS='--input-charset latin-1' terom@525: terom@525: FORWARD_MX=mail terom@525: REVERSE_ZONE=194.197.235 terom@525: REVERSE_DOMAIN=paivola.fi terom@525: terom@530: ## options terom@530: IS_TTY= terom@530: UPDATE_FORCE= terom@530: SERIAL_NOUPDATE= terom@530: terom@530: function help_args { terom@530: local prog=$1 terom@530: terom@530: cat <&2 terom@525: } terom@525: terom@530: function log_color { terom@530: local code=$1; shift terom@530: terom@530: if [ $IS_TTY ]; then terom@530: echo $'\e[0;'${code}'m'"$*"$'\e[00m' >&2 terom@530: else terom@530: echo "$*" >&2 terom@530: fi terom@530: } terom@530: terom@530: function log_error { terom@530: log_color 31 "$*" terom@530: } terom@530: terom@530: function log { terom@530: log_msg "$*" terom@530: } terom@530: terom@530: function log_info { terom@530: log_color 36 " $*" terom@530: } terom@530: terom@530: function log_debug { terom@530: log_color 32 " $*" terom@530: } terom@530: terom@530: function log_cmd { terom@530: log_color 35 " \$ $*" terom@530: } terom@530: terom@525: function die { terom@530: log_error "$*" terom@525: exit 1 terom@525: } terom@525: terom@530: function cmd { terom@530: log_cmd "$@" terom@530: terom@530: "$@" || die "Failed" terom@530: } terom@530: terom@530: function run_cmd { terom@525: local msg=$1; shift terom@525: terom@530: log_info "$msg... " terom@525: terom@530: cmd "$@" terom@525: } terom@525: terom@530: function indent () { terom@530: "$@" | ( terom@530: while read line; do terom@530: echo " $line" terom@530: done terom@530: ) || exit $? terom@530: } terom@530: terom@530: ## test terom@525: [ -d $SETTINGS ] || die "Missing settings: $SETTINGS" terom@525: [ -d $SERIALS ] || die "Missing serials: $SERIALS" terom@525: [ -d $ZONES ] || die "Missing zones: $ZONES" terom@525: terom@530: ## functions terom@530: function update { terom@530: local dst=$1 terom@530: local src=$2 terom@530: local tmp=$dst.new terom@530: terom@530: shift 2 terom@530: terom@530: if [ -z $src ] || [ $UPDATE_FORCE ] || [ $dst -ot $src ]; then terom@530: log_debug "update: $dst <- $src" terom@530: cmd "$@" $src > $tmp terom@530: terom@530: # compare terom@530: if [ -e $dst ]; then terom@530: # terse terom@530: indent diff --unified=1 $dst $tmp terom@530: fi terom@530: terom@530: # overwrite terom@530: mv $tmp $dst terom@530: terom@530: else terom@530: log_debug "$dst <- $src: up-to-date" terom@530: fi terom@530: } terom@530: terom@530: ## bin wrappers terom@530: function update_serial { terom@530: cmd $UPDATE_SERIAL $* terom@530: } terom@530: terom@525: function expand_zone { terom@525: local output=$1; shift terom@530: local src=$1; shift terom@525: terom@530: terom@530: update $output $src $EXPAND_ZONE "$@" terom@525: } terom@525: terom@525: function process_zone { terom@525: local output=$1; shift terom@530: local src=$1; shift terom@525: terom@530: update $output $src $PROCESS_ZONE $PROCESS_ARGS "$@" terom@525: } terom@525: terom@530: ## actions terom@525: function copy_zone_part { terom@525: local zone=$1 terom@525: local part=$2 terom@525: terom@525: local name=$zone.zone.$part terom@525: terom@530: log_info "Copying zone $zone/$part: zones/$name" terom@530: terom@530: update $ZONES/$name $SETTINGS/$name cat terom@525: } terom@525: terom@525: function update_zone { terom@525: local zone=$1 terom@525: local name=$zone.zone terom@525: terom@530: log_info "Generating $zone zone headers: zones/$name" terom@530: terom@530: expand_zone $ZONES/$name $SETTINGS/$zone.zone \ terom@530: --serial $SERIALS/$zone.serial \ terom@530: --expand zones=$ROOT/$ZONES terom@525: } terom@525: terom@525: function update_zone_view { terom@525: local zone=$1 terom@525: local view=$2 terom@525: terom@525: local name=$view/$zone.zone terom@525: terom@530: log_info "Generating $zone:$view zone headers: zones/$name" terom@530: terom@530: expand_zone $ZONES/$name $SETTINGS/$zone.zone \ terom@530: --serial $SERIALS/$zone.serial \ terom@530: --expand zones=$ROOT/$ZONES \ terom@530: --expand view=$view terom@525: } terom@525: terom@525: function main { terom@530: # test tty terom@530: [ -t 1 ] && IS_TTY=y terom@525: terom@530: parse_args "$@" terom@530: terom@530: if [ $SERIAL_NOUPDATE ]; then terom@530: log_debug "skipping serial-update" terom@530: else terom@530: log "Updating serials..." terom@530: update_serial $SERIALS/paivola.serial terom@530: update_serial $SERIALS/paivola-reverse.serial terom@530: fi terom@530: terom@530: log "Generating host zones..." terom@530: process_zone $ZONES/external/paivola.zone.hosts $SETTINGS/paivola.txt --forward-zone terom@525: process_zone $ZONES/internal/paivola.zone.hosts $SETTINGS/paivola.txt --forward-zone --forward-txt --forward-mx $FORWARD_MX terom@525: process_zone $ZONES/paivola-reverse.zone.hosts $SETTINGS/paivola.txt --reverse-zone $REVERSE_ZONE --reverse-domain $REVERSE_DOMAIN terom@525: terom@530: log "Copying zone parts..." terom@530: copy_zone_part paivola auto terom@530: copy_zone_part paivola services terom@530: copy_zone_part paivola internal terom@530: copy_zone_part paivola external terom@525: terom@530: log "Updating zones..." terom@530: update_zone paivola-reverse terom@530: update_zone_view paivola internal terom@530: update_zone_view paivola external terom@525: } terom@525: terom@530: main "$@"