#!/usr/bin/env bash # # nagios-acknowledge(1) -- Shortcut to acknowledge problems in Nagios, because # it's annoying to do with the web interface for large sets of hosts or # services. # # $ nac (|-) [optional comment] # # You can specify multiple objects by separating them with commas: # # $ nac abc-example-ap-1,abc-example-ap-2/VOLTAGE 'Power problems at abc-example' # # Even easier is to pipe them into stdin by specifying - as the object: # # $ nul | grep abc-example | nac - 'Power problems at abc-example' # # By default, does not send ACKNOWLEDGEMENT notifications. Use -n if you do # want that. # # Author: Tom Ryder # Copyright: 2016 # # Name self self=nagios-acknowledge # Usage printing function usage() { printf 'USAGE: %s [-n] (|-) [comment]\n' "$self" } # Default to not notifying notify=0 # Figure out whether we should notify OPTIND=1 while getopts 'hn' opt ; do case $opt in n) notify=1 ;; h) usage exit 0 ;; '?') usage >&2 exit 1 ;; esac done shift "$((OPTIND-1))" # Bail if no arguments left; we need at least the host/service name if ! (($#)) ; then usage >&2 exit 1 fi # Define relatively fixed/guaranteed fields for Nagios command; note that the # comment has a default of 'no comment given' now=$(date +%s) spec=$1 sticky=1 notify=$notify persistent=1 author=${SUDO_USER:-$USER} comment=${2:-'no comment given'} cmdfile=${NAGCMD_FILE:-/usr/local/nagios/var/rw/nagios.cmd} # How to get the objects depends on the spec (the first argument) declare -a objects case $spec in # If the spec is just "-", we just read unique objects from stdin -) while read -r object ; do [[ $object ]] || continue objects[${#objects[@]}]=$object done < <(sort -u) ;; # If the spec is anything else, we break it up with commas and read the # objects that way *) IFS=, read -a objects -r < <(printf '%s\n' "$spec") ;; esac # All the hosts or services must exist, just to be strict; they don't # necessarily have to be in a PROBLEM state though for object in "${objects[@]}" ; do nagios-exists "$object" && continue printf '%s: Host/service %s does not seem to exist\n' \ "$self" "$object" >&2 exit 1 done # Quietly replace semicolons in comment with commas comment=${comment//;/,} # Write commands to schedule downtime for each of the objects, bail if a single # one of them fails for object in "${objects[@]}" ; do case $object in */*) host=${object%/*} service=${object##*/} cmd=$(printf '[%lu] ACKNOWLEDGE_SVC_PROBLEM;%s;%s;%u;%u;%u;%s;%s' \ "$now" "$host" "$service" \ "$sticky" "$notify" "$persistent" "$author" "$comment") ;; *) host=$object cmd=$(printf '[%lu] ACKNOWLEDGE_HOST_PROBLEM;%s;%u;%u;%u;%s;%s' \ "$now" "$host" \ "$sticky" "$notify" "$persistent" "$author" "$comment") ;; esac printf '%s\n' "$cmd" > "$cmdfile" || exit done # Attempt to write command to file if ! printf '%s\n' "$cmd" > "$cmdfile" ; then printf '%s: Failed to write command to file\n' "$self" >&2 exit 1 fi