1
2
3
4
5
6
7
8
9
10
11
12
13 from itertools import imap
14 from Products.ZenUtils.Time import LocalDateTimeFromMilli
15 from Products.ZenEvents.events2.fields import EventField, EventSummaryField, ZepRawEventField
16 from zenoss.protocols.protobufs.model_pb2 import DEVICE, COMPONENT
17 from zenoss.protocols.protobufs.zep_pb2 import (
18 STATUS_NEW,
19 STATUS_ACKNOWLEDGED,
20 STATUS_SUPPRESSED,
21 STATUS_CLOSED,
22 STATUS_CLEARED,
23 STATUS_DROPPED,
24 STATUS_AGED,
25 SEVERITY_CLEAR,
26 EventTag,
27 EventDetail
28 )
29 from zenoss.protocols.jsonformat import to_dict
30
31 import logging
32 log = logging.getLogger('zen.%s' % __name__)
35 """
36 A proxy for a tag UUID dictionary. Maps org.zenoss.protocols.zep.EventTag
37 to a dictionary.
38 """
39 - def __init__(self, eventProtobufWithTags):
40 self._eventProtobuf = eventProtobufWithTags
41 self._tags = {}
42 self._load()
43
45 for tag in self._eventProtobuf.tags:
46 tag_uuids = self._tags.get(tag.type)
47 if not tag_uuids:
48 self._tags[tag.type] = tag_uuids = set()
49 for tagUuid in tag.uuid:
50 tag_uuids.add(tagUuid)
51
52 - def add(self, type, uuid):
53 tag_uuids = self._tags.get(type)
54 if not tag_uuids:
55 self._tags[type] = tag_uuids = set()
56
57 if not uuid in tag_uuids:
58 tag_uuids.add(uuid)
59
60 event_tag = None
61 for tag in self._eventProtobuf.tags:
62 if tag.type == type:
63 event_tag = tag
64 break
65 else:
66 event_tag = self._eventProtobuf.tags.add()
67 event_tag.type = type
68
69 event_tag.uuid.append(uuid)
70
71 - def addAll(self, type, uuids):
74
77
79
80
81
82 if hasattr(removetype, 'next'):
83 removetype = list(removetype)
84
85
86 if not hasattr(removetype, '__iter__'):
87 removetype = [removetype]
88
89
90 for typ in removetype:
91 if typ in self._tags:
92 del self._tags[typ]
93
94
95
96
97
98
99 saveTags = []
100 for tag in self._eventProtobuf.tags:
101 if tag.type not in removetype:
102 cloned = EventTag()
103 cloned.MergeFrom(tag)
104 saveTags.append(cloned)
105
106 del self._eventProtobuf.tags[:]
107 self._eventProtobuf.tags.extend(saveTags)
108
111 """
112 A proxy for a details dictionary. Maps org.zenoss.protocols.zep.EventDetail
113 to a dictionary.
114 """
116 self.__dict__['_eventProtobuf'] = eventProtobuf
117 self.__dict__['_map'] = {}
118
119 for detail in self._eventProtobuf.details:
120 self._map[detail.name] = detail
121
123 try:
124 return self[name]
125 except KeyError:
126 raise AttributeError(name)
127
130
132 if key in self._map:
133 item = self._map.pop(key)
134
135
136 savedetails = []
137 for det in self._eventProtobuf.details:
138 if det.name != item.name:
139 cloned = EventDetail()
140 cloned.MergeFrom(det)
141 savedetails.append(cloned)
142 self._map[cloned.name] = cloned
143 del self._eventProtobuf.details[:]
144 self._eventProtobuf.details.extend(savedetails)
145
147 item = self._map[key]
148
149
150 if len(item.value) == 0:
151 return None
152 if len(item.value) == 1:
153 return item.value[0]
154 else:
155 raise Exception('Detail %s has more than one value but the old event system expects only one: %s' % (item.name, item.value))
156
173
175 return key in self._map
176
178 return len(self._map)
179
180 - def get(self, key, default=None):
181 try:
182 return self[key]
183 except KeyError:
184 return default
185
186 - def set(self, key, value):
188
189 - def getAll(self, key, default=None):
190 """
191 The normal __getitem__ and get() methods throw an exception for multi-valued details. This one specifically
192 allows multi-valued details.
193 """
194 try:
195 return self._map[key].value
196 except KeyError:
197 return default
198
200 """
201 Conveinence wrapper for protobufs to make sure fields
202 are actually set.
203 """
205 self.__dict__['_pb'] = pb
206
207 - def get(self, key, default=None):
212
213 - def set(self, key, value):
214 setattr(self.__dict__['_pb'], key, value)
215
217 return getattr(self._pb, name)
218
221
223 self._pb.ClearField(name)
224
227
229 """
230 Wraps an org.zenoss.protobufs.zep.Event
231 and makes it look like an old style Event.
232 """
233
234 DEVICE_PRIORITY_DETAIL_KEY = "zenoss.device.priority"
235 PRODUCTION_STATE_DETAIL_KEY = "zenoss.device.production_state"
236 DEVICE_IP_ADDRESS_DETAIL_KEY = 'zenoss.device.ip_address'
237 DEVICE_SYSTEMS_DETAIL_KEY = 'zenoss.device.systems'
238 DEVICE_GROUPS_DETAIL_KEY = 'zenoss.device.groups'
239 DEVICE_LOCATION_DETAIL_KEY = 'zenoss.device.location'
240 DEVICE_CLASS_DETAIL_KEY = 'zenoss.device.device_class'
241
243 self.__dict__['_event'] = ProtobufWrapper(eventProtobuf)
244 self.__dict__['_clearClasses'] = set()
245 self.__dict__['_readOnly'] = {}
246 self.__dict__['details'] = EventDetailProxy(self._event)
247 self.__dict__['_tags'] = EventTagProxy(self._event)
248
252
253 @property
258 @property
261
262 @agent.setter
265
266 @property
269
270 @severity.setter
273
274 @property
276 return self._event.actor.element_identifier
277
278 @device.setter
280 self._event.actor.element_identifier = val
281 self._event.actor.element_type_id = DEVICE
282 self._event.actor.ClearField(EventField.Actor.ELEMENT_UUID)
283
284 @property
286 return self._event.actor.element_sub_identifier
287
288 @component.setter
290 self._event.actor.element_sub_identifier = val
291 self._event.actor.element_sub_type_id = COMPONENT
292 self._event.actor.ClearField(EventField.Actor.ELEMENT_SUB_UUID)
293
294 @property
296 eventClassValue = self._event.get(EventField.EVENT_CLASS)
297 if isinstance( eventClassValue, unicode ):
298 eventClassValue = str( eventClassValue )
299 return eventClassValue
300
301 @eventClass.setter
304
305 @property
310
311 @prodState.setter
314
315 @property
318
319 @summary.setter
322
323 @property
326
327 @message.setter
330
331 @property
334
335 @facility.setter
338
339 @property
342
343 @eventClassKey.setter
346
347 @property
350
351 @dedupid.setter
354
355 @property
358
359 @monitor.setter
362
363 @property
366
367 @ntevid.setter
370
371 @property
376
377 @DevicePriority.setter
380
381 @property
384
385 @priority.setter
388
389 @property
392
393 @property
396
397 @eventKey.setter
400
401 @property
404
405 @eventGroup.setter
408
409 @property
412
413 @ipAddress.setter
416
417 @property
420
421 @DeviceClass.setter
424
425 @property
428
429 @eventState.setter
432
433 @property
436
437 @property
440
441 @property
446
447 @property
452
454 """
455 Adds a read only attribute for transforms to read.
456 These properties are not sent with the event to the queue.
457 """
458 self._readOnly[name] = value
459
461 """
462 Clears a read only attribute so it can be updated.
463 """
464 self._readOnly.pop(name, None)
465
466
468 try:
469 if name in self._readOnly:
470 return self._readOnly[name]
471
472 try:
473 return self.__dict__['details'][name]
474 except KeyError:
475 raise AttributeError(name)
476 except:
477 log.debug('Could not get key %s', name)
478 raise
479
485
487 """
488 Wraps an org.zenoss.protobufs.zep.EventSummary
489
490 and makes it look like an old style Event.
491 """
492 - def __init__(self, eventSummaryProtobuf):
493 self.__dict__['_eventSummary'] = ProtobufWrapper(eventSummaryProtobuf)
494 if not self._eventSummary.occurrence:
495 self._eventSummary.occurrence.add()
496
497 event = self._eventSummary.occurrence[0]
498 EventProxy.__init__(self, event)
499
500 @property
503
504 @property
509
510 @property
513
514 @clearid.setter
517
518 @property
523
524 @property
529
530 @property
533
534 @property
537
538 @ownerid.setter
541
542 @property
545
546 @eventState.setter
549
551 """
552 Wraps an org.zenoss.protobufs.zep.ZepRawEvent and makes it look like
553 an old style Event. It is the proper event proxy to use for transforms
554 since transforms use _action and _clearClasses.
555 """
556 ACTION_HISTORY = 'history'
557 ACTION_DROP = 'drop'
558 ACTION_STATUS = 'status'
559 ACTION_HEARTBEAT = 'heartbeat'
560 ACTION_LOG = 'log'
561 ACTION_ALERT_STATE = 'alert_state'
562 ACTION_DETAIL = 'detail'
563
564 ACTION_STATUS_MAP = {
565 ACTION_HISTORY : STATUS_CLOSED,
566 ACTION_STATUS : STATUS_NEW,
567 ACTION_DROP : STATUS_DROPPED,
568 None : STATUS_NEW,
569 }
570
571 STATUS_ACTION_MAP = {
572 STATUS_NEW : ACTION_STATUS,
573 STATUS_ACKNOWLEDGED : ACTION_STATUS,
574 STATUS_SUPPRESSED : ACTION_STATUS,
575 STATUS_CLOSED : ACTION_HISTORY,
576 STATUS_CLEARED : ACTION_HISTORY,
577 STATUS_DROPPED : ACTION_DROP,
578 STATUS_AGED : ACTION_HISTORY,
579 None : ACTION_STATUS,
580 }
581
592
594 return "{_zepRawEvent:%s}" % str(to_dict(self._zepRawEvent))
595
597
598 if self._event.severity == SEVERITY_CLEAR and self._event.get(EventField.EVENT_CLASS):
599 self._clearClassesSet.add(self._event.event_class)
600
601 del self._zepRawEvent.clear_event_class
602 for eventClass in self._clearClassesSet:
603 self._zepRawEvent.clear_event_class.append(eventClass)
604
605 @property
607 return list(self._clearClassesSet)
608
609 @_clearClasses.setter
614
615 @property
618
619 @_action.setter
624
625 @property
627 return self.details.get('eventClassMapping', '')
628
629 @eventClassMapping.setter
631
632
633 self.details['eventClassMapping'] = val
634
635
636
637 for typ in (EventProxy, EventSummaryProxy):
638 typ.FIELDS = [name for name in dir(typ) if isinstance(getattr(typ,name), property)]
639