tero@628: #HOSTS_CHARSET='utf-8' tero@628: HOSTS_INCLUDE="$ETC/hosts" tero@628: tero@628: NAMED_CHECKZONE=/usr/sbin/named-checkzone tero@628: tero@628: RNDC=/usr/sbin/rndc tero@628: RNDC_KEY=/etc/bind/rndc.key tero@628: tero@628: tero@628: ## Generate forward zone from hosts hosts using pvl.hosts-forward tero@628: # tero@628: # update_hosts_forward $out $src tero@628: function update_hosts_forward { tero@628: local out="$1" tero@628: local src="$2" tero@628: local srcs=($src/*) tero@628: local msg="$out: Generating forward hosts zone: $src" tero@628: tero@628: if apply_check "$out" "${srcs[@]}"; then tero@628: log_skip "$msg" tero@628: else tero@628: log_apply "$msg" tero@628: tero@628: apply_cmd "$out" $OPT/bin/pvl.hosts-forward \ tero@628: --hosts-include="$HOSTS_INCLUDE" \ tero@628: "$src" tero@628: fi tero@628: } tero@628: tero@628: ## Generate reverse zone from hosts hosts using pvl.hosts-reverse tero@628: # tero@628: # update_hosts_reverse $out $src tero@628: function update_hosts_reverse { tero@628: local out="$1" tero@628: local src="$2" tero@628: local srcs=($src/*) tero@628: local msg="$out: Generating reverse hosts zone: $src" tero@628: tero@628: if apply_check "$out" "${srcs[@]}"; then tero@628: log_skip "$msg" tero@628: else tero@628: log_apply "$msg" tero@628: tero@628: apply_cmd "$out" $OPT/bin/pvl.hosts-reverse \ tero@628: --hosts-include="$HOSTS_INCLUDE" \ tero@628: "$src" tero@628: fi tero@628: } tero@628: tero@628: function update_zone_include { tero@628: local out="$1" tero@628: local src="$2" tero@628: local msg="$out: Copy zone include: $src" tero@628: tero@628: if apply_check "$out" "${srcs[@]}"; then tero@628: log_skip "$msg" tero@628: else tero@628: log_apply "$msg" tero@628: tero@628: apply_cmd "$out" cat \ tero@628: "$src" tero@628: fi tero@628: } tero@628: tero@628: ## Read include paths from file tero@628: function read_zone_includes { tero@628: cmd sed -n -E 's/^\$INCLUDE\s+"(.+)"/\1/p' "$@" tero@628: } tero@628: tero@628: ## (cached) include paths for zone file tero@628: function zone_includes { tero@628: local cache="$1" tero@628: local src="$2" tero@628: local prefix="${3:-}" tero@628: tero@628: if [ ! -e "$cache" -o "$cache" -ot "$src" ]; then tero@628: read_zone_includes "$src" > "$cache" tero@628: fi tero@628: tero@628: while read include; do tero@628: echo -n "$prefix$include " tero@628: done < "$cache" tero@628: } tero@628: tero@628: ## Search for prefix-matching includes in zone file tero@628: function zone_includes_grep { tero@628: local cache="$1" tero@628: local src="$2" tero@628: local prefix="$3" tero@628: tero@628: for include in $(zone_includes $cache $src); do tero@628: if [ "${include#$prefix}" != "$include" ]; then tero@628: echo -n " ${include#$prefix}" tero@628: fi tero@628: done tero@628: } tero@628: tero@628: ## Generate new serial for zone using pvl.dns-serial, if the zone data has changed: tero@628: # tero@628: # update_serial .../serials/$zone $serial $deps... tero@628: # tero@628: # Supports SERIAL_FORCE/NOOP. tero@628: # Updates $SERIALS/$zone.serial. tero@628: function update_zone_serial { tero@628: local out="$1" tero@628: local serial="$2" tero@628: tero@628: local old=$(test -e "$out" && cat "$out" || echo '') tero@628: tero@628: # test tero@628: if [ "$SERIAL" = 1 ]; then tero@628: log_force "$out: Force serial $old <- $serial" tero@628: tero@628: elif apply_check "$out" "${@:3}"; then tero@628: log_skip "$out: Skip serial: $old <- $serial" tero@628: tero@628: return tero@628: tero@628: elif [ "$SERIAL" = 0 ]; then tero@628: log_noop "$out: Noop serial: $old <- $serial" tero@628: tero@628: return tero@628: tero@628: else tero@628: log_apply "$out: Update serial: $old <- $serial" tero@628: fi tero@628: tero@628: echo "$serial" > $out tero@628: } tero@628: tero@628: ## Generate zone file from source using pvl.dns-zone: tero@628: # tero@628: # update_zone out/zones/$zone in/zones/$zone var/serials/$zone tero@628: function update_zone { tero@628: local out="$1" tero@628: local src="$2" tero@628: local serial="$3" tero@628: local serial_opt= tero@628: local msg="$out: Generate zone: $src" tero@628: tero@628: if [ -n "$serial" -a -f "$serial" ]; then tero@628: serial_opt="--serial=$(cat "$serial")" tero@628: elif [ "$SERIAL" = 0 ]; then tero@628: warn "$out: noop'd serial, omitting" tero@628: else tero@628: fail "$out: missing serial: $serial" tero@628: fi tero@628: tero@628: if apply_check "$@"; then tero@628: log_skip "$msg" tero@628: else tero@628: log_apply "$msg" tero@628: tero@628: apply_cmd "$out" $OPT/bin/pvl.dns-zone \ tero@628: --include-path=$VAR/zones \ tero@628: $serial_opt \ tero@628: "$src" tero@628: fi tero@628: } tero@628: tero@628: ## Test zone file for validity using named-checkzone: tero@628: # tero@628: # check_zone ..../$zone $origin tero@628: function test_zone { tero@628: local zone=$1 tero@628: local origin=$2 tero@628: tero@628: log_check "$zone: Checking zone @$origin..." tero@628: tero@628: # checkzone is very specific about the order of arguments, -q must be first tero@628: test_cmd $zone \ tero@628: $NAMED_CHECKZONE $origin $zone tero@628: } tero@628: tero@628: # set by do_reload_zone if zone data has actually been reloaded tero@628: RELOAD_ZONES= tero@628: tero@628: ## Load update zonefiles into bind: tero@628: # tero@628: # reload_zones tero@628: # tero@628: # Invokes `rndc reload`, showing its output. tero@628: function reload_zones { tero@628: if [ "$RELOAD" = 1 ]; then tero@628: log_force "Reload zones" tero@628: tero@628: elif [ "$RELOAD" = 0 ]; then tero@628: log_noop "Skip reload zones" tero@628: tero@628: return tero@628: tero@628: elif [ ! -e "$RNDC" ]; then tero@628: warn "Skip with missing RNDC: $RNDC" tero@628: tero@628: return tero@628: tero@628: elif [ ! -e "$RNDC_KEY" ]; then tero@628: warn "Skip with missing RNDC_KEY: $RNDC_KEY" tero@628: tero@628: return tero@628: tero@628: elif [ ! -r $RNDC_KEY ]; then tero@628: error "Permission denied for RNDC_KEY: $RNDC_KEY" tero@628: tero@628: return 1 tero@628: tero@628: else tero@628: log_apply "Reload zones" tero@628: fi tero@628: tero@628: indent " rndc: " \ tero@628: $RNDC reload tero@628: tero@628: # set flag for dhcp tero@628: RELOAD_ZONES=1 tero@628: }