diff --git a/heartbeat/dnsupdate.in b/heartbeat/dnsupdate.in index 1ecbadf18..34a6c56f3 100644 --- a/heartbeat/dnsupdate.in +++ b/heartbeat/dnsupdate.in @@ -1,276 +1,297 @@ #!@BASH_SHELL@ # # # Support: users@clusterlabs.org # License: GNU General Public License v2 # # Copyright (c) 2014 SUSE Linux Products GmbH, Lars Marowsky-Brée # All Rights Reserved. # ####################################################################### : ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat} . ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs + +# Parameter defaults + +OCF_RESKEY_hostname_default="" +OCF_RESKEY_ip_default="" +OCF_RESKEY_ttl_default="300" +OCF_RESKEY_keyfile_default="" +OCF_RESKEY_server_default="" +OCF_RESKEY_serverport_default="53" +OCF_RESKEY_nsupdate_opts_default="" +OCF_RESKEY_unregister_on_stop_default="false" + +: ${OCF_RESKEY_hostname=${OCF_RESKEY_hostname_default}} +: ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}} +: ${OCF_RESKEY_ttl=${OCF_RESKEY_ttl_default}} +: ${OCF_RESKEY_keyfile=${OCF_RESKEY_keyfile_default}} +: ${OCF_RESKEY_server=${OCF_RESKEY_server_default}} +: ${OCF_RESKEY_serverport=${OCF_RESKEY_serverport_default}} +: ${OCF_RESKEY_nsupdate_opts=${OCF_RESKEY_nsupdate_opts_default}} +: ${OCF_RESKEY_unregister_on_stop=${OCF_RESKEY_unregister_on_stop_default}} + ####################################################################### # TODO: # - Should setting CNAMEs be supported? # - Should multiple A records be supported? usage() { cat <<-! usage: $0 {start|stop|status|monitor|meta-data|validate-all} ! } meta_data() { cat < 1.0 This resource agent manages IP take-over via dynamic DNS updates. IP take-over via dynamic DNS update The hostname whose IP address will need to be updated. Hostname to update - + IP address to set. IP address to set - + Time to live, in seconds, for the DNS record. This affects how soon DNS updates propagate. It should be a reasonable compromise between update speed and DNS server load. If using booth, the ticket timeout is a good start. TTL for the DNS record - + The file containing the shared secret needed to update the DNS record. Please see the nsupdate man page for the exact syntax. nsupdate key file - + Which DNS server to send these updates for. When no server is provided, this defaults to the master server for the correct zone. DNS server to contact - + Port number on the DNS server. Note: due to a limitation in the nsupdate command, this option will only take effect if you also specify the DNS server! Port number on the DNS server - + Additional options to be passed to nsupdate. Additional nsupdate options - + Whether or not to actively remove records on stop. This is not needed for normal operation, since the site taking over the IP address will delete all previous records. Remove A record on stop - + END } dnsupdate_status() { # The resource is considered active if the current IP # address is returned as the only response. local record=$(dig ${dig_opts} ${hostname}. A +short 2>/dev/null) if [ "$record" = "$ip" ]; then return $OCF_SUCCESS fi return $OCF_NOT_RUNNING } dnsupdate_monitor() { if ocf_is_probe ; then # return $OCF_NOT_RUNNING fi dnsupdate_status } dnsupdate_start() { if dnsupdate_status ; then ocf_log info "$hostname already resolves to $ip" return $OCF_SUCCESS fi ocf_log info "Updating DNS records for $hostname" ( if [ -n "$dns_server" ]; then echo "server ${dns_server} ${dns_serverport}" fi echo "update delete $hostname A" echo "update add $hostname ${OCF_RESKEY_ttl} A $ip" echo "send" ) | nsupdate ${nsupdate_opts} dnsupdate_monitor return $? } dnsupdate_stop() { if ocf_is_true "${OCF_RESKEY_unregister_on_stop}" && dnsupdate_status ; then ocf_log info "Unregistering $hostname with $ip from DNS server" ( if [ -n "$dns_server" ]; then echo "server ${dns_server} ${dns_serverport}" fi echo "update delete $hostname A $ip" echo "send" ) | nsupdate ${nsupdate_opts} dnsupdate_monitor if [ $? -ne $OCF_NOT_RUNNING ]; then ocf_log warn "Unregistering failed!" # There's no point in invoking a stop failure # here. If another site takes over the record, # it'll delete all previous entries anyway. fi fi return $OCF_SUCCESS } dnsupdate_validate() { hostname=${OCF_RESKEY_hostname} ip=${OCF_RESKEY_ip} dig_opts="" dns_server=${OCF_RESKEY_server} : ${OCF_RESKEY_serverport:="53"} dns_serverport=${OCF_RESKEY_serverport} : ${OCF_RESKEY_ttl:="300"} nsupdate_opts=${OCF_RESKEY_nsupdate_opts} if [ -z "$nsupdate_opts" -a -n "$OCF_RESKEY_opts" ]; then nsupdate_opts=${OCF_RESKEY_opts} ocf_log warn "opts was never an advertised parameter, please use nsupdate_opts" fi if [ -z "$hostname" ]; then ocf_log err "No hostname specified." exit $OCF_ERR_CONFIGURED fi if [ -z "$ip" ]; then ocf_log err "No IP specified." exit $OCF_ERR_CONFIGURED fi if ! ocf_is_decimal $OCF_RESKEY_ttl ; then ocf_log err "ttl $OCF_RESKEY_ttl is not valid" exit $OCF_ERR_CONFIGURED fi if ! ocf_is_decimal $dns_serverport ; then ocf_log err "serverport $dns_serverport is not valid" exit $OCF_ERR_CONFIGURED fi dig_opts+=" -p ${dns_serverport}" if [ -n "$dns_server" ]; then dig_opts+=" @${dns_server}" fi if [ -n "$OCF_RESKEY_keyfile" ]; then if [ ! -f ${OCF_RESKEY_keyfile} ]; then ocf_log err "keyfile $OCF_RESKEY_keyfile does not exist" exit $OCF_ERR_CONFIGURED fi nsupdate_opts+=" -k $OCF_RESKEY_keyfile" fi } if [ $# -ne 1 ]; then usage exit $OCF_ERR_ARGS fi case $1 in meta-data) meta_data exit $OCF_SUCCESS ;; usage) usage exit $OCF_SUCCESS ;; esac check_binary dig check_binary nsupdate dnsupdate_validate case $1 in start) dnsupdate_start ;; stop) dnsupdate_stop ;; monitor) dnsupdate_monitor ;; status) dnsupdate_status ;; validate-all) # We've already run this exit $OCF_SUCCESS ;; *) usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $?