monitoringplugin.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. #####################################################################
  4. # (c) 2010-2011 by Sven Velt and team(ix) GmbH, Nuernberg, Germany #
  5. # sv@teamix.net #
  6. # #
  7. # This file is part of "team(ix) Monitoring Plugins" #
  8. # URL: http://oss.teamix.org/projects/monitoringplugins/ #
  9. # #
  10. # This file is free software: you can redistribute it and/or modify #
  11. # it under the terms of the GNU General Public License as published #
  12. # by the Free Software Foundation, either version 2 of the License, #
  13. # or (at your option) any later version. #
  14. # #
  15. # This file is distributed in the hope that it will be useful, but #
  16. # 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 file. If not, see <http://www.gnu.org/licenses/>. #
  22. #####################################################################
  23. __version__ = '0.0.110715'
  24. __all__ = ['MonitoringPlugin', 'SNMPMonitoringPlugin']
  25. import datetime, optparse, os, re, sys
  26. try:
  27. import netsnmp
  28. except ImportError:
  29. pass
  30. class MonitoringPlugin(object):
  31. RETURNSTRINGS = { 0: "OK", 1: "WARNING", 2: "CRITICAL", 3: "UNKNOWN", 127: "UNKNOWN" }
  32. RETURNCODE = { 'OK': 0, 'WARNING': 1, 'CRITICAL': 2, 'UNKNOWN': 3 }
  33. returncode_priority = [2, 1, 3, 0]
  34. powers_binary = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']
  35. powers_binary_lower = [ p.lower() for p in powers_binary]
  36. powers_si = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']
  37. powers_si_lower = [ p.lower() for p in powers_si]
  38. def __init__(self, *args, **kwargs):
  39. self.__pluginname = kwargs.get('pluginname') or ''
  40. self.__version = kwargs.get('version') or None
  41. self.__tagforstatusline = kwargs.get('tagforstatusline') or ''
  42. self.__tagforstatusline = self.__tagforstatusline.replace('|', ' ')
  43. self.__description = kwargs.get('description') or None
  44. self.__output = []
  45. self.__multilineoutput = []
  46. self.__performancedata = []
  47. self.__returncode = []
  48. self.__brain_checks = []
  49. self.__brain_perfdata = []
  50. self.__brain_perfdatalabels = []
  51. self.__optparser = optparse.OptionParser(version=self.__version, description=self.__description)
  52. self._cmdlineoptions_parsed = False
  53. def add_cmdlineoption(self, shortoption, longoption, dest, help, **kwargs):
  54. if help == None:
  55. help = optparse.SUPPRESS_HELP
  56. self.__optparser.add_option(shortoption, longoption, dest=dest, help=help, **kwargs)
  57. def parse_cmdlineoptions(self):
  58. if self._cmdlineoptions_parsed:
  59. return
  60. # self.__optparser.add_option('-V', '--version', action='version', help='show version number and exit')
  61. self.__optparser.add_option('-v', '--verbose', dest='verbose', help='Verbosity, more for more ;-)', action='count')
  62. (self.options, self.args) = self.__optparser.parse_args()
  63. self._cmdlineoptions_parsed = True
  64. def range_to_limits(self, range):
  65. # Check if we must negate result
  66. if len(range) > 0 and range[0] == '@':
  67. negate = True
  68. range = range[1:]
  69. else:
  70. negate = False
  71. # Look for a ':'...
  72. if range.find(':') >= 0:
  73. # ... this is a range
  74. (low, high) = range.split(':')
  75. if not low:
  76. low = float(0.0)
  77. elif low[0] == '~':
  78. low = float('-infinity')
  79. else:
  80. low = float(low)
  81. if high:
  82. high = float(high)
  83. else:
  84. high = float('infinity')
  85. elif len(range) == 0:
  86. low = float('-infinity')
  87. high = float('infinity')
  88. else:
  89. # ... this is just a number
  90. low = float(0.0)
  91. high = float(range)
  92. return (low, high, negate)
  93. def value_in_range(self, value, range):
  94. if range not in ['', None]:
  95. (low, high, negate) = self.range_to_limits(range)
  96. else:
  97. return True
  98. if value < low or value > high:
  99. result = False
  100. else:
  101. result = True
  102. if negate:
  103. result = not result
  104. return result
  105. def value_wc_to_returncode(self, value, range_warn, range_crit):
  106. if not self.value_in_range(value, range_crit):
  107. return 2
  108. elif not self.value_in_range(value, range_warn):
  109. return 1
  110. return 0
  111. def is_float(self, string):
  112. try:
  113. float(string)
  114. return True
  115. except ValueError:
  116. return False
  117. def special_value_wc_to_returncode(self, value, warn, crit):
  118. # Special add on: WARN > CRIT
  119. if self.is_float(warn) and self.is_float(crit) and float(warn) > float(crit):
  120. # Test if value is *smaller* than thresholds
  121. warn = '@0:' + warn
  122. crit = '@0:' + crit
  123. return self.value_wc_to_returncode(value, warn, crit)
  124. def add_output(self, value):
  125. self.__output.append(value)
  126. def add_multilineoutput(self, value):
  127. self.__multilineoutput.append(value)
  128. def format_performancedata(self, label, value, unit, *args, **kwargs):
  129. label = label.lstrip().rstrip()
  130. if re.search('[=\' ]', label):
  131. label = '\'' + label + '\''
  132. perfdata = label + '=' + str(value)
  133. if unit:
  134. perfdata += str(unit).lstrip().rstrip()
  135. for key in ['warn', 'crit', 'min', 'max']:
  136. perfdata += ';'
  137. if key in kwargs and kwargs[key]!=None:
  138. perfdata += str(kwargs[key])
  139. return perfdata
  140. def add_performancedata(self, perfdata):
  141. self.__performancedata.append(perfdata)
  142. def format_add_performancedata(self, label, value, unit, *args, **kwargs):
  143. self.add_performancedata(self.format_performancedata(label, value, unit, *args, **kwargs))
  144. def add_returncode(self, value):
  145. self.__returncode.append(value)
  146. def tagtarget(self, tag, target):
  147. if target:
  148. return str(tag) + ':' + str(target)
  149. else:
  150. return str(tag)
  151. def remember_check(self, tag, returncode, output, multilineoutput=None, perfdata=None, target=None):
  152. check = {}
  153. check['tag'] = tag
  154. check['returncode'] = returncode
  155. check['output'] = output
  156. check['multilineoutput'] = multilineoutput
  157. check['perfdata'] = perfdata
  158. check['target'] = target
  159. self.remember_perfdata(perfdata)
  160. self.__brain_checks.append(check)
  161. return check
  162. def remember_perfdata(self, perfdata=None):
  163. if perfdata:
  164. for pd in perfdata:
  165. if pd['label'] in self.__brain_perfdatalabels:
  166. pdidx = self.__brain_perfdatalabels.index(pd['label'])
  167. self.__brain_perfdata[pdidx] = pd
  168. else:
  169. self.__brain_perfdata.append(pd)
  170. self.__brain_perfdatalabels.append(pd['label'])
  171. def dump_brain(self):
  172. return (self.__brain_checks, self.__brain_perfdata)
  173. def brain2output(self):
  174. if len(self.__brain_checks) == 1:
  175. check = self.__brain_checks[0]
  176. self.add_output(check.get('output'))
  177. if check.get('multilineoutput'):
  178. self.add_multilineoutput(check.get('multilineoutput'))
  179. self.add_returncode(check.get('returncode') or 0)
  180. else:
  181. out = [[], [], [], []]
  182. for check in self.__brain_checks:
  183. tagtarget = self.tagtarget(check['tag'], check.get('target'))
  184. returncode = check.get('returncode') or 0
  185. self.add_returncode(returncode)
  186. out[returncode].append(tagtarget)
  187. self.add_multilineoutput(self.RETURNSTRINGS[returncode] + ' ' + tagtarget + ' - ' + check.get('output'))
  188. if check.get('multilineoutput'):
  189. self.add_multilineoutput(check.get('multilineoutput'))
  190. statusline = []
  191. for retcode in self.returncode_priority:
  192. if len(out[retcode]):
  193. statusline.append(str(len(out[retcode])) + ' ' + self.RETURNSTRINGS[retcode] + ': ' + ' '.join(out[retcode]))
  194. statusline = ', '.join(statusline)
  195. self.add_output(statusline)
  196. for pd in self.__brain_perfdata:
  197. self.format_add_performancedata(**pd)
  198. def value_to_human_binary(self, value, unit=''):
  199. for power in self.powers_binary:
  200. if value < 1024.0:
  201. return "%3.1f%s%s" % (value, power, unit)
  202. value /= 1024.0
  203. if float(value) not in [float('inf'), float('-inf')]:
  204. return "%3.1fYi%s" % (value, unit)
  205. else:
  206. return value
  207. def value_to_human_si(self, value, unit=''):
  208. for power in self.powers_si:
  209. if value < 1000.0:
  210. return "%3.1f%s%s" % (value, power, unit)
  211. value /= 1000.0
  212. if float(value) not in [float('inf'), float('-inf')]:
  213. return "%3.1fY%s" % (value, unit)
  214. else:
  215. return value
  216. def seconds_to_hms(self, seconds):
  217. seconds = int(seconds)
  218. hours = int(seconds / 3600)
  219. seconds -= (hours * 3600)
  220. minutes = seconds / 60
  221. seconds -= (minutes * 60)
  222. return '%i:%02i:%02i' % (hours, minutes, seconds)
  223. def seconds_to_timedelta(self, seconds):
  224. return datetime.timedelta(seconds=long(seconds))
  225. def human_to_number(self, value, total=None, unit=['',]):
  226. if total:
  227. if not self.is_float(total):
  228. total = self.human_to_number(total, unit=unit)
  229. if type(unit) == list:
  230. unit = [u.lower() for u in unit]
  231. elif type(unit) == str:
  232. unit = [unit.lower(),]
  233. else:
  234. unit = ['',]
  235. if value.lower()[-1] in unit:
  236. value = value[0:-1]
  237. if self.is_float(value):
  238. return float(value)
  239. elif value[-1] == '%':
  240. if total:
  241. return float(value[:-1])/100.0 * float(total)
  242. else:
  243. if total in [0, 0.0]:
  244. return 0.0
  245. else:
  246. return float(value[:-1]) # FIXME: Good idea?
  247. elif value[-1].lower() in self.powers_si_lower:
  248. return 1000.0 ** self.powers_si_lower.index(value[-1].lower()) * float(value[:-1])
  249. elif value[-2:].lower() in self.powers_binary_lower:
  250. return 1024.0 ** self.powers_binary_lower.index(value[-2:].lower()) * float(value[:-2])
  251. else:
  252. return value
  253. def range_dehumanize(self, range, total=None, unit=['',]):
  254. newrange = ''
  255. if len(range):
  256. if range[0] == '@':
  257. newrange += '@'
  258. range = range[1:]
  259. parts = range.split(':')
  260. newrange += ('%s' % self.human_to_number(parts[0], total, unit)).rstrip('0').rstrip('.')
  261. if len(parts) > 1:
  262. newrange += ':' + ('%s' % self.human_to_number(parts[1], total, unit)).rstrip('0').rstrip('.')
  263. if range != newrange:
  264. self.verbose(3, 'Changed range/thresold from "' + range + '" to "' + newrange + '"')
  265. return newrange
  266. else:
  267. return ''
  268. def verbose(self, level, output, prefix=None):
  269. if level <= self.options.verbose:
  270. bol = 'V' + str(level) + ':' + ' ' * level
  271. if prefix:
  272. bol += '%s' % prefix
  273. if type(output) in [str, unicode, ]:
  274. print(bol + output)
  275. elif type(output) in [list, ]:
  276. print('\n'.join( ['%s%s' % (bol, l) for l in output] ) )
  277. else:
  278. print('%s%s' % (bol, output) )
  279. def max_returncode(self, returncodes):
  280. for rc in self.returncode_priority:
  281. if rc in returncodes:
  282. break
  283. return rc
  284. def exit(self):
  285. returncode = self.max_returncode(self.__returncode)
  286. self.back2nagios(returncode, statusline=self.__output, multiline=self.__multilineoutput, performancedata=self.__performancedata)
  287. def back2nagios(self, returncode, statusline=None, multiline=None, performancedata=None, subtag=None, exit=True):
  288. # FIXME: Make 'returncode' also accept strings
  289. # Build status line
  290. out = self.__tagforstatusline
  291. if subtag:
  292. out += '(' + subtag.replace('|', ' ') + ')'
  293. out += ' ' + self.RETURNSTRINGS[returncode]
  294. # Check if there's a status line text and build it
  295. if statusline:
  296. out += ' - '
  297. if type(statusline) == str:
  298. out += statusline
  299. elif type(statusline) in [list, tuple]:
  300. out += ', '.join(statusline).replace('|', ' ')
  301. # Check if we have multi line output and build it
  302. if multiline:
  303. if type(multiline) == str:
  304. out += '\n' + multiline.replace('|', ' ')
  305. elif type(multiline) in [list, tuple]:
  306. if type(multiline[0]) in [list, tuple]:
  307. out += '\n' + '\n'.join([item for sublist in multiline for item in sublist]).replace('|', ' ')
  308. else:
  309. out += '\n' + '\n'.join(multiline).replace('|', ' ')
  310. # Check if there's perfdata
  311. if performancedata:
  312. out += '|'
  313. if type(performancedata) == str:
  314. out += performancedata
  315. elif type(performancedata) in [list, tuple]:
  316. out += ' '.join(performancedata).replace('|', ' ')
  317. # Exit program or return output line(s)
  318. if exit:
  319. print out
  320. sys.exit(returncode)
  321. else:
  322. return (returncode, out)
  323. ##############################################################################
  324. class SNMPMonitoringPlugin(MonitoringPlugin):
  325. def __init__(self, *args, **kwargs):
  326. # Same as "MonitoringPlugin.__init__(*args, **kwargs)" but a little bit more flexible
  327. #super(MonitoringPlugin, self).__init__(*args, **kwargs)
  328. MonitoringPlugin.__init__(self, *args, **kwargs)
  329. self.add_cmdlineoption('-H', '', 'host', 'Host to check', default='127.0.0.1')
  330. self.add_cmdlineoption('-P', '', 'snmpversion', 'SNMP protocol version', metavar='1', default='1')
  331. self.add_cmdlineoption('-C', '', 'snmpauth', 'SNMP v1/v2c community OR SNMP v3 quadruple', metavar='public', default='public')
  332. self.add_cmdlineoption('', '--snmpcmdlinepath', 'snmpcmdlinepath', 'Path to "snmpget" and "snmpwalk"', metavar='/usr/bin/', default='/usr/bin')
  333. # FIXME
  334. self.add_cmdlineoption('', '--nonetsnmp', 'nonetsnmp', 'Do not use NET-SNMP python bindings', action='store_true')
  335. # self.__optparser.add_option('', '--nonetsnmp', dest='nonetsnmp', help='Do not use NET-SNMP python bindings', action='store_true')
  336. self.__SNMP_Cache = {}
  337. self.__use_netsnmp = False
  338. self.__prepared_snmp = False
  339. def prepare_snmp(self):
  340. if not self._cmdlineoptions_parsed:
  341. self.parse_cmdlineoptions()
  342. if not self.options.nonetsnmp:
  343. try:
  344. import netsnmp
  345. self.__use_netsnmp = True
  346. except ImportError:
  347. pass
  348. if self.__use_netsnmp:
  349. self.verbose(1, 'Using NET-SNMP Python bindings')
  350. self.SNMPGET_wrapper = self.__SNMPGET_netsnmp
  351. self.SNMPWALK_wrapper = self.__SNMPWALK_netsnmp
  352. if self.options.snmpversion == '2c':
  353. self.options.snmpversion = '2'
  354. else:
  355. self.verbose(1, 'Using NET-SNMP command line tools')
  356. self.SNMPGET_wrapper = self.__SNMPGET_cmdline
  357. self.SNMPWALK_wrapper = self.__SNMPWALK_cmdline
  358. # Building command lines
  359. self.__CMDLINE_get = os.path.join(self.options.snmpcmdlinepath, 'snmpget') + ' -OqevtU '
  360. self.__CMDLINE_walk = os.path.join(self.options.snmpcmdlinepath, 'snmpwalk') + ' -OqevtU '
  361. if self.options.snmpversion in [1, 2, '1', '2', '2c']:
  362. if self.options.snmpversion in [2, '2']:
  363. self.options.snmpversion = '2c'
  364. self.__CMDLINE_get += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
  365. self.__CMDLINE_walk += ' -v' + str(self.options.snmpversion) + ' -c' + self.options.snmpauth + ' '
  366. elif options.snmpversion == [3, '3']:
  367. # FIXME: Better error handling
  368. try:
  369. snmpauth = self.options.snmpauth.split(':')
  370. self.__CMDLINE_get += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
  371. self.__CMDLINE_walk += ' -v3 -l' + snmpauth[0] + ' -u' + snmpauth[1] + ' -a' + snmpauth[2] + ' -A' + snmpauth[3] + ' '
  372. except:
  373. self.back2nagios(3, 'Could not build SNMPv3 command line, need "SecLevel:SecName:AuthProtocol:AuthKey"')
  374. else:
  375. self.back2nagios(3, 'Unknown SNMP version "' + str(self.options.snmpversion) + '"')
  376. self.__CMDLINE_get += ' ' + self.options.host + ' %s 2>/dev/null'
  377. self.__CMDLINE_walk += ' ' + self.options.host + ' %s 2>/dev/null'
  378. self.verbose(3, 'Using commandline: ' + self.__CMDLINE_get)
  379. self.verbose(3, 'Using commandline: ' + self.__CMDLINE_walk)
  380. # Test if snmp(get|walk) are executable
  381. for fpath in [self.__CMDLINE_get, self.__CMDLINE_walk,]:
  382. fpath = fpath.split(' ',1)[0]
  383. if not( os.path.exists(fpath) and os.path.isfile(fpath) and os.access(fpath, os.X_OK) ):
  384. self.back2nagios(3, 'Could not execute "%s"' % fpath)
  385. self.__prepared_snmp = True
  386. def find_index_for_value(self, list_indexes, list_values, wanted):
  387. self.verbose(2, 'Look for "' + str(wanted) + '"')
  388. index = None
  389. if len(list_indexes) != len(list_values):
  390. self.verbose(1, 'Length of index and value lists do not match!')
  391. return None
  392. try:
  393. index = list_values.index(wanted)
  394. index = list_indexes[index]
  395. except ValueError:
  396. pass
  397. if index:
  398. self.verbose(2, 'Found "' + str(wanted) +'" with index "' + str(index) + '"')
  399. else:
  400. self.verbose(2, 'Nothing found!')
  401. return index
  402. def find_in_table(self, oid_index, oid_values, wanted):
  403. self.verbose(2, 'Look for "' + str(wanted) + '" in "' + str(oid_values) +'"')
  404. index = None
  405. indexes = list(self.SNMPWALK(oid_index))
  406. values = list(self.SNMPWALK(oid_values))
  407. if len(indexes) != len(values):
  408. self.back2nagios(3, 'Different data from 2 SNMP Walks!')
  409. return self.find_index_for_value(indexes, values, wanted)
  410. def SNMPGET(self, baseoid, idx=None, exitonerror=True):
  411. if type(baseoid) in (list, tuple):
  412. if idx not in ['', None]:
  413. idx = '.' + str(idx)
  414. else:
  415. idx = ''
  416. if self.options.snmpversion in [1, '1']:
  417. value_low = long(self.SNMPGET_wrapper(baseoid[1] + idx, exitonerror=exitonerror))
  418. if value_low < 0L:
  419. value_low += 2 ** 32
  420. value_hi = long(self.SNMPGET_wrapper(baseoid[2] + idx, exitonerror=exitonerror))
  421. if value_hi < 0L:
  422. value_hi += 2 ** 32
  423. return value_hi * 2L ** 32L + value_low
  424. elif self.options.snmpversion in [2, 3, '2', '2c', '3']:
  425. return long(self.SNMPGET_wrapper(baseoid[0] + idx, exitonerror=exitonerror))
  426. elif type(baseoid) in (str, ) and idx != None:
  427. return self.SNMPGET_wrapper(baseoid + '.' + str(idx), exitonerror=exitonerror)
  428. else:
  429. return self.SNMPGET_wrapper(baseoid, exitonerror=exitonerror)
  430. def SNMPWALK(self, baseoid, exitonerror=True):
  431. return self.SNMPWALK_wrapper(baseoid, exitonerror=exitonerror)
  432. def __SNMPGET_netsnmp(self, oid, exitonerror=True):
  433. if not self.__prepared_snmp:
  434. self.prepare_snmp()
  435. if oid in self.__SNMP_Cache:
  436. self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
  437. return self.__SNMP_Cache[oid]
  438. result = netsnmp.snmpget(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)[0]
  439. if not result:
  440. if exitonerror:
  441. self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
  442. else:
  443. return None
  444. self.__SNMP_Cache[oid] = result
  445. self.verbose(2, "%40s -> %s" % (oid, result))
  446. return result
  447. def __SNMPWALK_netsnmp(self, oid, exitonerror=True):
  448. if not self.__prepared_snmp:
  449. self.prepare_snmp()
  450. if oid in self.__SNMP_Cache:
  451. self.verbose(2, "%40s -> (CACHED) %s" % (oid, self.__SNMP_Cache[oid]))
  452. return self.__SNMP_Cache[oid]
  453. result = netsnmp.snmpwalk(oid, Version=int(self.options.snmpversion), DestHost=self.options.host, Community=self.options.snmpauth)
  454. if not result:
  455. if exitonerror:
  456. self.back2nagios(3, 'Timeout or no answer from "%s" looking for "%s"' % (self.options.host, oid))
  457. else:
  458. return None
  459. self.__SNMP_Cache[oid] = result
  460. self.verbose(2, "%40s -> %s" % (oid, result))
  461. return result
  462. def __SNMPGET_cmdline(self, oid, exitonerror=True):
  463. if not self.__prepared_snmp:
  464. self.prepare_snmp()
  465. cmdline = self.__CMDLINE_get % oid
  466. self.verbose(2, cmdline)
  467. if oid in self.__SNMP_Cache:
  468. self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
  469. return self.__SNMP_Cache[oid]
  470. cmd = os.popen(cmdline)
  471. out = cmd.readline().rstrip().replace('"','')
  472. retcode = cmd.close()
  473. if retcode:
  474. if not exitonerror:
  475. return None
  476. if retcode == 256:
  477. self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
  478. elif retcode ==512:
  479. self.back2nagios(3, 'OID "' + oid + '" not found')
  480. else:
  481. self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
  482. self.__SNMP_Cache[oid] = out
  483. self.verbose(1, out)
  484. return out
  485. def __SNMPWALK_cmdline(self, oid, exitonerror=True):
  486. if not self.__prepared_snmp:
  487. self.prepare_snmp()
  488. cmdline = self.__CMDLINE_walk % oid
  489. self.verbose(2, cmdline)
  490. if oid in self.__SNMP_Cache:
  491. self.verbose(2, "(CACHED) %s" % (self.__SNMP_Cache[oid]))
  492. return self.__SNMP_Cache[oid]
  493. cmd = os.popen(cmdline)
  494. out = cmd.readlines()
  495. retcode = cmd.close()
  496. if retcode:
  497. if not exitonerror:
  498. return None
  499. if retcode == 256:
  500. self.back2nagios(3, 'Timeout - no SNMP answer from "' + self.options.host + '"')
  501. elif retcode ==512:
  502. self.back2nagios(3, 'OID "' + oid + '" not found')
  503. else:
  504. self.back2nagios(3, 'Unknown error code "' + str(retcode) + '" from command line utils')
  505. for line in range(0,len(out)):
  506. out[line] = out[line].rstrip().replace('"','')
  507. self.__SNMP_Cache[oid] = out
  508. self.verbose(1, str(out))
  509. return out
  510. ##############################################################################
  511. def main():
  512. myplugin = MonitoringPlugin(pluginname='check_testplugin', tagforstatusline='TEST')
  513. from pprint import pprint
  514. pprint(myplugin.back2nagios(0, 'Nr. 01: Simple plugin', exit=False) )
  515. pprint(myplugin.back2nagios(0, 'Nr. 02: Simple plugin with sub tag', subtag='MySubTag', exit=False) )
  516. pprint(myplugin.back2nagios(0, 'Nr. 10: Exit Code OK', exit=False) )
  517. pprint(myplugin.back2nagios(1, 'Nr. 11: Exit Code WARNING', exit=False) )
  518. pprint(myplugin.back2nagios(2, 'Nr. 12: Exit Code CRITICAL', exit=False) )
  519. pprint(myplugin.back2nagios(3, 'Nr. 13: Exit Code UNKNOWN', exit=False) )
  520. ret = myplugin.back2nagios(0, 'Nr. 20: Plugin with string-based multiline output', 'Line 2\nLine 3\nLine4', exit=False)
  521. print ret[1]
  522. print 'Returncode: ' + str(ret[0])
  523. ret = myplugin.back2nagios(0, 'Nr. 21: Plugin with list-based multiline output', ['Line 2', 'Line 3', 'Line4'], exit=False)
  524. print ret[1]
  525. print 'Returncode: ' + str(ret[0])
  526. ret = myplugin.back2nagios(0, 'Nr. 22: Plugin with tuple-based multiline output', ('Line 2', 'Line 3', 'Line4'), exit=False)
  527. print ret[1]
  528. print 'Returncode: ' + str(ret[0])
  529. myplugin.add_performancedata('Val1', 42, '')
  530. myplugin.add_performancedata('Val2', 23, 'c', warn=10, crit=20, min=0, max=100)
  531. myplugin.add_performancedata('Val 3', '2342', 'c', warn=10, crit=20, min=0, max=100)
  532. pprint(myplugin.back2nagios(0, 'Nr. 30: With perfdatas', exit=False) )
  533. myplugin.back2nagios(0, 'Nr. 99: Exit test suite with OK')
  534. if __name__ == '__main__':
  535. main()
  536. #vim: ts=4 sw=4