summaryrefslogtreecommitdiff
path: root/usr-lib-nagios-plugins/check_needs-rebooting.sh
blob: 48c25bac5b61d9a08cb379dd625cca9a412e5aa8 (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
#!/bin/bash

#set -x

# License: The BSD 3-Clause License
#
# Copyright (c) 2014, Johan Ryberg
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#  this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#  this list of conditions and the following disclaimer in the documentation
#  and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
#  may be used to endorse or promote products derived from this software without
#  specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#  POSSIBILITY OF SUCH DAMAGE.
#
# check_reboot-required
# Plugin for NRPE (Nagios Remote Plugin Executor) for
# Debian/Ubuntu/RedHat/CentOS to check if a reboot are required and
# also list packages that requires reboot
# Web: https://github.com/jryberg/nagios-plugins/

APPNAME=`basename $0`
VERSION="1.0"

# Defining standard messages and exit error levels
# https://nagios-plugins.org/doc/guidelines.html
OK_EXIT_CODE=0
WARNING_EXIT_CODE=1
CRITICAL_EXIT_CODE=2
UNKNOWN_EXIT_CODE=3
OK_MSG="OK"
WARNING_MSG="Warning"
CRITICAL_MSG="Critical"
UNKNOWN_MSG="Unknown"

# Using Unknown as default
EXIT_CODE=$UNKNOWN_EXIT_CODE
EXIT_MSG=$UNKNOWN_MSG

# Stupid warning and critical levels, this cannot be determined by numbers
# some may want to have this anyway. Default will be a warning if a reboot
# are required and never critical
# -1 = disable service status
WARNING_LEVEL=1
CRITICAL_LEVEL=-1

# Path to reboot-required
REBOOT_REQUIRED_PATH="/var/run/reboot-required"
REBOOT_REQUIRED_PKGS_PATH="/var/run/reboot-required.pkgs"

# Function to explain how to use the program
function_usage () {
cat - <<EOF
Usage: ${appname} [--help]
Usage: ${appname} -d status [-w warn] [-c crit]

This check command checks if a reboot are required after an upgrade. It will
also list packages that requires a reboot to ease the decision for the
sysadmin if/when a reboot needs to be carried out.

WARNING: It's impossible by numbers to decide if a reboot are required by
raising a "warning" or "critical" event. A patch for 0-day vulnerability
will probably required immediate attention and less important updates can
wait until next scheduled maintenance window. Please read documentation
for each update.

Default without any options will be Warning for 1 or more packages
that requires reboot. Critical event will not be raised.

 --help
    Show this help
 -V, --version
    Show version
 -s
    Default service status when reboot are needed but package information
    are missing. w=Warning, c=Critical
 -w
    Warning: Number of packages needing reboot as integer. Default: 1
 -c
    Critical: Number of packages needing reboot as integer. Disabled as default

Example:
${APPNAME} -s w

EOF
}

function distro_name() {
	if [[ -e /etc/redhat-release ]]; then
		REDHAT_RELEASE=`cat /etc/redhat-release`
		if [[ `cat /etc/redhat-release | grep CentOS` != "" ]]; then
			echo "CentOS"
		elif [[ `cat /etc/redhat-release | grep "Red Hat"` != "" ]]; then
			echo "Red Hat"
		else
			echo "$REDHAT_RELEASE"
		fi
	elif [[ -e /etc/lsb-release ]]; then
		. /etc/lsb-release
		echo $DISTRIB_ID
	elif [[ -e /etc/debian_version ]]; then
		DEBIAN_VER=`cat /etc/debian_version`
		echo "Debian"
	else
		echo "OS not recognized"
	fi
}

function CheckDebianRebootRequired() {
	if [ ! -f ${REBOOT_REQUIRED_PATH} ]; then
		# Reboot not required
		EXIT_MSG=$OK_MSG
		EXIT_MSG_BODY="No reboot required|Packages=0;${WARNING_LEVEL//-1/};${CRITICAL_LEVEL//-1/};0"
		EXIT_MSG_NR_PACKAGES=0
		EXIT_CODE=$OK_EXIT_CODE
	else
		# Reboot required
		NR_OF_PACKAGES=0
		if [ -f ${REBOOT_REQUIRED_PKGS_PATH} ]; then
			NR_OF_PACKAGES=`wc -l ${REBOOT_REQUIRED_PKGS_PATH} | awk '{ print $1 }'`
		fi
		if [ ${NR_OF_PACKAGES} -gt 0 ]; then
			if [ ${NR_OF_PACKAGES} -ge ${CRITICAL_LEVEL} ] && [ ${CRITICAL_LEVEL} -ne "-1" ];then
				EXIT_MSG=$CRITICAL_MSG
				EXIT_CODE=$CRITICAL_EXIT_CODE
			elif [ ${NR_OF_PACKAGES} -ge ${WARNING_LEVEL} ] && [ ${WARNING_LEVEL} -ne "-1" ];then
				EXIT_MSG=$WARNING_MSG
				EXIT_CODE=$WARNING_EXIT_CODE
			else
				EXIT_MSG=$OK_MSG
				EXIT_CODE=$OK_EXIT_CODE
			fi
			EXIT_MSG_BODY="`cat ${REBOOT_REQUIRED_PATH}`<br/>Packages:<br/>`cat ${REBOOT_REQUIRED_PKGS_PATH} | sed ':a;N;$!ba;s/\n/<br\/>/g'`|Packages=${NR_OF_PACKAGES};${WARNING_LEVEL//-1/};${CRITICAL_LEVEL//-1/};0"
		else
			if [[ ${STATUS} = "w" ]]; then
				EXIT_MSG=$WARNING_MSG
				EXIT_CODE=$WARNING_EXIT_CODE
			else
				EXIT_MSG=$CRITICAL_MSG
				EXIT_CODE=$CRITICAL_EXIT_CODE
			fi
			EXIT_MSG_BODY="`cat ${REBOOT_REQUIRED_PATH}`|Packages=U;${WARNING_LEVEL//-1/};${CRITICAL_LEVEL//-1/};0"
		fi
	fi
}

function CheckRedHatRebootRequired() {
	LAST_KERNEL=`/bin/rpm -q --last kernel | /usr/bin/head -1 | /usr/bin/perl -pe 's/^kernel-(\S+).*/$1/'`
	RUNNING_KERNEL=`uname -r`

	if [[ $LAST_KERNEL != $RUNNING_KERNEL ]]; then
		EXIT_MSG=$CRITICAL_MSG
		EXIT_MSG_BODY="Reboot required, the running kernel ($RUNNING_KERNEL) is different from the last kernel installed ($LAST_KERNEL)."
		EXIT_MSG_NR_PACKAGES=1
		EXIT_CODE=$CRITICAL_EXIT_CODE
	else
		EXIT_MSG=$OK_MSG
		EXIT_MSG_BODY="No reboot required|Packages=0;${WARNING_LEVEL//-1/};${CRITICAL_LEVEL//-1/};0"
		EXIT_MSG_NR_PACKAGES=0
		EXIT_CODE=$OK_EXIT_CODE
	fi
}
# Process arguments
while [ $# -gt 0 ]; do
	OPT="$1"
	case "${OPT}" in
		--help)
			function_usage
			exit $OK_EXIT_CODE
		;;
		-s)
			shift
			case $1 in
				w|c)
					STATUS="${1}"
				;;
				*)
					echo "${APPNAME}: Service status must be w (Warning) or c (Critical)"
					exit $UNKNOWN_EXIT_CODE
				;;
			esac
			shift
		;;
		-w)
			shift
			if [[ ${1} =~ ^[0-9]+$ ]]; then
				WARNING_LEVEL="${1}"
			else
				echo "${APPNAME}: Warning level must be positive integer"
				exit $UNKNOWN_EXIT_CODE
			fi
			shift
		;;
		-c)
			shift
			if [[ ${1} =~ ^[0-9]+$ ]]; then
				CRITICAL_LEVEL="${1}"
			else
				echo "${APPNAME}: Critical level must be positive integer"
				exit $UNKNOWN_EXIT_CODE
			fi
			shift
		;;
		--version|-V)
			echo "${APPNAME} ${VERSION}"
			exit $OK_EXIT_CODE
		;;
		*)
			echo "${APPNAME}: invalid option '${1}'"
			echo "Try '${APPNAME} --help' for more information."
			exit $UNKNOWN_EXIT_CODE
		;;
	esac
done

if [ -z ${STATUS} ]; then
	echo "${APPNAME}: -s Status argument are missing"
	exit $UNKNOWN_EXIT_CODE
fi

case `distro_name` in
	"OS not recognized")
		echo "OS wasn't recognized, please report to maintainer of this script."
		exit $UNKNOWN_EXIT_CODE
	;;
	"Debian"|"Ubuntu")
		CheckDebianRebootRequired
	;;
	"Red Hat"|"CentOS")
		CheckRedHatRebootRequired
	;;
	*)
		echo "OS wasn't recognized, please report to maintainer of this script."
		exit $UNKNOWN_EXIT_CODE
	;;
esac

# Echo message and exit
echo "${EXIT_MSG}: ${EXIT_MSG_BODY}"
exit $EXIT_CODE