#!/bin/bash
## vim: set ft=sh :
#
# Operations on zonefiles/hosts/whatever
function link {
local out="$1"
local tgt="$2"
if check_link "$out" "$tgt"; then
log_update "Linking $out -> $tgt..."
do_link "$out" "$tgt"
else
log_skip "Linking $out -> $tgt: not changed"
fi
}
function copy {
local out="$1"
local src="$2"
if check_update "$out" "$src"; then
log_update "Copying $out <- $src..."
do_update "$out" \
cat "$src"
else
log_skip "Copying $out <- $src: not changed"
fi
}
## Run check-command on given file, outputting results:
#
# check $src $cmd $args...
#
function check {
local src="$1"; shift
local cmd="$1"; shift
if cmd_test "$cmd" -q "$@"; then
log_skip "Check $src: OK"
else
log_error " Check $src: Failed"
indent " " "$cmd" "$@"
exit 1
fi
}
## Generate forward zone from hosts hosts using pvl.hosts-dns:
#
# update_hosts_forward out/hosts/$hosts $hosts in/hosts/$hosts
function update_hosts_forward {
local out="$1"; shift
local domain="$1"; shift
if check_update "$out" "$@"; then
log_update "Generating forward hosts zone $out @ $domain <- $@..."
do_update "$out" $OPT/bin/pvl.hosts-dns \
--hosts-charset=$CHARSET \
--forward-zone="$domain" \
"$@"
else
log_skip "Generating forward hosts $out <- $@: not changed"
fi
}
function update_hosts_dhcp {
local out=$1; shift
local domain="$1"; shift
if check_update $out "$@"; then
log_update "Generating DHCP hosts $out @ $domain <- $@..."
do_update $out $OPT/bin/pvl.hosts-dhcp \
--hosts-charset=$CHARSET \
--hosts-domain=$domain \
"$@"
else
log_skip "Generating DHCP hosts $out <- $@: not changed"
fi
}
## Generate reverse zone from hosts hosts using pvl.hosts-dns:
#
# update_hosts_reverse out/hosts/$reverse $reverse in/hosts/$hosts
function update_hosts_reverse {
local out="$1"; shift
local reverse="$1"; shift
if check_update "$out" "$@"; then
log_update "Generating reverse hosts zone $out <- $@..."
do_update "$out" $OPT/bin/pvl.hosts-dns \
--hosts-charset=$CHARSET \
--reverse-zone="$reverse" \
"$@"
else
log_skip "Generating reverse hosts $out <- $@: not changed"
fi
}
## Update .serial number:
#
# do_update_serial .../serials/$zone $serial
#
function do_update_serial {
local dst="$1"
local serial="$2"
echo $serial > $dst
}
## Generate new serial for zone using pvl.dns-serial, if the zone data has changed:
#
# update_serial .../serials/$zone $serial $deps...
#
# Supports SERIAL_FORCE/NOOP.
# Updates $SERIALS/$zone.serial.
function update_serial {
local dst="$1"; shift
local serial="$1"; shift
local old=$(test -e "$dst" && cat "$dst" || echo '')
# test
if [ $SERIAL_FORCE ]; then
log_force "Updating $dst: $old <- $serial: forced"
do_update_serial "$dst" "$serial"
elif ! check_update "$dst" "$@"; then
log_skip "Updating $dst: $old <- $serial: not changed"
elif [ $SERIAL_NOOP ]; then
log_noop "Updating $dst: $old <- $serial: skipped"
else
log_update "Updating $dst: $old <- $serial"
do_update_serial "$dst" "$serial"
fi
}
## Generate zone file from source using pvl.dns-zone:
#
# update_zone out/zones/$zone in/zones/$zone var/serials/$zone
function update_zone {
local out="$1"; shift
local src="$1"; shift
local serial="$1"; shift
local serial_opt=
if [ -n "$serial" -a -f "$serial" ]; then
serial_opt="--serial=$(cat "$serial")"
elif [ $SERIAL_NOOP ]; then
warn "$out: noop'd serial, omitting"
else
fail "$out: missing serial: $serial"
fi
if check_update "$out" "$src" "$serial" "$@"; then
log_update "Generating $out <- $src..."
do_update "$out" $OPT/bin/pvl.dns-zone "$src" \
--include-path=$SRV/var/zones \
$serial_opt
else
log_skip "Generating $out <- $src: not changed"
fi
}
## Generate dhcp confs from source using pvl.dhcp-conf:
function update_dhcp_conf {
local out="$1"
local src="$2"
if check_update "$out" "$src"; then
log_update "Generating $out <- $src..."
do_update "$out" $OPT/bin/pvl.dhcp-conf "$src" \
--include-path=$SRV/var/dhcp
else
log_skip "Generating $out <- $src: not changed"
fi
}
## Test hosts zone for validity using pvl.hosts-check:
#
# check_hosts .../hosts
function check_hosts {
local hosts=$1; shift 1
# TODO
check $hosts \
$OPT/bin/pvl.hosts-check $hosts
}
## Test zone file for validity using named-checkzone:
#
# check_zone ..../$zone $origin
function check_zone {
local zone=$1
local origin=$2
log_check "Checking $zone @ $origin..."
# checkzone is very specific about the order of arguments, -q must be first
check $zone $NAMED_CHECKZONE $origin $zone
}
## Test DHCP configuration for validity using dhcpd -t:
#
# check_dhcp [$conf]
#
# Defaults to the global $DHCPD_CONF.
# Fails if the check fails.
function check_dhcp {
local conf=${1:-$DHCPD_CONF}
log_check "Checking DHCP $conf..."
if [ ! -e $DHCPD ]; then
log_warn "check_dhcp: dhcpd not installed, skipping: $conf"
return 0
fi
check $conf \
$DHCPD -cf $conf -t
}
## Test DHCP configuration of given settings/dhcp using check_dhcp $DHCP_DATA/$host.conf:
#
# check_dhcp_conf $conf
#
function check_dhcp_conf {
local conf=$1;
check_dhcp $DHCP_DATA/$conf.conf
}
### Deploy
# set by do_reload_zone if zone data has actually been reloaded
RELOAD_ZONES=
## Run rndc reload
function do_reload_zones {
# run
indent " rndc: " \
$RNDC reload
# set flag
RELOAD_ZONES=y
}
## Load update zonefiles into bind:
#
# reload_zones
#
# Invokes `rndc reload`, showing its output.
function reload_zones {
local msg="Reload zones"
if [ $RELOAD_FORCE ]; then
log_force "$msg..."
do_reload_zones
elif [ $RELOAD_NOOP ]; then
log_noop "$msg: skipped"
elif [ ! -e $RNDC ]; then
log_warn "reload_zones: rndc not installed, skipping"
elif [ ! -e $RNDC_KEY ]; then
log_warn " $msg: rndc: key not found: $RNDC_KEY"
elif [ ! -r $RNDC_KEY ]; then
log_error " $msg: rndc: permission denied: $RNDC_KEY"
return 1
else
log_update "$msg..."
# run
do_reload_zones
fi
}
## Reload DHCP by restarting it, if running:
#
# do_reload_dhcp
#
# Does NOT restart dhcp if it is not running (status).
function do_reload_dhcp {
if cmd_test $DHCPD_INIT status >/dev/null; then
cmd $DHCPD_INIT restart
else
log_warn "dhcpd not running; did not restart"
fi
}
## Reload dhcp hosts
#
# reload_dhcp
#
# noop's if we haven't reloaded zones
function reload_dhcp {
local msg="Reload DHCP hosts"
if [ $RELOAD_FORCE ]; then
log_force "$msg..."
do_reload_dhcp
elif [ $RELOAD_NOOP ]; then
log_noop "$msg: skipped"
elif [ ! -e $DHCPD ]; then
log_warn "reload_dhcp: dhcpd not installed, skipping: $conf"
else
log_update "$msg..."
# run
do_reload_dhcp
fi
}
### Commit
## Commit changes to version control:
#
# update_commit .../etc "commit message"
#
# Invokes `hg commit`, first showing the diff.
function update_commit {
local repo="$1"
local commit_msg="$COMMIT_MSG"
local msg="Commit changes"
# operate?
if [ $COMMIT_FORCE ]; then
log_force "$msg: $commit_msg"
[ $LOG_DIFF ] && indent " " hg_diff $repo
hg_commit "$repo" "$commit_msg"
elif ! hg_modified "$repo"; then
log_warn "$msg: no changes"
elif [ $COMMIT_SKIP ]; then
log_noop "$msg: skipped"
# still show diff, though
[ $LOG_DIFF ] && indent " " hg_diff "$repo"
else
log_update "$msg: $commit_msg"
[ $LOG_DIFF ] && indent " " hg_diff $repo
hg_commit "$repo" "$commit_msg"
fi
}