Skip to content
This repository has been archived by the owner on Mar 12, 2019. It is now read-only.

Commit

Permalink
Remove requests and jinja2 dependencies. Fixes #9
Browse files Browse the repository at this point in the history
  • Loading branch information
hannseman committed Mar 20, 2014
1 parent 7a41497 commit c311c4a
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 61 deletions.
1 change: 0 additions & 1 deletion MANIFEST.in
@@ -1,3 +1,2 @@
include LICENSE *.txt README.md
exclude hipsaint/tests.py
recursive-include hipsaint/templates *
3 changes: 3 additions & 0 deletions Makefile
Expand Up @@ -12,3 +12,6 @@ develop:

coverage:
coverage run --include=hipsaint/* setup.py test

clean:
rm -rf .tox/ dist/ *.egg *.egg-info .coverage reports/
2 changes: 1 addition & 1 deletion hipsaint/__init__.py
@@ -1,4 +1,4 @@
VERSION = (0, 4, 3, 'final', 0)
VERSION = (0, 4, 4, 'final', 0)


def get_version(version=None):
Expand Down
6 changes: 3 additions & 3 deletions hipsaint/bin/commands.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
from optparse import OptionParser
import hipsaint
from hipsaint.messages import HipchatMessage
from ..messages import HipchatMessage


def main():
Expand Down Expand Up @@ -30,7 +30,7 @@ def main():
help="Input variables from Nagios separated by |")

parser.add_option("-T", "--type",
dest="type",
dest="msg_type",
default="",
help="Mark if notification is from host group or service group, host|service|short-host|short-service")

Expand All @@ -49,7 +49,7 @@ def main():
parser.error('--inputs is required')
if not options.room_id:
parser.error('--room is required')
if not options.type:
if not options.msg_type:
parser.error('--type is required')
msg = HipchatMessage(**vars(options))
msg.deliver_payload()
Expand Down
63 changes: 38 additions & 25 deletions hipsaint/messages.py
@@ -1,10 +1,10 @@
import logging
import requests
import urllib
import urllib2
import socket
from os import path
from jinja2.loaders import FileSystemLoader
from jinja2 import Environment
from hipsaint.options import COLORS
import json
from .options import COLORS
from .templates import templates

logging.basicConfig()
log = logging.getLogger(__name__)
Expand All @@ -14,17 +14,20 @@ class HipchatMessage(object):
url = "https://api.hipchat.com/v1/rooms/message"
default_color = 'red'

def __init__(self, type, inputs, token, user, room_id, notify, **kwargs):
self.type = type
def __init__(self, msg_type, inputs, token, user, room_id, notify):
self.type = msg_type
self.inputs = inputs
self.inputs_list = [input.strip() for input in self.inputs.split('|')]
self.token = token
self.user = user
self.room_id = room_id
self.notify = notify
self.message_color = 'gray'

def deliver_payload(self, **kwargs):
""" Makes HTTP GET request to HipChat containing the message from nagios
according to API Documentation https://www.hipchat.com/docs/api/method/rooms/message
"""
Makes HTTP GET request to HipChat containing the message from nagios
according to API Documentation https://www.hipchat.com/docs/api/method/rooms/message
"""
message_body = self.render_message()
message = {'room_id': self.room_id,
Expand All @@ -34,8 +37,9 @@ def deliver_payload(self, **kwargs):
'notify': int(self.notify),
'auth_token': self.token}
message.update(kwargs)
raw_response = requests.get(self.url, params=message)
response_data = raw_response.json()
message_params = urllib.urlencode(message)
raw_response = urllib2.urlopen(self.url, message_params)
response_data = json.load(raw_response)
if 'error' in response_data:
error_message = response_data['error'].get('message')
error_type = response_data['error'].get('type')
Expand All @@ -45,29 +49,38 @@ def deliver_payload(self, **kwargs):
log.error('Unexpected response')
return raw_response

def get_host_context(self):
hostname, timestamp, ntype, hostaddress, state, hostoutput = self.inputs_list
return {'hostname': hostname, 'timestamp': timestamp, 'ntype': ntype,
'hostaddress': hostaddress, 'state': state, 'hostoutput': hostoutput}

def get_service_context(self):
servicedesc, hostalias, timestamp, ntype, hostaddress, state, serviceoutput = self.inputs_list
return {'servicedesc': servicedesc, 'hostalias': hostalias, 'timestamp': timestamp,
'ntype': ntype, 'hostaddress': hostaddress, 'state': state,
'serviceoutput': serviceoutput}

def render_message(self):
""" Unpacks Nagios inputs and renders the appropriate template depending
on the notification type.
"""
Unpacks Nagios inputs and renders the appropriate template depending
on the notification type.
"""
template_type = self.type
inputs = [x.strip() for x in self.inputs.split('|')]

if template_type == 'host' or template_type == 'short-host':
hostname, timestamp, ntype, hostaddress, state, hostoutput = inputs
elif template_type == 'service' or template_type == 'short-service':
servicedesc, hostalias, timestamp, ntype, hostaddress, state, serviceoutput = inputs
if template_type in ('host', 'short-host'):
template_context = self.get_host_context()
elif template_type in ('service', 'short-service'):
template_context = self.get_service_context()
else:
raise Exception('Invalid notification type')

ntype = template_context['ntype']
state = template_context['state']
if ntype != 'PROBLEM':
self.message_color = COLORS.get(ntype, self.default_color)
else:
self.message_color = COLORS.get(state, self.default_color)
nagios_host = socket.gethostname().split('.')[0]

template_path = path.realpath(path.join(path.dirname(__file__), 'templates'))
env = Environment(loader=FileSystemLoader(template_path))
template = env.get_template('{tmpl}.html'.format(tmpl=template_type))
context = locals()
context.pop('self')
return template.render(**context)
template_context.update(nagios_host=nagios_host)
template = templates[template_type]
return template.format(**template_context)
29 changes: 29 additions & 0 deletions hipsaint/templates.py
@@ -0,0 +1,29 @@
"""
Templates used to build hipchat api payloads
"""

host_template = """
<strong>{timestamp} - {hostname} (nagios@{nagios_host})</strong><br/>
<strong>Type:</strong> {ntype}<br/>
<strong>Host:</strong> {hostname} (<a href="{hostaddress}">{hostaddress}</a>)<br/>
<strong>State:</strong> {state}<br>
<strong>Info:</strong>
<pre>{hostoutput}</pre>
"""

host_short_template = """[{ntype}] {hostname}: {hostoutput}"""

service_template = """
<strong>{timestamp} - {servicedesc} on {hostalias} (nagios@{nagios_host})</strong><br/>
<strong>Type:</strong> {ntype}<br/>
<strong>Host:</strong> {hostalias} (<a href="{hostaddress}">{hostaddress}</a>)<br/>
<strong>State:</strong> {state}<br/>
<strong>Info:</strong>
<pre>{serviceoutput}</pre>
"""

service_short_template = "[{ntype}] {hostalias} {servicedesc}: {serviceoutput}"


templates = {'host': host_template, 'short-host': host_short_template,
'service': service_template, 'short-service': service_short_template}
6 changes: 0 additions & 6 deletions hipsaint/templates/host.html

This file was deleted.

6 changes: 0 additions & 6 deletions hipsaint/templates/service.html

This file was deleted.

1 change: 0 additions & 1 deletion hipsaint/templates/short-host.html

This file was deleted.

1 change: 0 additions & 1 deletion hipsaint/templates/short-service.html

This file was deleted.

24 changes: 13 additions & 11 deletions hipsaint/tests.py
@@ -1,13 +1,14 @@
import unittest
import mock
import json
from datetime import datetime
from hipsaint.messages import HipchatMessage
from .messages import HipchatMessage


def setup_mock_request(mock_method, status_code, json):
def setup_mock_request(mock_method, status_code, json_data):
mock_response = mock.Mock()
mock_response.json.return_value = json
mock_response.status_code = status_code
mock_response.read.return_value = json.dumps(json_data)
mock_response.getcode.return_value = status_code
mock_method.return_value = mock_response


Expand All @@ -28,27 +29,29 @@ def setUp(self):
#"$SERVICEDESC$|$HOSTALIAS$|$LONGDATETIME$|$NOTIFICATIONTYPE$|$HOSTADDRESS$|$SERVICESTATE$|$SERVICEOUTPUT$"
self.service_inputs = 'servicedesc|hostalias|%(longdatetime)s|%(notificationtype)s|127.0.0.1|%(servicestate)s|NAGIOS_OUTPUT'

@mock.patch('requests.get')
@mock.patch('urllib2.urlopen')
def test_ok_payload_delivery(self, mock_get):
mock_hipchat_ok_request(mock_get)
msg_inputs = self.host_inputs % {'longdatetime': datetime.now(),
'notificationtype': 'PROBLEM',
'hoststate': 'DOWN'}
problem_msg = HipchatMessage('host', msg_inputs, None, None, None, False)
response = problem_msg.deliver_payload()
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json()['status'], 'sent')
self.assertEqual(response.getcode(), 200)
response_data = json.load(response)
self.assertEqual(response_data['status'], 'sent')

@mock.patch('requests.get')
@mock.patch('urllib2.urlopen')
def test_error_payload_delivery(self, mock_get):
mock_hipchat_error_request(mock_get)
msg_inputs = self.host_inputs % {'longdatetime': datetime.now(),
'notificationtype': 'PROBLEM',
'hoststate': 'DOWN'}
problem_msg = HipchatMessage('host', msg_inputs, None, None, None, False)
response = problem_msg.deliver_payload()
self.assertEqual(response.status_code, 401)
self.assertTrue('error' in response.json())
response_data = json.load(response)
self.assertEqual(response.getcode(), 401)
self.assertTrue('error' in response_data)

def test_render_host(self):
message_type = 'host'
Expand Down Expand Up @@ -91,7 +94,6 @@ def test_render_service(self):
'notificationtype': 'PROBLEM',
'servicestate': 'WARNING'}
problem_msg = HipchatMessage(message_type, msg_inputs, None, None, None, False)
problem_msg.render_message()
self.assertEqual(problem_msg.message_color, 'yellow')

msg_inputs = self.service_inputs % {'longdatetime': datetime.now(),
Expand Down
2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

4 changes: 0 additions & 4 deletions setup.py
Expand Up @@ -34,10 +34,6 @@
include_package_data=True,
test_suite='hipsaint.tests',
tests_require=['mock'],
install_requires=[
"Jinja2>=2.6",
"requests>=1.1.0"
],
entry_points="""
[console_scripts]
hipsaint=hipsaint.bin.commands:main
Expand Down

0 comments on commit c311c4a

Please sign in to comment.