66# Released under the same terms as Sensu (the MIT license); see LICENSE
77# for details.
88
9+ '''
10+ This provides a base SensuHandler class that can be used for writing
11+ python-based Sensu handlers.
12+ '''
13+
914from __future__ import print_function
1015import os
1116import sys
17+ import json
1218import requests
1319try :
1420 from urlparse import urlparse
1521except ImportError :
1622 from urllib .parse import urlparse
17- from utils import *
23+ from sensu_plugin . utils import get_settings
1824
1925
2026class SensuHandler (object ):
27+ '''
28+ Class to be used as a basis for handlers.
29+ '''
2130 def __init__ (self ):
2231 # Parse the stdin into a global event object
2332 stdin = sys .stdin .read ()
@@ -40,8 +49,8 @@ def read_event(self, check_result):
4049 self .event ['occurrences' ] = self .event .get ('occurrences' , 1 )
4150 self .event ['check' ] = self .event .get ('check' , {})
4251 self .event ['client' ] = self .event .get ('client' , {})
43- except Exception as e :
44- print ('error reading event: ' + e . message )
52+ except Exception as exception : # pylint: disable=broad-except
53+ print ('error reading event: ' + exception )
4554 sys .exit (1 )
4655
4756 def handle (self ):
@@ -63,7 +72,7 @@ def filter(self):
6372 self .filter_silenced ()
6473 self .filter_dependencies ()
6574
66- if self .deprecated_occurrence_filtering_enabled ():
75+ if self .deprecated_occurrence_filtering ():
6776 print ('warning: occurrence filtering in sensu-plugin is' +
6877 'deprecated, see http://bit.ly/sensu-plugin' )
6978 self .filter_repeated ()
@@ -78,7 +87,7 @@ def deprecated_filtering_enabled(self):
7887 '''
7988 return self .event ['check' ].get ('enable_deprecated_filtering' , False )
8089
81- def deprecated_occurrence_filtering_enabled (self ):
90+ def deprecated_occurrence_filtering (self ):
8291 '''
8392 Evaluates whether the event should be processed by the
8493 filter_repeated method. Defaults to true, i.e. filter_repeated
@@ -94,23 +103,23 @@ def bail(self, msg):
94103 '''
95104 Gracefully terminate with message
96105 '''
97- client_name = self .event [ 'client' ] .get ('name ' , 'error:no-client-name' )
106+ client_name = self .event .get ('client ' , 'error:no-client-name' )
98107 check_name = self .event ['client' ].get ('name' , 'error:no-check-name' )
99108 print ('{}: {}/{}' .format (msg , client_name , check_name ))
100109 sys .exit (0 )
101110
102111 def get_api_settings (self ):
103112 '''
104- Return a hash of API settings derived first from ENV['SENSU_API_URL ']
113+ Return a hash of API settings derived first from ENV['sensu_api_url ']
105114 if set, then Sensu config `api` scope if configured, and finally
106115 falling back to to ipv4 localhost address on default API port.
107116
108117 return dict
109118 '''
110119
111- SENSU_API_URL = os .environ .get ('SENSU_API_URL ' )
112- if SENSU_API_URL :
113- uri = urlparse (SENSU_API_URL )
120+ sensu_api_url = os .environ .get ('sensu_api_url ' )
121+ if sensu_api_url :
122+ uri = urlparse (sensu_api_url )
114123 self .api_settings = {
115124 'host' : '{0}//{1}' .format (uri .scheme , uri .hostname ),
116125 'port' : uri .port ,
@@ -125,7 +134,10 @@ def get_api_settings(self):
125134 'port' , 4567 )
126135
127136 # API requests
128- def api_request (method , path , blk ):
137+ def api_request (self , method , path ):
138+ '''
139+ Query Sensu api for information.
140+ '''
129141 if not hasattr (self , 'api_settings' ):
130142 ValueError ('api.json settings not found' )
131143
@@ -135,7 +147,6 @@ def api_request(method, path, blk):
135147 _request = requests .post
136148
137149 domain = self .api_settings ['host' ]
138- # TODO: http/https
139150 uri = 'http://{}:{}{}' .format (domain , self .api_settings ['port' ], path )
140151 if self .api_settings ['user' ] and self .api_settings ['password' ]:
141152 auth = (self .api_settings ['user' ], self .api_settings ['password' ])
@@ -145,19 +156,32 @@ def api_request(method, path, blk):
145156 return req
146157
147158 def stash_exists (self , path ):
159+ '''
160+ Query Sensu API for stash data.
161+ '''
148162 return self .api_request ('get' , '/stash' + path ).status_code == 200
149163
150164 def event_exists (self , client , check ):
151- return self .api_request ('get' ,
152- '/events/{}/{}' .format (client , check )
153- ).status_code == 200
165+ '''
166+ Query Sensu API for event.
167+ '''
168+ return self .api_request (
169+ 'get' ,
170+ 'events/{}/{}' .format (client , check )
171+ ).status_code == 200
154172
155173 # Filters
156174 def filter_disabled (self ):
175+ '''
176+ Determine whether a check is disabled and shouldn't handle.
177+ '''
157178 if self .event ['check' ]['alert' ] is False :
158- bail ('alert disabled' )
179+ self . bail ('alert disabled' )
159180
160181 def filter_silenced (self ):
182+ '''
183+ Determine whether a check is silenced and shouldn't handle.
184+ '''
161185 stashes = [
162186 ('client' , '/silence/{}' .format (self .event ['client' ]['name' ])),
163187 ('check' , '/silence/{}/{}' .format (
@@ -166,17 +190,18 @@ def filter_silenced(self):
166190 ('check' , '/silence/all/{}' .format (self .event ['check' ]['name' ]))
167191 ]
168192 for scope , path in stashes :
169- if stash_exists (path ):
170- bail (scope + ' alerts silenced' )
171- # TODO: Timeout for querying Sensu API?
172- # More appropriate in the api_request method?
193+ if self .stash_exists (path ):
194+ self .bail (scope + ' alerts silenced' )
173195
174196 def filter_dependencies (self ):
197+ '''
198+ Determine whether a check has dependencies.
199+ '''
175200 dependencies = self .event ['check' ].get ('dependencies' , None )
176201 if dependencies is None or not isinstance (dependencies , list ):
177202 return
178203 for dependency in self .event ['check' ]['dependencies' ]:
179- if len ( str (dependency )) == 0 :
204+ if not str (dependency ):
180205 continue
181206 dependency_split = tuple (dependency .split ('/' ))
182207 # If there's a dependency on a check from another client, then use
@@ -187,9 +212,12 @@ def filter_dependencies(self):
187212 client = self .event ['client' ]['name' ]
188213 check = dependency_split [0 ]
189214 if self .event_exists (client , check ):
190- bail ('check dependency event exists' )
215+ self . bail ('check dependency event exists' )
191216
192217 def filter_repeated (self ):
218+ '''
219+ Determine whether a check is repeating.
220+ '''
193221 defaults = {
194222 'occurrences' : 1 ,
195223 'interval' : 30 ,
@@ -198,8 +226,7 @@ def filter_repeated(self):
198226
199227 # Override defaults with anything defined in the settings
200228 if isinstance (self .settings ['sensu_plugin' ], dict ):
201- defaults .update (settings ['sensu_plugin' ])
202- end
229+ defaults .update (self .settings ['sensu_plugin' ])
203230
204231 occurrences = int (self .event ['check' ].get (
205232 'occurrences' , defaults ['occurrences' ]))
@@ -209,7 +236,7 @@ def filter_repeated(self):
209236 'refresh' , defaults ['refresh' ]))
210237
211238 if self .event ['occurrences' ] < occurrences :
212- bail ('not enough occurrences' )
239+ self . bail ('not enough occurrences' )
213240
214241 if (self .event ['occurrences' ] > occurrences and
215242 self .event ['action' ] == 'create' ):
@@ -220,4 +247,4 @@ def filter_repeated(self):
220247 (self .event ['occurrences' ] - occurrences ) % number == 0 ):
221248 return
222249
223- bail ('only handling every ' + str (number ) + ' occurrences' )
250+ self . bail ('only handling every ' + str (number ) + ' occurrences' )
0 commit comments