Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

* Removed a bunch of python build objects.

  • Loading branch information...
commit e850e19cb9950a29356a6c2189f26c5953d402a7 1 parent 9eeb8d7
Shaun Thomas authored
BIN  build/bdist.linux-i686/rpm/SOURCES/NagAconda-0.1.tar.gz
Binary file not shown
50 build/bdist.linux-i686/rpm/SPECS/NagAconda.spec
... ... @@ -1,50 +0,0 @@
1   -%define name NagAconda
2   -%define version 0.1
3   -%define unmangled_version 0.1
4   -%define unmangled_version 0.1
5   -%define release 1
6   -
7   -Summary: NagAconda is a Python Nagios wrapper.
8   -Name: %{name}
9   -Version: %{version}
10   -Release: %{release}
11   -Source0: %{name}-%{unmangled_version}.tar.gz
12   -License: UNKNOWN
13   -Group: Development/Libraries
14   -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
15   -Prefix: %{_prefix}
16   -BuildArch: noarch
17   -Vendor: Shaun Thomas <sthomas@leapfrogonline.com>
18   -Url: http://www.leapfrogonline.com/
19   -
20   -%description
21   -
22   -:mod:`NagAconda` -- Python Nagios Integration
23   -=============================================
24   -
25   -Nagios has been around for quite some time, but producing output it can
26   -consume is something of a black art. Only the plugin documentation actually
27   -explains what all the extra semicolons or extended formatting even means.
28   -
29   -This is especially onerous when performance consuming add-ons expect a
30   -specific structure before operating properly. This package strives to
31   -greatly simplify the process of actually generating Nagios output.
32   -
33   -.. automodule:: NagAconda.Plugin
34   -
35   -
36   -
37   -%prep
38   -%setup -n %{name}-%{unmangled_version} -n %{name}-%{unmangled_version}
39   -
40   -%build
41   -python setup.py build
42   -
43   -%install
44   -python setup.py install --single-version-externally-managed --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
45   -
46   -%clean
47   -rm -rf $RPM_BUILD_ROOT
48   -
49   -%files -f INSTALLED_FILES
50   -%defattr(-,root,root)
525 build/lib.linux-i686-2.6/NagAconda/Plugin.py
... ... @@ -1,525 +0,0 @@
1   -"""
2   -:mod:`Plugin` -- Nagios Plugin Wrapper
3   -======================================
4   -
5   -.. module:: Plugin
6   - :platform: Unix
7   - :synopsis: Wraps Nagios plugins in a candy coating.
8   -.. moduleauthor:: Shaun Thomas <sthomas@leapfrogonline.com>
9   -
10   -The Plugin module provides all the parts necessary to create a simple Nagios
11   -report for a service or host check by removing all that pesky inside
12   -knowledge necessary. All the classes and methods provided here reduce plugin
13   -creation to a few lines of python unless the plugin is especially complex.
14   -
15   -All specifications for this module are obtained from the `Nagios developer
16   -documentation <http://nagiosplug.sourceforge.net/developer-guidelines.html>`_.
17   -
18   -Usage
19   ------
20   -
21   -.. code-block:: python
22   -
23   - from NagAconda import Plugin
24   - from Person import Dude
25   -
26   - feet = Plugin("Plugin to quantify current foot odor.", "1.0")
27   - feet.add_option('t', 'target', 'Person to check for odor.',
28   - required=True)
29   -
30   - feet.enable_status('warning')
31   - feet.enable_status('critical')
32   - feet.start()
33   -
34   - roommate = Dude(feet.options.target)
35   - feet.set_value('stench', rommmate.gym_socks())
36   - feet.set_status_message('Current stench level (%s)' % rommmate.gym_socks())
37   -
38   - feet.finish()
39   -
40   -API Specification
41   ------------------
42   -
43   -.. autoclass:: NagAconda.Plugin
44   - :members: add_option, enable_status, finish, set_value, set_status_message,
45   - start, unknown_error
46   -
47   -"""
48   -
49   -__version__ = '0.1.4'
50   -__all__ = ['Plugin']
51   -
52   -# We need the option parser primarily to provide an instruction harness to the
53   -# plugins. We'll act as a wrapper and not an extension here because there's
54   -# too much potential namespace pollution due to optparse's attribute creation.
55   -# We also want exit for Nagios specification exit status.
56   -
57   -from optparse import OptionParser
58   -import sys
59   -
60   -class Plugin:
61   - """
62   - This is the primary control class for NagAconda.
63   -
64   - The attributes available here are direct-access to parsed options and
65   - arguments, not class-level variables.
66   -
67   - .. attribute:: options
68   -
69   - This contains all of the options obtained from the command line for this
70   - plugin. This includes any options registered by the master class.
71   -
72   - .. attribute:: arguments
73   -
74   - After `start` is called, all command-line options are read, and anything
75   - left over is placed into this object for further use. Most Nagios
76   - parsers use explicit option setting, so you might never use this.
77   -
78   - """
79   -
80   - def __init__(self, description, version):
81   - """
82   - Initialize our Plugin's state.
83   -
84   - The Plugin constructor starts the option parser and fills it with
85   - the verbose descriptor, as described in the Nagios documentation.
86   - Warning and Critical thresholds can be enabled later.
87   -
88   - :param description: Paragraphs that describe this plugin.
89   - Option descriptions are automatically included, as is
90   - basic usage. This explains the plugin itself.
91   - :param version: Sets the version of this plugin. Nagios **strongly**
92   - suggests this is available, so we require it.
93   -
94   - """
95   - # PUBLIC
96   - self.options = None
97   - self.arguments = None
98   -
99   - # PRIVATE
100   - self.__opt_parser = None # OptionParser object.
101   - self.__perf = {} # Collected performance data.
102   - self.__req_option = [] # Options considered required for operation.
103   - self.__started = False # Has 'start' been called yet?
104   - self.__exit_status = None # 'ok', 'warning', or 'critical'.
105   - self.__exit_message = None # User specified status, filtered.
106   -
107   - # With our variables out of the way, let's start up the option parser
108   - # with a version and verbose setting, along with a sane usage
109   - # statement.
110   -
111   - self.__opt_parser = OptionParser(version=version,
112   - description=description, conflict_handler="resolve")
113   -
114   - self.__opt_parser.add_option('-V', '--version', action='version',
115   - help="show program's version number and exit"
116   - )
117   -
118   - self.__opt_parser.add_option('-v', '--verbose', action='count',
119   - help="Get more verbose status output. "
120   - "Can be specified up to three times"
121   - )
122   -
123   - self.__opt_parser.set_usage('%prog')
124   -
125   -
126   - def __check_range(self, range_type, name):
127   - """
128   - Check a submitted value against warning/critical thresholds
129   -
130   - :param range_type: **warning** or **critical**
131   - :param name: Name of the performance metric to check against the
132   - specified range type.
133   -
134   - :raises UserWarning: When the user-specified range is missing the
135   - threshold necessary to test the targeted variable.
136   -
137   - """
138   - range_list = getattr(self.options, range_type)
139   - if not range_list:
140   - return
141   -
142   - threshold = self.__perf[name]['threshold']
143   - val = self.__perf[name]['val']
144   -
145   - # Even if the warning/critical thresholds are required, a user may
146   - # forget to set all necessary ranges. If the ranges are required,
147   - # exit with a complaint, otherwise just skip the range test.
148   -
149   - if len(range_list) < threshold:
150   - if range_type not in self.__req_option:
151   - return
152   - raise UserWarning, (
153   - "Please set part %s of the %s threshold!" % (
154   - threshold, range_type))
155   -
156   - # The option parser should have already split these into proper
157   - # bottom, top, inclusive, so long as the array element is defined.
158   - # Perform our range test and set the exit status.
159   -
160   - (bottom, top, inclusive) = range_list[threshold-1]
161   -
162   - if inclusive and val >= bottom and val <= top:
163   - self.__exit_status = range_type
164   - self.__perf[name]['state'] = range_type
165   - elif not inclusive and val > bottom and val < top:
166   - self.__exit_status = range_type
167   - self.__perf[name]['state'] = range_type
168   -
169   - def add_option(self, flag, name, helptext, **kwargs):
170   - """
171   - Adds a Nagios-style help option to this plugin.
172   -
173   - :param flag: A one-letter shortcut for this option.
174   - :param name: The full name for this option.
175   - :param helptext: Instructions for usage of this option.
176   - :param required: Force option for plugin execution. Default False.
177   - :type required: True or False
178   - :param action: What type of storage action should take place for
179   - this parameter? This is the same as the OptionParser 'action'
180   - setting. Default is 'store'.
181   - :type action: Setting string. Default 'store'
182   - :param callback: When action is `callback`, use specified function.
183   - :type callback: function reference or None
184   - :param default: What value to default if unset.
185   - """
186   - self.__opt_parser.add_option('-' + flag, '--' + name, help=helptext,
187   - dest=name, type='string', action=kwargs.get('action'),
188   - callback=kwargs.get('callback'), default=kwargs.get('default'))
189   -
190   - opt_usage = "-%s %s" % (flag, name.upper())
191   -
192   - if kwargs.has_key('required') and kwargs['required'] is True:
193   - self.__req_option.append(name)
194   - else:
195   - opt_usage = "[%s]" % opt_usage
196   -
197   - opts = self.__opt_parser.get_usage().rstrip("\n")
198   - self.__opt_parser.set_usage(opts + " " + opt_usage)
199   -
200   - def enable_status(self, status_type, required=False):
201   - """
202   - Enable warning or critical exit statuses.
203   -
204   - Nagios requires error levels to be returned by the running
205   - application to evaluate exit status since the text is indeterminate.
206   - For Nagios:
207   -
208   - * 0 - Status OK
209   - * 1 - Plugin is notifying a warning state.
210   - * 2 - Plugin is notifying of a critical error or state.
211   - * 3 - Some unknown or unhandled error occurred.
212   - * other - Nagios will report this as a plugin failure.
213   -
214   - By default, warnings and critical errors are not enabled, in case the
215   - plugin is just tracking values. This method will turn them on and add
216   - the proper command-line elements so the user can set them.
217   -
218   - .. note::
219   -
220   - If **warning** or **critical** is enabled and set as required,
221   - failing to provide them to the plugin will result in an automatic
222   - exit and presentation of the usage documentation.
223   -
224   - When plugins make use of multiple performance metrics, they may also
225   - have different scales, and hence warning/critical ranges involved.
226   - In this case, ranges must be passed by the command-line in
227   - comma-delimited format.
228   -
229   - :param status_type: Should be either `warning` or `critical`.
230   - :type status_type: String.
231   - :param required: Should this threshold be a required option?
232   - :type required: True or False. Default False.
233   -
234   - """
235   - try:
236   - status_type = status_type.lower()
237   - assert status_type in ('warning', 'critical')
238   - except (AttributeError, AssertionError):
239   - self.unknown_error(
240   - "Status_type can only be one of *warning* or *critical*!")
241   -
242   - self.add_option(status_type[0], status_type,
243   - "Set the %s notification level." % status_type,
244   - required=required, action='callback', callback=convert_range)
245   -
246   - def finish(self):
247   - """
248   - Prints out all results in a form Nagios understands.
249   -
250   - The process of setting a value through 'set_value' actually applies
251   - warning and critical threshold checks, so by now, all is over but the
252   - shouting. This method prints out the status and performance data in a
253   - manner Nagios will understand.
254   -
255   - """
256   - try:
257   - assert self.__started
258   - except AssertionError:
259   - self.unknown_error("Start method must be called first!")
260   -
261   - exit_value = 0
262   - if self.__exit_status == 'warning':
263   - exit_value = 1
264   - if self.__exit_status == 'critical':
265   - exit_value = 2
266   -
267   - # Nagios performance output is values delimited by a space. semicolons
268   - # separate to val;warn;crit;min;max with the scale included in all
269   - # output. So, let's get cracking...
270   -
271   - perfs = []
272   -
273   - for (perf_name, perf_dict) in self.__perf.items():
274   -
275   - perfs.append('%s=%s%s;%s;%s;%s;%s' % (
276   - perf_name, perf_dict['val'], perf_dict['scale'] or '',
277   - self.options.ensure_value('raw_warning', ''),
278   - self.options.ensure_value('raw_critical', ''),
279   - perf_dict['min'] or '', perf_dict['max'] or '')
280   - )
281   -
282   - perf_string = ''
283   - if len(perfs) > 0:
284   - perf_string = '|' + ' '.join(["%s" % item for item in perfs])
285   -
286   - exit_status = self.__exit_status.capitalize()
287   - if self.__exit_message is not None:
288   - exit_status += ', %s' % self.__exit_message
289   -
290   - print 'Status ' + exit_status + perf_string
291   - sys.exit(exit_value)
292   -
293   - def set_value(self, name, val, **kwargs):
294   - """
295   - Set a performance measurement for output to Nagios.
296   -
297   - There is theoretically no limit on the number of metrics being tracked
298   - in Nagios performance output. That said, we strongly recommend reading
299   - the Nagios developer docs to understand how warning and critical test
300   - ranges are handled.
301   -
302   - Should a minimum or maximum value be provided here, they will only
303   - be used to build percentage ranges, and will not otherwise affect
304   - operation of Nagios.
305   -
306   - This should always be called *after* the **start** method.
307   -
308   - .. note::
309   -
310   - Any value parameter that is not submitted as an numeric type will be
311   - converted to one so tests work properly.
312   -
313   - :param name: Name of the performance setting.
314   - :param val: Value observed for this iteration.
315   - :type val: float
316   - :param lowest: Minimum possible value for this setting. Optional.
317   - :type lowest: float or None
318   - :param highest: Maximum possible value for this setting. Optional.
319   - :type highest: float or None
320   - :param scale: The unit of measurement to apply to this value.
321   - should be a byte measurement (B, KB, MB, GB, TB) or
322   - a unit of time (s, ms, us, ns), or a percentage (%).
323   - :type scale: string or None
324   - :param threshold: Which warning/critical range to target for this
325   - value? Default 1, since most never use more.
326   - :type threshold: integer, default 1
327   -
328   - :raises ValueError: When an invalid scale is passed.
329   - :return string: One of 'ok', 'warning' or 'critical', as to how this
330   - value compared to the enabled and supplied thresholds.
331   - """
332   - try:
333   - assert self.__started
334   - val = float(val)
335   - except AssertionError:
336   - self.unknown_error("Start method must be called first!")
337   - except (TypeError, ValueError):
338   - self.unknown_error("Performance measures must be numeric!")
339   -
340   - val_dict = {'val': val, 'min': None, 'max': None, 'scale': None,
341   - 'threshold': 1, 'state': 'ok'}
342   -
343   - if kwargs.has_key('lowest'):
344   - val_dict['min'] = float(kwargs.get('lowest'))
345   -
346   - if kwargs.has_key('highest'):
347   - val_dict['max'] = float(kwargs.get('highest'))
348   -
349   - if kwargs.has_key('threshold'):
350   - val_dict['threshold'] = kwargs['threshold']
351   -
352   - # Nagios actually understands most byte and time oriented scales.
353   - # The developer docs also list a counter scale, but we're not certain
354   - # if any plugin has ever used that. Only accept known scales.
355   -
356   - if kwargs.has_key('scale'):
357   - scale = kwargs.get('scale')
358   -
359   - if scale.upper() in ('B', 'KB', 'MB', 'GB', 'TB'):
360   - val_dict['scale'] = scale.upper()
361   - elif scale.lower() in ('s', 'ms', 'us', 'ns', '%'):
362   - val_dict['scale'] = scale.lower()
363   - else:
364   - raise ValueError("""Scale must be one of: B, KB, MB, GB,
365   - TB, s, ms, us, ns, or %.""")
366   -
367   - self.__perf[name] = val_dict
368   -
369   - # We'll use the opportunity to check the status ranges right when the
370   - # variable is set so we don't have to loop through all of them later.
371   -
372   - if hasattr(self.options, 'warning'):
373   - self.__check_range('warning', name)
374   -
375   - if hasattr(self.options, 'critical'):
376   - self.__check_range('critical', name)
377   -
378   - return self.__perf[name]['state']
379   -
380   - def set_status_message(self, message):
381   - """
382   - Set a more informational exit string for plugin status.
383   -
384   - By default, NagAconda exits merely with OK, WARNING, or CRITICAL, a
385   - raw interpretation as applied to provided warning and critical
386   - thresholds. Clearly this isn't sufficent in many cases where plugins
387   - know more than merely the metrics being measured. This method is
388   - provided as a means to manually add textual information to the plugin's
389   - output that won't interfere with Nagios's parsing of that status.
390   -
391   - Since status may change through the process of the plugin's execution
392   - several times, or in accordance to the status of several metrics, this
393   - is provided separately from the 'finish' method.
394   -
395   - .. note::
396   -
397   - This is not the same as verbose Nagios output that can span
398   - multiple lines. This is just appended to the usual OK / WARNING /
399   - CRITICAL status reported back to Nagios.
400   -
401   - :param message: Exit status to include in Nagios output. String
402   - will be filtered to remove characters that may cause Nagios to
403   - ignore or misinterpret plugin output.
404   - :type message: string
405   -
406   - """
407   -
408   - # Nagios considers a pipe (|) a split from STATUS MESSAGE and perf
409   - # data. If we replace it with a space, that should safely render the
410   - # message safe without risking making it unreadable.
411   -
412   - try:
413   - assert message is not None
414   - self.__exit_message = message.replace('|', ' ')
415   - except (AttributeError, AssertionError):
416   - self.unknown_error("Status message must be a standard string!")
417   -
418   - def start(self):
419   - """
420   - Invokes all preparation steps to retrieve host/service status.
421   -
422   - Starts the actual plugin's work. The Plugin class will start by
423   - parsing any options so the whole process can short-circuit before
424   - we do anything important.
425   -
426   - .. note::
427   -
428   - This method may exit directly to the console.
429   -
430   - """
431   - (self.options, self.arguments) = self.__opt_parser.parse_args()
432   -
433   - for opt_name in self.__req_option:
434   - if not getattr(self.options, opt_name):
435   - self.__opt_parser.error("Required option '%s' not set!" %
436   - opt_name)
437   -
438   - self.__started = True
439   - self.__exit_status = 'OK'
440   -
441   - def unknown_error(self, message):
442   - """
443   - The Plugin encountered an unexpected error, and must immediately exit.
444   -
445   - The plugin system itself handles all the necessary details when
446   - processing thresholds, which will take care of OK, WARNING, and
447   - CRITICAL exit status, but what about UNKNOWN? If some kind of
448   - unexpected behavior or parameter, or otherwise misbehaving resource
449   - confuses our plugin, we should immediately stop and reconsider.
450   - Call this to generate Nagios output with an optional message as to
451   - why the plugin quit processing.
452   -
453   - This allows 'finish' to continue to function as an expected exit
454   - point full of processed performance metrics without unnecessary
455   - error handling/formatting logic.
456   -
457   - :param message: Exit status to include in Nagios output.
458   - :type message: string
459   -
460   - """
461   - print 'Status Unknown: ' + message
462   - sys.exit(3)
463   -
464   -def convert_range(option, opt_str, value, parser):
465   - """
466   - Convert a warning/critical range into separate testable variables.
467   -
468   - Nagios warning or critical status tests are actually ranges with
469   - some weird rules. See the developer documentation to see them all,
470   - but rest assured we've implemented *all* of them.
471   -
472   - :param values: All values currently parsed by OptionParser. We'll
473   - be adding 'dest' to the pile or extending its values.
474   - :param dest: **warning** or **critical** range to convert.
475   - :param value: Range text as passed from the command-line. The
476   - option parser splits these up if multiple ranges are specified,
477   - so there's no need to split on a comma and loop.
478   -
479   - """
480   - # Preserve the original option string for print output.
481   - parser.values.ensure_value("raw_%s" % option.dest, value)
482   -
483   - for part in value.split(','):
484   -
485   - # If we find a '@' at the beginning of the range, it's inclusive
486   -
487   - inclusive = False
488   -
489   - if part.find('@') == 0:
490   - inclusive = True
491   - part = part.lstrip('@')
492   -
493   - # The : separates a max/min range. If it exists, there is at least
494   - # a minimum. We'll start our ranges at infinity so we don't have to
495   - # worry about complex testing logic.
496   -
497   - bottom = -float('infinity')
498   - top = float('infinity')
499   -
500   - if part.find(':') > 0:
501   - (bottom, top) = part.split(':')
502   - if top == '':
503   - top = float('infinity')
504   - else:
505   - top = float(top)
506   -
507   - if bottom == '~':
508   - bottom = -float('infinity')
509   - else:
510   - bottom = float(bottom)
511   - else:
512   - bottom = float(part)
513   -
514   - # Place bottom, top, and inclusive into a single entry for each found
515   - # threshold. This lets a user see all possible ranges passed by the
516   - # user, and select a set based on specification order.
517   -
518   - parser.values.ensure_value(option.dest, []).append([bottom,
519   - top, inclusive])
520   -
521   -
522   -if __name__ == "__main__":
523   - PLUGTEST = Plugin()
524   - sys.exit(0)
525   -
20 build/lib.linux-i686-2.6/NagAconda/__init__.py
... ... @@ -1,20 +0,0 @@
1   -"""
2   -:mod:`NagAconda` -- Python Nagios Integration
3   -=============================================
4   -
5   -Nagios has been around for quite some time, but producing output it can
6   -consume is something of a black art. Only the plugin documentation actually
7   -explains what all the extra semicolons or extended formatting even means.
8   -
9   -This is especially onerous when performance consuming add-ons expect a
10   -specific structure before operating properly. This package strives to
11   -greatly simplify the process of actually generating Nagios output.
12   -
13   -.. automodule:: NagAconda.Plugin
14   -
15   -"""
16   -
17   -__version__ = "0.1.4"
18   -
19   -from Plugin import *
20   -

0 comments on commit e850e19

Please sign in to comment.
Something went wrong with that request. Please try again.