From: Frank Brehm Date: Wed, 30 Nov 2022 09:17:28 +0000 (+0100) Subject: Adding scripts/create-pdns-zones-from-files X-Git-Tag: 0.7.4^2~1^2~2 X-Git-Url: https://git.uhu-banane.org/?a=commitdiff_plain;h=f34186e162b2a8a2e4edd4ca75d206a2a084ce50;p=pixelpark%2Fpp-admin-tools.git Adding scripts/create-pdns-zones-from-files --- diff --git a/scripts/create-pdns-zones-from-files b/scripts/create-pdns-zones-from-files new file mode 100755 index 0000000..d158aa4 --- /dev/null +++ b/scripts/create-pdns-zones-from-files @@ -0,0 +1,265 @@ +#!/bin/bash + +set -e +set -u + +BASE_NAME="$( basename ${0} )" +MY_REAL_NAME=$( readlink -f $0 ) +BIN_DIR=$( dirname "${MY_REAL_NAME}" ) + +RC_FILE='/usr/libexec/pixelpark/functions.rc' + +if [[ -f "${RC_FILE}" ]] ; then + . "${RC_FILE}" +else + echo "Bash resource file '${RC_FILE}' not found" >&2 + exit 5 +fi + +detect_color + +CUSTOMER='DNS:NET' +TSIG_KEY='pp-dns.com' +ERRORS="0" + +declare -a ZONE_FILES=() + +DESCRIPTION=$( cat <<-EOF + Creating zones from zone files on the local PowerDNS service. + + EOF +) + +#------------------------------------------------------------------------------ +usage() { + cat <<-EOF + Usage: ${BASE_NAME} [-C|--customer CUSTOMER] [--tsig-key KEY] [Common Options] ZONE_FILE [ZONE_FILE ...] + ${BASE_NAME} [-h|--help] + ${BASE_NAME} [-V|--version] + + Zone options: + -C|--customer CUSTOMER + The name of the customer or registrar of the zone. + Use 'local' or 'private' to create a private zone, which is + not mirrored at the authoritative name servers. + Default: '${CUSTOMER}'. + --tsig-key KEY The name of the TSIG key, which has to be used by secondary + servers on transfering the zone. Defaut: '${TSIG_KEY}'. + + Common Options: + ${STD_USAGE_MSG} + EOF + +} + +#------------------------------------------------------------------------------ +get_options() { + + local tmp= + local base_dir= + + set +e + tmp=$( getopt -o ${STD_SHORT_OPTIONS}C: \ + --long ${STD_LONG_OPTIONS},customer:,tsig-key: \ + -n "${BASE_NAME}" -- "$@" ) + if [[ $? != 0 ]] ; then + echo "" >&2 + usage >&2 + exit 1 + fi + set -e + + # Note the quotes around `$TEMP': they are essential! + eval set -- "${tmp}" + eval_common_options "$@" + if [[ "${DEBUG}" == 'y' ]] ; then + declare -p REMAINING_OPTS + declare -p REMAINING_ARGS + fi + + local len="${#REMAINING_OPTS[*]}" + local i="0" + local j= + local arg= + + while [[ "$i" -lt "${len}" ]] ; do + + j=$(( $i + 1 )) + arg="${REMAINING_OPTS[$i]}" + + case "${arg}" in + -C|--customer) + CUSTOMER="${REMAINING_OPTS[$j]}" + i=$(( $i + 2 )) + ;; + --tsig-key) + TSIG_KEY="${REMAINING_OPTS[$j]}" + i=$(( $i + 2 )) + ;; + *) echo -e "Internal error - option '${RED}${arg}${NORMAL} was wrong!" + exit 1 + ;; + esac + + done + + if [[ "${#REMAINING_OPTS[@]}" -gt 0 ]] ; then + error "Unknown options: ${REMAINING_OPTS[*]}" + echo >&2 + usage >&2 + exit 1 + fi + + if [[ "${#REMAINING_ARGS[@]}" == "0" ]] ; then + error "No zone files for loading into PowerDNS given." + echo >&2 + usage >&2 + exit 1 + fi + + i="0" + for arg in "${REMAINING_ARGS[@]}" ; do + if [[ "${i}" == "0" && "${arg}" == '--' ]] ; then + continue + fi + i=$(( $i + 1 )) + ZONE_FILES+=( "${arg}" ) + done + + if [[ "${#ZONE_FILES[@]}" == "0" ]] ; then + error "No zone files for loading into PowerDNS given." + echo >&2 + usage >&2 + exit 1 + fi + + if [[ $(id -u -n) != "root" ]] ; then + error "You must ${RED}be root${NORMAL} to execute this script!" >&2 + exit 1 + fi + + local zone_file= + local found=y + for zone_file in "${ZONE_FILES[@]}" ; do + if [[ ! -f "${zone_file}" ]] ; then + error "Zone file '${RED}${zone_file}${NORMAL}' not found." + found=n + fi + done + if [[ "${found}" == 'n' ]] ; then + exit 1 + fi + + local cmd= + for cmd in pdns_control pdnsutil; do + if [[ -z $( type -p "${cmd}" ) ]] ; then + error "Command '${RED}${cmd}${NORMAL}' not found." + exit 5 + fi + done + + local pong=$( pdns_control rping | tr '[:upper:]' '[:lower:]' || true ) + if [[ "${pong}" != 'pong' ]] ; then + error "The PowerDNS server service seems not to be active and running." + exit 2 + fi + +} + +#------------------------------------------------------------------------------ +create_zone() { + + local zone_file="$1" + + local zone=$( grep -P -i '^\S+\s+\d+\s+IN\s+SOA\s' "${zone_file}" | \ + grep -P -o '^(\S+)' | \ + sed -e 's/\.*$//' ) + + if [[ -z "${zone}" ]] ; then + error "Did not found a valid SOA record in zone file '${RED}${zone_file}${NORMAL}'." + ERRORS=$(( $ERRORS + 1 )) + return + fi + + local existing=$( pdnsutil list-zone "${zone}" 2>/dev/null || true ) + if [[ -n "${existing}" ]] ; then + error "Zone '${RED}${zone}${NORMAL}' is already existing in PowerDNS." + ERRORS=$(( $ERRORS + 1 )) + return + fi + + empty_line + line + info "Creating zone '${GREEN}${zone}${NORMAL}' from file '${CYAN}${zone_file}${NORMAL}' ..." + empty_line + + local cmd= + + cmd="pdnsutil load-zone \"${zone}\" \"${zone_file}\"" + if [[ "${SIMULATE}" == "y" ]] ; then + info "Executing: ${cmd}" + else + debug "Executing: ${cmd}" + fi + + cmd="pdnsutil set-account \"${zone}\" \"${CUSTOMER}\"" + if [[ "${SIMULATE}" == "y" ]] ; then + info "Executing: ${cmd}" + else + debug "Executing: ${cmd}" + fi + + cmd="pdnsutil set-kind \"${zone}\" \"master\"" + if [[ "${SIMULATE}" == "y" ]] ; then + info "Executing: ${cmd}" + else + debug "Executing: ${cmd}" + fi + + cmd="pdnsutil set-meta \"${zone}\" \"SOA-EDIT-API\" \"DEFAULT\"" + if [[ "${SIMULATE}" == "y" ]] ; then + info "Executing: ${cmd}" + else + debug "Executing: ${cmd}" + fi + + cmd="pdnsutil set-meta \"${zone}\" \"TSIG-ALLOW-AXFR\" \"${TSIG_KEY}\"" + if [[ "${SIMULATE}" == "y" ]] ; then + info "Executing: ${cmd}" + else + debug "Executing: ${cmd}" + fi + +} + +################################################################################ +## +## Main +## +################################################################################ + +#------------------------------------------------------------------------------ +main() { + + get_options "$@" + + set_locale 'en_US.utf8' + + local zone_file= + for zone_file in "${ZONE_FILES[@]}" ; do + create_zone "${zone_file}" + done + + empty_line + info "Finished." + +} + +main "$@" + +if [[ "${ERRORS}" != "0" ]] ; then + exit 6 +fi +exit 0 + +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list