This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcheck_bacula_client
executable file
·98 lines (86 loc) · 4.23 KB
/
check_bacula_client
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
#!/usr/bin/env python
#
# check_bacula_client Nagios plugin to check Bacula client backups
# Copyright (C) 2010 Tom Payne
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime, timedelta
from optparse import OptionParser, OptionValueError
import re
import sys
import time
import pexpect
OK, WARNING, CRITICAL, UNKNOWN = xrange(0, 4)
status_message = 'OK WARNING CRITICAL UNKNOWN'.split()
MULTIPLIERS = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400, 'w': 604800}
DIVISORS = ((60, 'minutes'), (60, 'hours'), (24, 'days'), (7, 'weeks'))
def parse_period(option, opt_str, value, parser):
m = re.match(r'(\d+(?:\.\d+)?)(%s)\Z' % '|'.join(MULTIPLIERS.keys()), value)
if not m:
raise OptionValueError('invalid period - %s' % value)
setattr(parser.values, option.dest, timedelta(seconds=float(m.group(1)) * MULTIPLIERS[m.group(2)]))
def main(argv):
parser = OptionParser()
parser.add_option('-H', metavar='FD_NAME', dest='hostid', help='client file director name')
parser.add_option('-B', metavar='BACKUP_NAME', dest='backupid', help='backup job name')
parser.add_option('-w', metavar='PERIOD', type=str, dest='warning', action='callback', callback=parse_period, help='generate warning if last successful backup older than PERIOD')
parser.add_option('-c', metavar='PERIOD', type=str, dest='critical', action='callback', callback=parse_period, help='generate critical if last successful backup older than PERIOD')
parser.add_option('-b', metavar='PATH', dest='bconsole', help='path to bconsole')
parser.set_defaults(bconsole='/usr/sbin/bconsole')
options, args = parser.parse_args(argv[1:])
if not options.hostid or not options.backupid:
parser.error("-H and -B should be specified.")
exit_status, message = OK, None
child = pexpect.spawn(options.bconsole, ['-n'])
hostid = options.hostid
backupid = options.backupid
try:
child.expect(r'\n\*')
child.sendline('status client=%s' % hostid)
if child.expect_list([re.compile(r'Terminated Jobs:'), re.compile(r'Error: Client resource .* does not exist.'), pexpect.TIMEOUT]):
raise RuntimeError('Timeout or unknown client: %s' % hostid)
child.expect(r'\n\*')
r = re.compile(r'\s*(\d+)\s+(\S+)\s+(\S+)\s+(\d+\.\d+\s+[KMGTP]|\d+)\s+OK\s+(\S+\s+\S+)\s+%s' % re.escape(backupid))
job_id = level = files = bytes = finished = None
for line in child.before.splitlines():
m = r.match(line)
if m:
job_id = int(m.group(1))
level = m.group(2)
files = int(re.sub(r',', '', m.group(3)))
bytes = re.sub(r'\s+', '', m.group(4))
finished = datetime(*(time.strptime(m.group(5), '%d-%b-%y %H:%M')[0:6]))
if job_id is None:
raise RuntimeError('no terminated jobs')
age = datetime.now() - finished
if options.warning and age > options.warning:
exit_status = WARNING
if options.critical and age > options.critical:
exit_status = CRITICAL
age, units = 24.0 * 60 * 60 * age.days + age.seconds, 'seconds'
for d, u in DIVISORS:
if age < d:
break
else:
age /= d
units = u
message = '%s, %d files, %sB, %s (%.1f %s ago)' % (level, files, bytes, finished, age, units)
except RuntimeError:
exit_status, message = (CRITICAL, str(sys.exc_info()[1]))
child.sendeof()
child.expect_list([pexpect.EOF, pexpect.TIMEOUT])
print '%s: %s' % (status_message[exit_status], message)
sys.exit(exit_status)
if __name__ == '__main__':
main(sys.argv)