Merge lp:~brad-marshall/charms/trusty/nrpe-external-master/add-daemon-checks into lp:charms/nrpe-external-master

Proposed by Brad Marshall
Status: Merged
Approved by: Brad Marshall
Approved revision: 37
Merged at revision: 37
Proposed branch: lp:~brad-marshall/charms/trusty/nrpe-external-master/add-daemon-checks
Merge into: lp:charms/nrpe-external-master
Diff against target: 341 lines (+317/-0)
4 files modified
files/check_exit_status.pl (+189/-0)
files/check_status_file.py (+54/-0)
files/check_upstart_job (+72/-0)
hooks/install (+2/-0)
To merge this branch: bzr merge lp:~brad-marshall/charms/trusty/nrpe-external-master/add-daemon-checks
Reviewer Review Type Date Requested Status
Review Queue (community) automated testing Needs Fixing
JuanJo Ciarlante (community) Approve
Review via email: mp+242037@code.launchpad.net

Description of the change

Added nagios checks for monitoring upstart and sysvinit daemons

To post a comment you must log in.
Revision history for this message
JuanJo Ciarlante (jjo) wrote :

As per inline comments - please remove the puppet header, also suggest adding a 'juju' one, LGTM afterwards.

37. By Brad Marshall

[bradm] Replaced puppet header with juju one

Revision history for this message
JuanJo Ciarlante (jjo) wrote :

LGTM.

review: Approve
Revision history for this message
Review Queue (review-queue) wrote :

This items has failed automated testing! Results available here http://reports.vapour.ws/charm-tests/charm-bundle-test-10337-results

review: Needs Fixing (automated testing)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'files/check_exit_status.pl'
2--- files/check_exit_status.pl 1970-01-01 00:00:00 +0000
3+++ files/check_exit_status.pl 2014-11-20 01:02:07 +0000
4@@ -0,0 +1,189 @@
5+#!/usr/bin/perl
6+################################################################################
7+# #
8+# Copyright (C) 2011 Chad Columbus <ccolumbu@hotmail.com> #
9+# #
10+# This program is free software; you can redistribute it and/or modify #
11+# it under the terms of the GNU General Public License as published by #
12+# the Free Software Foundation; either version 2 of the License, or #
13+# (at your option) any later version. #
14+# #
15+# This program is distributed in the hope that it will be useful, #
16+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
17+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18+# GNU General Public License for more details. #
19+# #
20+# You should have received a copy of the GNU General Public License #
21+# along with this program; if not, write to the Free Software #
22+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
23+# #
24+################################################################################
25+
26+use strict;
27+use Getopt::Std;
28+$| = 1;
29+
30+my %opts;
31+getopts('heronp:s:', \%opts);
32+
33+my $VERSION = "Version 1.0";
34+my $AUTHOR = '(c) 2011 Chad Columbus <ccolumbu@hotmail.com>';
35+
36+# Default values:
37+my $script_to_check;
38+my $pattern = 'is running';
39+my $cmd;
40+my $message;
41+my $error;
42+
43+# Exit codes
44+my $STATE_OK = 0;
45+my $STATE_WARNING = 1;
46+my $STATE_CRITICAL = 2;
47+my $STATE_UNKNOWN = 3;
48+
49+# Parse command line options
50+if ($opts{'h'} || scalar(%opts) == 0) {
51+ &print_help();
52+ exit($STATE_OK);
53+}
54+
55+# Make sure scipt is provided:
56+if ($opts{'s'} eq '') {
57+ # Script to run not provided
58+ print "\nYou must provide a script to run. Example: -s /etc/init.d/httpd\n";
59+ exit($STATE_UNKNOWN);
60+} else {
61+ $script_to_check = $opts{'s'};
62+}
63+
64+# Make sure only a-z, 0-9, /, _, and - are used in the script.
65+if ($script_to_check =~ /[^a-z0-9\_\-\/\.]/) {
66+ # Script contains illegal characters exit.
67+ print "\nScript to check can only contain Letters, Numbers, Periods, Underscores, Hyphens, and/or Slashes\n";
68+ exit($STATE_UNKNOWN);
69+}
70+
71+# See if script is executable
72+if (! -x "$script_to_check") {
73+ print "\nIt appears you can't execute $script_to_check, $!\n";
74+ exit($STATE_UNKNOWN);
75+}
76+
77+# If a pattern is provided use it:
78+if ($opts{'p'} ne '') {
79+ $pattern = $opts{'p'};
80+}
81+
82+# If -r run command via sudo as root:
83+if ($opts{'r'}) {
84+ $cmd = "sudo -n $script_to_check status" . ' 2>&1';
85+} else {
86+ $cmd = "$script_to_check status" . ' 2>&1';
87+}
88+
89+my $cmd_result = `$cmd`;
90+chomp($cmd_result);
91+if ($cmd_result =~ /sudo/i) {
92+ # This means it could not run the sudo command
93+ $message = "$script_to_check CRITICAL - Could not run: 'sudo -n $script_to_check status'. Result is $cmd_result";
94+ $error = $STATE_UNKNOWN;
95+} else {
96+ # Check exitstatus instead of output:
97+ if ($opts{'e'} == 1) {
98+ if ($? != 0) {
99+ # error
100+ $message = "$script_to_check CRITICAL - Exit code: $?\.";
101+ if ($opts{'o'} == 0) {
102+ $message .= " $cmd_result";
103+ }
104+ $error = $STATE_CRITICAL;
105+ } else {
106+ # success
107+ $message = "$script_to_check OK - Exit code: $?\.";
108+ if ($opts{'o'} == 0) {
109+ $message .= " $cmd_result";
110+ }
111+ $error = $STATE_OK;
112+ }
113+ } else {
114+ my $not_check = 1;
115+ if ($opts{'n'} == 1) {
116+ $not_check = 0;
117+ }
118+ if (($cmd_result =~ /$pattern/i) == $not_check) {
119+ $message = "$script_to_check OK";
120+ if ($opts{'o'} == 0) {
121+ $message .= " - $cmd_result";
122+ }
123+ $error = $STATE_OK;
124+ } else {
125+ $message = "$script_to_check CRITICAL";
126+ if ($opts{'o'} == 0) {
127+ $message .= " - $cmd_result";
128+ }
129+ $error = $STATE_CRITICAL;
130+ }
131+ }
132+}
133+
134+if ($message eq '') {
135+ print "Error: program failed in an unknown way\n";
136+ exit($STATE_UNKNOWN);
137+}
138+
139+if ($error) {
140+ print "$message\n";
141+ exit($error);
142+} else {
143+ # If we get here we are OK
144+ print "$message\n";
145+ exit($STATE_OK);
146+}
147+
148+####################################
149+# Start Subs:
150+####################################
151+sub print_help() {
152+ print << "EOF";
153+Check the output or exit status of a script.
154+$VERSION
155+$AUTHOR
156+
157+Options:
158+-h
159+ Print detailed help screen
160+
161+-s
162+ 'FULL PATH TO SCRIPT' (required)
163+ This is the script to run, the script is designed to run scripts in the
164+ /etc/init.d dir (but can run any script) and will call the script with
165+ a 'status' argument. So if you use another script make sure it will
166+ work with /path/script status, example: /etc/init.d/httpd status
167+
168+-e
169+ This is the "exitstaus" flag, it means check the exit status
170+ code instead of looking for a pattern in the output of the script.
171+
172+-p 'REGEX'
173+ This is a pattern to look for in the output of the script to confirm it
174+ is running, default is 'is running', but not all init.d scripts output
175+ (iptables), so you can specify an arbitrary pattern.
176+ All patterns are case insensitive.
177+
178+-n
179+ This is the "NOT" flag, it means not the -p pattern, so if you want to
180+ make sure the output of the script does NOT contain -p 'REGEX'
181+
182+-r
183+ This is the "ROOT" flag, it means run as root via sudo. You will need a
184+ line in your /etc/sudoers file like:
185+ nagios ALL=(root) NOPASSWD: /etc/init.d/* status
186+
187+-o
188+ This is the "SUPPRESS OUTPUT" flag. Some programs have a long output
189+ (like iptables), this flag suppresses that output so it is not printed
190+ as a part of the nagios message.
191+EOF
192+}
193+
194
195=== added file 'files/check_status_file.py'
196--- files/check_status_file.py 1970-01-01 00:00:00 +0000
197+++ files/check_status_file.py 2014-11-20 01:02:07 +0000
198@@ -0,0 +1,54 @@
199+#!/usr/bin/python
200+#--------------------------------------------------------
201+# This file is managed by Juju
202+#--------------------------------------------------------
203+
204+#
205+# Copyright 2014 Canonical Ltd.
206+#
207+# Author: Jacek Nykis <jacek.nykis@canonical.com>
208+#
209+
210+import re
211+import nagios_plugin
212+
213+
214+def parse_args():
215+ import argparse
216+
217+ parser = argparse.ArgumentParser(
218+ description='Read file and return nagios status based on its content',
219+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
220+ parser.add_argument('-f', '--status-file', required=True,
221+ help='Status file path')
222+ parser.add_argument('-c', '--critical-text', default='CRITICAL',
223+ help='String indicating critical status')
224+ parser.add_argument('-w', '--warning-text', default='WARNING',
225+ help='String indicating warning status')
226+ parser.add_argument('-o', '--ok-text', default='OK',
227+ help='String indicating OK status')
228+ parser.add_argument('-u', '--unknown-text', default='UNKNOWN',
229+ help='String indicating unknown status')
230+ return parser.parse_args()
231+
232+
233+def check_status(args):
234+ nagios_plugin.check_file_freshness(args.status_file, 43200)
235+
236+ with open(args.status_file, "r") as f:
237+ content = [l.strip() for l in f.readlines()]
238+
239+ for line in content:
240+ if re.search(args.critical_text, line):
241+ raise nagios_plugin.CriticalError(line)
242+ elif re.search(args.warning_text, line):
243+ raise nagios_plugin.WarnError(line)
244+ elif re.search(args.unknown_text, line):
245+ raise nagios_plugin.UnknownError(line)
246+ else:
247+ print line
248+
249+
250+if __name__ == '__main__':
251+ args = parse_args()
252+ nagios_plugin.try_check(check_status, args)
253
254=== added file 'files/check_upstart_job'
255--- files/check_upstart_job 1970-01-01 00:00:00 +0000
256+++ files/check_upstart_job 2014-11-20 01:02:07 +0000
257@@ -0,0 +1,72 @@
258+#!/usr/bin/python
259+
260+#
261+# Copyright 2012, 2013 Canonical Ltd.
262+#
263+# Author: Paul Collins <paul.collins@canonical.com>
264+#
265+# Based on http://www.eurion.net/python-snippets/snippet/Upstart%20service%20status.html
266+#
267+
268+import sys
269+
270+import dbus
271+
272+
273+class Upstart(object):
274+ def __init__(self):
275+ self._bus = dbus.SystemBus()
276+ self._upstart = self._bus.get_object('com.ubuntu.Upstart',
277+ '/com/ubuntu/Upstart')
278+ def get_job(self, job_name):
279+ path = self._upstart.GetJobByName(job_name,
280+ dbus_interface='com.ubuntu.Upstart0_6')
281+ return self._bus.get_object('com.ubuntu.Upstart', path)
282+
283+ def get_properties(self, job):
284+ path = job.GetInstance([], dbus_interface='com.ubuntu.Upstart0_6.Job')
285+ instance = self._bus.get_object('com.ubuntu.Upstart', path)
286+ return instance.GetAll('com.ubuntu.Upstart0_6.Instance',
287+ dbus_interface=dbus.PROPERTIES_IFACE)
288+
289+ def get_job_instances(self, job_name):
290+ job = self.get_job(job_name)
291+ paths = job.GetAllInstances([], dbus_interface='com.ubuntu.Upstart0_6.Job')
292+ return [self._bus.get_object('com.ubuntu.Upstart', path) for path in paths]
293+
294+ def get_job_instance_properties(self, job):
295+ return job.GetAll('com.ubuntu.Upstart0_6.Instance',
296+ dbus_interface=dbus.PROPERTIES_IFACE)
297+
298+try:
299+ upstart = Upstart()
300+ try:
301+ job = upstart.get_job(sys.argv[1])
302+ props = upstart.get_properties(job)
303+
304+ if props['state'] == 'running':
305+ print 'OK: %s is running' % sys.argv[1]
306+ sys.exit(0)
307+ else:
308+ print 'CRITICAL: %s is not running' % sys.argv[1]
309+ sys.exit(2)
310+
311+ except dbus.DBusException as e:
312+ instances = upstart.get_job_instances(sys.argv[1])
313+ propses = [upstart.get_job_instance_properties(instance) for instance in instances]
314+ states = dict([(props['name'], props['state']) for props in propses])
315+ if len(states) != states.values().count('running'):
316+ not_running = []
317+ for name in states.keys():
318+ if states[name] != 'running':
319+ not_running.append(name)
320+ print 'CRITICAL: %d instances of %s not running: %s' % \
321+ (len(not_running), sys.argv[1], not_running.join(', '))
322+ sys.exit(2)
323+ else:
324+ print 'OK: %d instances of %s running' % (len(states), sys.argv[1])
325+
326+except dbus.DBusException as e:
327+ print 'CRITICAL: failed to get properties of \'%s\' from upstart' % sys.argv[1]
328+ sys.exit(2)
329+
330
331=== modified file 'hooks/install'
332--- hooks/install 2014-11-06 07:40:09 +0000
333+++ hooks/install 2014-11-20 01:02:07 +0000
334@@ -14,6 +14,8 @@
335 cp files/nagios_plugin.py /usr/lib/nagios/plugins/nagios_plugin.py
336 ln -fs /usr/lib/nagios/plugins/nagios_plugin.py /usr/local/lib/nagios/plugins/nagios_plugin.py
337
338+cp files/check_* /usr/local/lib/nagios/plugins/
339+
340 cp files/default_rsync /etc/default/rsync
341 cp files/rsyncd.conf /etc/rsyncd.conf
342

Subscribers

People subscribed via source and target branches

to all changes: