Utils Package

Utils Package

Misc utility classes and helper functions for pynag

This module contains misc classes and conveninence functions that are used throughout the pynag library.

class pynag.Utils.AttributeList(value=None)

Bases: object

Parse a list of nagios attributes (e. contact_groups) into a parsable format

This makes it handy to mangle with nagios attribute values that are in a comma seperated format.

Typical comma-seperated format in nagios configuration files looks something like this:
contact_groups +group1,group2,group3
>>> i = AttributeList('+group1,group2,group3')
>>> print("Operator is: %s" % i.operator)
Operator is: +
>>> print(i.fields)
['group1', 'group2', 'group3']

if your data is already in a list format you can use it directly: >>> i = AttributeList([‘group1’, ‘group2’, ‘group3’]) >>> print(i.fields) [‘group1’, ‘group2’, ‘group3’]

white spaces will be stripped from all fields >>> i = AttributeList(‘+group1, group2’) >>> print(i) +group1,group2


Same as list.append()

>>> i = AttributeList('group1,group2,group3')
>>> i.append('group5')
>>> print(i.fields)
['group1', 'group2', 'group3', 'group5']

Same as list.count()

>>> i = AttributeList('group1,group2,group3')
>>> i.count('group3')

Same as list.extend()

>>> i = AttributeList('group1,group2,group3')
>>> i.extend(['group4', 'group5'])
>>> print(i.fields)
['group1', 'group2', 'group3', 'group4', 'group5']
index(value, start=0, stop=None)

Same as list.index()

>>> i = AttributeList('group1,group2,group3')
>>> i.index('group2')
>>> i.index('group3', 2, 5)
insert(index, object)

Same as list.insert()

>>> i = AttributeList('group1,group2,group3')
>>> i.insert(1, 'group4')
>>> print(i.fields)
['group1', 'group4', 'group2', 'group3']

Same as list.remove()

>>> i = AttributeList('group1,group2,group3')
>>> i.remove('group3')
>>> print(i.fields)
['group1', 'group2']

Same as list.reverse()

>>> i = AttributeList('group1,group2,group3')
>>> i.reverse()
>>> print(i.fields)
['group3', 'group2', 'group1']

Same as list.sort()

>>> i = AttributeList('group3,group1,group2')
>>> i.sort()
>>> print(i.fields)
['group1', 'group2', 'group3']
class pynag.Utils.GitRepo(directory, auto_init=True, author_name='Pynag User', author_email=None)

Bases: object


Run git add on filename

filename – name of one file to add,
The stdout from “git add” shell command.
commit(message='commited by pynag', filelist=None, author=None)

Commit files with “git commit”

message – Message used for the git commit filelist – List of filenames to commit (if None, then commit all files in the repo) author – Author to use for git commit. If any is specified, overwrite self.author_name and self.author_email
Returns stdout from the “git commit” shell command.

Returns diff (as outputted by “git diff”) for filename or commit id.

If commit_id_or_filename is not specified. show diff against all uncommited files.


Returns a list of files that are have unstaged changes


Returns a list of all commit ids from git log


Initilizes a new git repo (i.e. run “git init”)


Returns True if filename needs to be committed to git


Returns True if all files in git repo are fully commited


Returns a log of previous commits. Log is is a list of dict objects.

Any arguments provided will be passed directly to pynag.Utils.grep() to filter the results.

self.log(author_name=’nagiosadmin’) self.log(comment__contains=’localhost’)
pre_save(object_definition, message)

Commits object_definition.get_filename() if it has any changes


Revert some existing commits works like “git revert”

save(object_definition, message)

Returns output from “git show” for a specified commit_id

write(object_definition, message)
class pynag.Utils.PerfData(perfdatastring='')

Bases: object

Data Structure for a nagios perfdata string with multiple perfdata metric

Example string: >>> perf = PerfData(“load1=10 load2=10 load3=20 ‘label with spaces’=5”) >>> perf.metrics [‘load1’=10;;;;, ‘load2’=10;;;;, ‘load3’=20;;;;, ‘label with spaces’=5;;;;] >>> for i in perf.metrics: print(“%s %s” % (i.label, i.value)) load1 10 load2 10 load3 20 label with spaces 5

add_perfdatametric(perfdatastring='', label='', value='', warn='', crit='', min='', max='', uom='')

Add a new perfdatametric to existing list of metrics.

Example: >>> s = PerfData() >>> s.add_perfdatametric(“a=1”) >>> s.add_perfdatametric(label=”utilization”,value=”10”,uom=”%”)


Get one specific perfdatametric >>> s = PerfData(“cpu=90% memory=50% disk_usage=20%”) >>> my_metric = s.get_perfdatametric(‘cpu’) >>> my_metric.label, my_metric.value (‘cpu’, ‘90’)


Returns True if the every metric in the string is valid

Example usage: >>> PerfData(“load1=10 load2=10 load3=20”).is_valid() True >>> PerfData(“10b”).is_valid() False >>> PerfData(“load1=”).is_valid() False >>> PerfData(“load1=10 10”).is_valid() False


Convert all thresholds in new_threshold_syntax to the standard one

class pynag.Utils.PerfDataMetric(perfdatastring='', label='', value='', warn='', crit='', min='', max='', uom='')

Bases: object

Data structure for one single Nagios Perfdata Metric

crit = ''

Return nagios-style exit code (int 0-3) by comparing

self.value with self.warn and self.crit

>>> PerfDataMetric("label1=10;20;30").get_status()
>>> PerfDataMetric("label2=25;20;30").get_status()
>>> PerfDataMetric("label3=35;20;30").get_status()

# Invalid metrics always return unknown >>> PerfDataMetric(“label3=35;invalid_metric”).get_status() 3


Returns True if all Performance data is valid. Otherwise False

Example Usage: >>> PerfDataMetric(“load1=2”).is_valid() True >>> PerfDataMetric(“load1”).is_valid() False >>> PerfDataMetric(‘’).is_valid() False >>> PerfDataMetric(‘invalid_value=invalid’).is_valid() False >>> PerfDataMetric(‘invalid_min=0;0;0;min;0’).is_valid() False >>> PerfDataMetric(‘invalid_min=0;0;0;0;max’).is_valid() False >>> PerfDataMetric(‘label with spaces=0’).is_valid() False >>> PerfDataMetric(“‘label with spaces=0’”).is_valid() False

label = ''
max = ''
min = ''

Convert threshold from new threshold syntax to current one, for backwards compatibility


get value=”10M” and return (10,”M”) >>> p = PerfDataMetric() >>> p.split_value_and_uom( “10” ) (‘10’, ‘’) >>> p.split_value_and_uom( “10c” ) (‘10’, ‘c’) >>> p.split_value_and_uom( “10B” ) (‘10’, ‘B’) >>> p.split_value_and_uom( “10MB” ) (‘10’, ‘MB’) >>> p.split_value_and_uom( “10KB” ) (‘10’, ‘KB’) >>> p.split_value_and_uom( “10TB” ) (‘10’, ‘TB’) >>> p.split_value_and_uom( “10%” ) (‘10’, ‘%’) >>> p.split_value_and_uom( “10s” ) (‘10’, ‘s’) >>> p.split_value_and_uom( “10us” ) (‘10’, ‘us’) >>> p.split_value_and_uom( “10ms” ) (‘10’, ‘ms’)

uom = ''
value = ''
warn = ''
class pynag.Utils.PluginOutput(stdout)

This class parses a typical stdout from a nagios plugin

It splits the output into the following fields: * Summary * Long Output * Perfdata

Example UsagE: >>> p = PluginOutput(“Everything is ok | load1=15 load2=10”) >>> p.summary ‘Everything is ok ‘ >>> p.long_output ‘’ >>> p.perfdata ‘load1=15 load2=10’ >>> p.parsed_perfdata.metrics [‘load1’=15;;;;, ‘load2’=10;;;;]

long_output = None
parsed_perfdata = None
perfdata = None
summary = None
exception pynag.Utils.PynagError(message, errorcode=None, errorstring=None, *args, **kwargs)

Bases: exceptions.Exception

The default pynag exception.

Exceptions raised within the pynag library should aim to inherit this one.

class pynag.Utils.defaultdict(default_factory=None, *a, **kw)

Bases: dict

This is an alternative implementation of collections.defaultdict.

Used as a fallback if using python 2.4 or older.

Usage: try:

from collections import defaultdict
except ImportError:
from pynag.Utils import defaultdict
pynag.Utils.grep(objects, **kwargs)

Returns all the elements from array that match the keywords in **kwargs

See documentation for pynag.Model.ObjectDefinition.objects.filter() for example how to use this.

array – a list of dict that is to be searched kwargs – Any search argument provided will be checked against every dict

Examples: array = [ {‘host_name’: ‘examplehost’, ‘state’:0}, {‘host_name’: ‘example2’, ‘state’:1}, ] grep_dict(array, state=0) # should return [{‘host_name’: ‘examplehost’, ‘state’:0},]

pynag.Utils.grep_to_livestatus(*args, **kwargs)

Converts from pynag style grep syntax to livestatus filter syntax.

>>> grep_to_livestatus(host_name='test')
['Filter: host_name = test']
>>> grep_to_livestatus(service_description__contains='serv')
['Filter: service_description ~ serv']
>>> grep_to_livestatus(service_description__isnot='serv')
['Filter: service_description != serv']
>>> grep_to_livestatus(service_description__contains=['serv','check'])
['Filter: service_description ~ serv']
>>> grep_to_livestatus(service_description__contains='foo', contacts__has_field='admin')
['Filter: contacts >= admin', 'Filter: service_description ~ foo']
>>> grep_to_livestatus(service_description__has_field='foo')
['Filter: service_description >= foo']
>>> grep_to_livestatus(service_description__startswith='foo')
['Filter: service_description ~ ^foo']
>>> grep_to_livestatus(service_description__endswith='foo')
['Filter: service_description ~ foo$']

Take threshold string as and normalize it to the format supported by plugin development team

the input (usually a string in the form of ‘the new threshold syntax’) is a string in the form of x..y

the output will be a compatible string in the older nagios plugin format @x:y

examples >>> reconsile_threshold(“0..5”) ‘@0:5’ >>> reconsile_threshold(“inf..5”) ‘5:’ >>> reconsile_threshold(“5..inf”) ‘~:5’ >>> reconsile_threshold(“inf..inf”) ‘@~:’ >>> reconsile_threshold(“^0..5”) ‘0:5’ >>> reconsile_threshold(“10..20”) '@10:20’ >>> reconsile_threshold(“10..inf”) ‘~:10’

pynag.Utils.runCommand(command, raise_error_on_fail=False, shell=True, env=None)

Run command from the shell prompt. Wrapper around subprocess.

command: string containing the command line to run raise_error_on_fail: Raise PynagError if returncode >0
stdout/stderr of the command run
PynagError if returncode > 0
pynag.Utils.send_nsca(code, message, nscahost, hostname=None, service=None, nscabin='send_nsca', nscaconf=None)

Send data via send_nsca for passive service checks


code – Return code of plugin. message – Message to pass back. nscahost – Hostname or IP address of NSCA server. hostname – Hostname the check results apply to. service – Service the check results apply to. nscabin – Location of send_nsca binary. If none specified whatever

is in the path will be used.

nscaconf – Location of the NSCA configuration to use if any.

Returns: [result,stdout,stderr] of the command being run


Synchronization decorator

Use this to make a multi-threaded method synchronized and thread-safe.

Use the decorator like so: @pynag.Utils.synchronized(pynag.Utils.rlock)