Skip to content

Commit

Permalink
initial, untested import from http://hg.mozilla.org/build/puppet-mani…
Browse files Browse the repository at this point in the history
  • Loading branch information
Dustin J. Mitchell committed May 20, 2011
0 parents commit b70419f
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
A very simple module to allow nagios service check results to be submitted via
NSCA.

== Usage ==
>>> from pynsca import NSCANotifier
>>> notif = NSCANotifier("nagios")
>>> notif.svc_result("host", "service", pynsca.OK, "Looks Good!")

== Requirements ==

* Python 2.4 or higher
* No other libraries required
120 changes: 120 additions & 0 deletions pynsca.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is pynsca.
#
# The Initial Developer of the Original Code is Dustin J. Mitchell. Portions
# created by Dustin J. Mitchell are Copyright (C) Mozilla, Inc. All Rights
# Reserved.
#
# Alternatively, the contents of this file may be used under the terms of the
# GNU Public License, Version 2 (the "GPLv2 License"), in which case the
# provisions of GPLv2 License are applicable instead of those above. If you
# wish to allow use of your version of this file only under the terms of the
# GPLv2 License and not to allow others to use your version of this file under
# the MPL, indicate your decision by deleting the provisions above and replace
# them with the notice and other provisions required by the GPLv2 License. If
# you do not delete the provisions above, a recipient may use your version of
# this file under either the MPL or the GPLv2 License.

import struct, binascii, itertools, socket

# return value constants
OK = 0
UP = 0
WARNING = 1
DOWN = 2
UNREACHABLE = 2
CRITICAL = 2
UNKNOWN = 3

class NSCANotifier(object):
"""
Class to send notifications to a Nagios server via NSCA.
This *only* supports XOR encryption right now.
"""

class TimeoutError(Exception): pass

# utilities for below
proto_version = 3
fromserver_fmt = "!128sL"
fromserver_fmt_size = struct.calcsize(fromserver_fmt)
toserver_fmt = "!HxxlLH64s128s514s"
toserver_fmt_size = struct.calcsize(toserver_fmt)

def __init__(self, monitoring_server, monitoring_port=5667):
self.monitoring_server = monitoring_server
self.monitoring_port = monitoring_port

def _decode_from_server(self, bytes):
iv, timestamp = struct.unpack(self.fromserver_fmt, bytes)
return iv, timestamp

def _encode_to_server(self, iv, timestamp, return_code, host_name,
svc_description, plugin_output):
# note that this will pad the strings with 0's instead of random digits. Oh well.
toserver = [
self.proto_version,
0, # crc32_value
timestamp,
return_code,
host_name,
svc_description,
plugin_output,
]

# calculate crc32 and insert into the list
crc32 = binascii.crc32(struct.pack(self.toserver_fmt, *toserver))
toserver[1] = crc32

# convert to bytes
toserver_pkt = struct.pack(self.toserver_fmt, *toserver)

# and XOR with the IV
toserver_pkt = ''.join([chr(p^i)
for p,i in itertools.izip(
itertools.imap(ord, toserver_pkt),
itertools.imap(ord, itertools.cycle(iv)))])

return toserver_pkt

def svc_result(self, host_name, svc_description, return_code, plugin_output):
"""
Send a service result to the configured monitoring host
Note that the nagios server provides no way to tell if it has actually
processed the check result.
@param host_name: host containing the service
@param svc_description: description of the service with the result
@param return_code: result (e.g., C{OK} or C{CRITICAL})
@param plugin_output: textual output
"""
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect((self.monitoring_host, self.monitoring_port))

# read packet
buf = ''
while len(buf) < self.fromserver_fmt_size:
data = sk.recv(self.fromserver_fmt_size - len(buf))
if not data:
break
buf += data

# make up reply
iv, timestamp = self._decode_from_server(buf)
toserver_pkt = self._encode_to_server(iv, timestamp, return_code,
host_name, svc_description, plugin_output)

# and send it
sk.send(toserver_pkt)
56 changes: 56 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is pynsca.
#
# The Initial Developer of the Original Code is Dustin J. Mitchell. Portions
# created by Dustin J. Mitchell are Copyright (C) Mozilla, Inc. All Rights
# Reserved.
#
# Alternatively, the contents of this file may be used under the terms of the
# GNU Public License, Version 2 (the "GPLv2 License"), in which case the
# provisions of GPLv2 License are applicable instead of those above. If you
# wish to allow use of your version of this file only under the terms of the
# GPLv2 License and not to allow others to use your version of this file under
# the MPL, indicate your decision by deleting the provisions above and replace
# them with the notice and other provisions required by the GPLv2 License. If
# you do not delete the provisions above, a recipient may use your version of
# this file under either the MPL or the GPLv2 License.

import os
from setuptools import setup, find_packages

descr = open(os.path.join(os.path.dirname(__file__), 'README.txt')).read()

setup(
name='pynsca',
version='1.0',
description='Simple Python interface to Nagios Service Check Architecture',
long_description=descr,
author='Dustin J. Mitchell',
author_email='[email protected]',
url='http://github.com/djmitche/pynsca',
license='MPL-1.1',
packages=find_packages(),
py_modules=['pynsca'],
include_package_data=True,
zip_safe=False,
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: System :: Monitoring',
'Topic :: System :: Networking :: Monitoring',
'Topic :: Software Development :: Libraries :: Python Modules',
],
)

0 comments on commit b70419f

Please sign in to comment.