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 Products.ZenModel.ZenossSecurity import *
27
28 from Products.ZenRelations.RelSchema import *
29 from Products.ZenModel.ZenModelRM import ZenModelRM
30 from Products.ZenModel.EventView import EventView
31 from Products.ZenModel.ZenPackable import ZenPackable
32 from Products.ZenWidgets import messaging
33 from Products.ZenUtils.Utils import convToUnits, zdecode
34
35
42
43
44 addEventClassInst = DTMLFile('dtml/addEventClassInst',globals())
45
46
48
49 transform = ''
50
51 _properties = (
52 {'id':'transform', 'type':'text', 'mode':'w'},
53 )
54
56 """Modify event with values taken from dict Inst.
57 Any non-None property values are applied to the event.
58 """
59 evt._clearClasses = copy.copy(getattr(self, "zEventClearClasses", []))
60 evt._action = getattr(self, "zEventAction", "status")
61 sev = getattr(self, "zEventSeverity", -1)
62 if sev >= 0:
63 if evt.severity > 0:
64 evt.severity = sev
65 updates = {}
66 for name in 'resolution', 'explanation':
67 value = getattr(self, name, None)
68 if value is not None and value != '':
69 updates[name] = value
70 evt.updateFromDict(updates)
71 return evt
72
95
96
111
112
121
122
124 """
125 Return the path to our current EventClassInst from the top level
126 EventClass down. We use this to process and display the heirarchy of
127 event transforms.
128 """
129 transpath = []
130 for obj in aq_chain(self):
131
132 if not isinstance(obj, EventClassPropertyMixin): continue
133 if obj.id == 'dmd': break
134 transpath.append(obj)
135 transpath.reverse()
136 return transpath
137
138
139
140 -class EventClassInst(EventClassPropertyMixin, ZenModelRM, EventView,
141 ZenPackable):
142 """
143 EventClassInst.
144 """
145
146 event_key = meta_type = "EventClassInst"
147
148 default_catalog = "eventClassSearch"
149
150 actions = ("status", "history", "heartbeat", "drop")
151
152 _properties = EventClassPropertyMixin._properties + (
153 {'id':'eventClassKey', 'type':'string', 'mode':'w'},
154 {'id':'sequence', 'type':'int', 'mode':'w'},
155 {'id':'rule', 'type':'string', 'mode':'w'},
156 {'id':'regex', 'type':'string', 'mode':'w'},
157 {'id':'example', 'type':'string', 'mode':'w'},
158 {'id':'explanation', 'type':'text', 'mode':'w'},
159 {'id':'resolution', 'type':'text', 'mode':'w'},
160 )
161
162
163 _relations = ZenPackable._relations + (
164 ("eventClass", ToOne(ToManyCont,"Products.ZenEvents.EventClass","instances")),
165 )
166
167
168
169 factory_type_information = (
170 {
171 'id' : 'EventClassInst',
172 'meta_type' : 'EventClassInst',
173 'description' : """Base class for all devices""",
174 'icon' : 'EventClassInst.gif',
175 'product' : 'ZenEvents',
176 'factory' : 'manage_addEventClassInst',
177 'immediate_view' : 'eventClassInstStatus',
178 'actions' :
179 (
180 { 'id' : 'status'
181 , 'name' : 'Status'
182 , 'action' : 'eventClassInstStatus'
183 , 'permissions' : (Permissions.view, )
184 },
185 { 'id' : 'edit'
186 , 'name' : 'Edit'
187 , 'action' : 'eventClassInstEdit'
188 , 'permissions' : ("Manage DMD", )
189 },
190 { 'id' : 'sequence'
191 , 'name' : 'Sequence'
192 , 'action' : 'eventClassInstSequence'
193 , 'permissions' : (Permissions.view,)
194 },
195 { 'id' : 'config'
196 , 'name' : 'zProperties'
197 , 'action' : 'zPropertyEdit'
198 , 'permissions' : ("Manage DMD",)
199 },
200 { 'id' : 'events'
201 , 'name' : 'Events'
202 , 'action' : 'viewEvents'
203 , 'permissions' : (Permissions.view, )
204 },
205
206
207
208
209
210 { 'id' : 'viewHistory'
211 , 'name' : 'Modifications'
212 , 'action' : 'viewHistory'
213 , 'permissions' : (ZEN_VIEW_MODIFICATIONS,)
214 },
215 )
216 },
217 )
218
219 security = ClassSecurityInfo()
220
222 ZenModelRM.__init__(self, id)
223 self.eventClassKey = id
224 self.sequence = None
225 self.rule = ""
226 self.regex = ""
227 self.example = ""
228 self.explanation = ""
229 self.resolution = ""
230
231
238
239
241 """Return the full EventClass of this EventClassInst."""
242 return self.getOrganizerName()
243
248
249
251 """Return the dmd key of this mapping ie: /App/Start/zentinel
252 """
253 return self.getOrganizerName() + "/" + self.id
254
255
257 """
258 Apply the event dict regex to extract additional values from the event.
259 """
260 if self.regex:
261 m = re.search(self.regex, evt.message)
262 if m: evt.updateFromDict(m.groupdict())
263 return evt
264
265
273
275 """Return the rule if it exists else return the regex.
276 limit limits the number of characters returned.
277 """
278 value = self.rule and self.rule or self.regex
279 if not value and self.example:
280 value = self.example
281 if limit: value = value[:limit]
282 return value
283
284
285 - def match(self, evt, device):
286 """
287 Match an event message against our regex.
288
289 @parameter evt: event to match in our mapping
290 @type evt: dictionary
291 @parameter device: device
292 @type device: DMD object
293 @return: boolean
294 @rtype: boolean
295 """
296 value = False
297 log.debug("match on:%s", self.getPrimaryDmdId())
298 if self.rule:
299 try:
300 log.debug("eval rule:%s", self.rule)
301 value = eval(self.rule, {'evt':evt, 'dev':device, 'device': device})
302 except Exception, e:
303 logging.warn("EventClassInst: %s rule failure: %s",
304 self.getDmdKey(), e)
305 else:
306 try:
307 log.debug("regex='%s' message='%s'", self.regex, evt.message)
308 value = re.search(self.regex, evt.message, re.I)
309 except sre_constants.error: pass
310 return value
311
312
314 """Test our regex using the example event string.
315 """
316 if self.example:
317 try:
318 value = re.search(self.regex, self.example, re.I)
319 if not value: return "color:#FF0000;"
320 except sre_constants.error:
321 return "color:#FF0000;"
322
323
325 """Test our rule by compiling it.
326 """
327 try:
328 if self.rule:
329 compile(self.rule, "<string>", "eval")
330 except:
331 return "color:#FF0000;"
332
333
335 """Return a list of all mappings with the same eventClassKey.
336 """
337 return self.eventClass().find(self.eventClassKey)
338
339
346
347
352
353
355 """
356 Device only propagates beforeDelete if we are being deleted or copied.
357 Moving and renaming don't propagate.
358 """
359 ZenModelRM.manage_beforeDelete(self, item, container)
360 self.unindex_object()
361
362
363 security.declareProtected('Manage DMD', 'manage_resequence')
375
376
377 security.declareProtected('Manage DMD', 'manage_editEventClassInst')
378 - def manage_editEventClassInst(self, name="", eventClassKey='',
379 regex='', rule='', example='',
380 transform='',
381 explanation='', resolution='', REQUEST=None):
401
402
403 InitializeClass(EventClassInst)
404