aboutsummaryrefslogtreecommitdiff
path: root/nagios-acknowledge
blob: 5fc6703488c643de5cf8b5974e194030e7b2a6c2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/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 (<host[/service][,host[/service],...>|-) [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 <tom@sanctum.geek.nz>
# Copyright: 2016
#

# Name self
self=nagios-acknowledge

# Usage printing function
usage() {
    printf 'USAGE: %s [-n] (<host[/service][,host[/service],...>|-) [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
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

# There must be at least one object
if ! ((${#objects[@]})) ; then
    printf '%s: At least one host/service must be given\n' \
        "$self" >&2
    exit 1
fi

# 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