1
2
3
4
5
6
7
8
9
10
11
12
13
14 import copy
15 import re
16 import sre_constants
17 import logging
18 import transaction
19 log = logging.getLogger("zen.Events")
20
21 from Globals import DTMLFile
22 from Globals import InitializeClass
23 from AccessControl import ClassSecurityInfo
24 from AccessControl import Permissions
25 from Acquisition import aq_chain
26 from zope.interface import implements
27
28 from Products.ZenModel.interfaces import IIndexed
29 from Products.ZenModel.ZenossSecurity import *
30 from Products.ZenRelations.RelSchema import *
31 from Products.ZenModel.ZenModelRM import ZenModelRM
32 from Products.ZenModel.EventView import EventView
33 from Products.ZenModel.ZenPackable import ZenPackable
34 from Products.ZenWidgets import messaging
35 from Products.ZenUtils.Utils import convToUnits, zdecode
36
37
44
45
46 addEventClassInst = DTMLFile('dtml/addEventClassInst',globals())
47
48
50
51 transform = ''
52
53 _properties = (
54 {'id':'transform', 'type':'text', 'mode':'w'},
55 )
56
58 """Modify event with values taken from dict Inst.
59 Any non-None property values are applied to the event.
60 """
61 evt._clearClasses = copy.copy(getattr(self, "zEventClearClasses", []))
62 evt._action = getattr(self, "zEventAction", "status")
63 sev = getattr(self, "zEventSeverity", -1)
64 if sev >= 0:
65 if evt.severity > 0:
66 evt.severity = sev
67 log.debug("Per transform/mapping, using severity %s, action '%s' and clear classes %s",
68 evt.severity, evt._action, evt._clearClasses)
69 updates = {}
70 for name in 'resolution', 'explanation':
71 value = getattr(self, name, None)
72 if value is not None and value != '':
73 updates[name] = value
74 if updates:
75 log.debug("Adding fields from transform/mapping: %s", updates)
76 evt.updateFromDict(updates)
77 return evt
78
88
132
157
158
173
174
183
184
186 """
187 Return the path to our current EventClassInst from the top level
188 EventClass down. We use this to process and display the heirarchy of
189 event transforms.
190 """
191 transpath = []
192 for obj in aq_chain(self):
193
194 if not isinstance(obj, EventClassPropertyMixin): continue
195 if obj.id == 'dmd': break
196 transpath.append(obj)
197 transpath.reverse()
198 return transpath
199
200
201
202 -class EventClassInst(EventClassPropertyMixin, ZenModelRM, EventView,
203 ZenPackable):
204 """
205 EventClassInst.
206 """
207 implements(IIndexed)
208 event_key = meta_type = "EventClassInst"
209
210 default_catalog = "eventClassSearch"
211
212 actions = ("status", "history", "heartbeat", "drop")
213
214 _properties = EventClassPropertyMixin._properties + (
215 {'id':'eventClassKey', 'type':'string', 'mode':'w'},
216 {'id':'sequence', 'type':'int', 'mode':'w'},
217 {'id':'rule', 'type':'string', 'mode':'w'},
218 {'id':'regex', 'type':'string', 'mode':'w'},
219 {'id':'example', 'type':'string', 'mode':'w'},
220 {'id':'explanation', 'type':'text', 'mode':'w'},
221 {'id':'resolution', 'type':'text', 'mode':'w'},
222 )
223
224
225 _relations = ZenPackable._relations + (
226 ("eventClass", ToOne(ToManyCont,"Products.ZenEvents.EventClass","instances")),
227 )
228
229
230
231 factory_type_information = (
232 {
233 'id' : 'EventClassInst',
234 'meta_type' : 'EventClassInst',
235 'description' : """Base class for all devices""",
236 'icon' : 'EventClassInst.gif',
237 'product' : 'ZenEvents',
238 'factory' : 'manage_addEventClassInst',
239 'immediate_view' : 'eventClassInstStatus',
240 'actions' :
241 (
242 { 'id' : 'status'
243 , 'name' : 'Status'
244 , 'action' : 'eventClassInstStatus'
245 , 'permissions' : (Permissions.view, )
246 },
247 { 'id' : 'edit'
248 , 'name' : 'Edit'
249 , 'action' : 'eventClassInstEdit'
250 , 'permissions' : ("Manage DMD", )
251 },
252 { 'id' : 'sequence'
253 , 'name' : 'Sequence'
254 , 'action' : 'eventClassInstSequence'
255 , 'permissions' : (Permissions.view,)
256 },
257 { 'id' : 'config'
258 , 'name' : 'Configuration Properties'
259 , 'action' : 'zPropertyEditNew'
260 , 'permissions' : ("Manage DMD",)
261 },
262 { 'id' : 'events'
263 , 'name' : 'Events'
264 , 'action' : 'viewEvents'
265 , 'permissions' : (Permissions.view, )
266 },
267
268
269
270
271
272 { 'id' : 'viewHistory'
273 , 'name' : 'Modifications'
274 , 'action' : 'viewNewHistory'
275 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,)
276 },
277 )
278 },
279 )
280
281 security = ClassSecurityInfo()
282
284 ZenModelRM.__init__(self, id)
285 self.eventClassKey = id
286 self.sequence = None
287 self.rule = ""
288 self.regex = ""
289 self.example = ""
290 self.explanation = ""
291 self.resolution = ""
292
293
300
301
303 """Return the full EventClass of this EventClassInst."""
304 return self.getOrganizerName()
305
310
311
313 """Return the dmd key of this mapping ie: /App/Start/zentinel
314 """
315 return self.getOrganizerName() + "/" + self.id
316
317
319 """
320 Apply the event dict regex to extract additional values from the event.
321 """
322 if self.regex:
323 m = re.search(self.regex, evt.message)
324 if m: evt.updateFromDict(m.groupdict())
325 return evt
326
327
335
337 """Return the rule if it exists else return the regex.
338 limit limits the number of characters returned.
339 """
340 value = self.rule and self.rule or self.regex
341 if not value and self.example:
342 value = self.example
343 if limit: value = value[:limit]
344 return value
345
346
347 - def match(self, evt, device):
348 """
349 Match an event message against our regex.
350
351 @parameter evt: event to match in our mapping
352 @type evt: dictionary
353 @parameter device: device
354 @type device: DMD object
355 @return: boolean
356 @rtype: boolean
357 """
358 value = False
359 log.debug("match on:%s", self.getPrimaryDmdId())
360 if self.rule:
361 try:
362 log.debug("eval rule:%s", self.rule)
363 value = eval(self.rule, {'evt':evt, 'dev':device, 'device': device})
364 except Exception, e:
365 logging.warn("EventClassInst: %s rule failure: %s",
366 self.getDmdKey(), e)
367 else:
368 try:
369 log.debug("regex='%s' message='%s'", self.regex, evt.message)
370 value = re.search(self.regex, evt.message, re.I)
371 except sre_constants.error: pass
372 return value
373
374
376 """Test our regex using the example event string.
377 """
378 if self.example:
379 try:
380 value = re.search(self.regex, self.example, re.I)
381 if not value: return "color:#FF0000;"
382 except sre_constants.error:
383 return "color:#FF0000;"
384
385
387 """Test our rule by compiling it.
388 """
389 try:
390 if self.rule:
391 compile(self.rule, "<string>", "eval")
392 except:
393 return "color:#FF0000;"
394
395
397 """Return a list of all mappings with the same eventClassKey.
398 """
399 return [ i for i in self.eventClass().find(self.eventClassKey) \
400 if i.eventClassKey == self.eventClassKey ]
401
402
403 security.declareProtected('Manage DMD', 'manage_resequence')
415
416
417 security.declareProtected('Manage DMD', 'manage_editEventClassInst')
418 - def manage_editEventClassInst(self, name="", eventClassKey='',
419 regex='', rule='', example='',
420 transform='',
421 explanation='', resolution='', REQUEST=None):
441
442
443 InitializeClass(EventClassInst)
444