1
2
3
4
5
6
7
8
9
10
11 """
12 Operations for Events.
13
14 Available at: /zport/dmd/evconsole_router
15 """
16
17 import time
18 import logging
19 from json import loads
20 from AccessControl import getSecurityManager
21 from zenoss.protocols.exceptions import NoConsumersException, PublishException
22 from zenoss.protocols.protobufs.zep_pb2 import STATUS_NEW, STATUS_ACKNOWLEDGED
23 from Products import Zuul
24 from Products.ZenUtils.Ext import DirectRouter
25 from Products.ZenUtils.extdirect.router import DirectResponse
26 from Products.ZenUtils.Time import isoToTimestamp
27 from Products.Zuul.decorators import require, serviceConnectionError
28 from Products.ZenUtils.guid.interfaces import IGlobalIdentifier, IGUIDManager
29 from Products.ZenEvents.EventClass import EventClass
30 from Products.ZenMessaging.audit import audit
31 from Products.ZenUtils.deprecated import deprecated
32 from Products.Zuul.utils import resolve_context
33 from Products.Zuul.utils import ZuulMessageFactory as _t
34 from Products.ZenUI3.browser.eventconsole.grid import column_config
35 from Products.Zuul.interfaces import ICatalogTool
36 from Products.Zuul.infos.event import EventCompatInfo, EventCompatDetailInfo
37
38
39 log = logging.getLogger('zen.%s' % __name__)
43 """
44 A JSON/ExtDirect interface to operations on events in ZEP
45 """
46
48 super(EventsRouter, self).__init__(context, request)
49 self.zep = Zuul.getFacade('zep', context)
50 self.catalog = ICatalogTool(context)
51 self.manager = IGUIDManager(context.dmd)
52
54 """
55 To view any events you either have to have administered roles or
56 be a global roled user
57 """
58 user = self.context.dmd.ZenUsers.getUserSettings()
59 if not user.hasNoGlobalRoles():
60 return True
61
62 return len(user.getAllAdminRoles()) > 0
63
65 try:
66 values = []
67 for t in value.split('/'):
68 values.append(int(isoToTimestamp(t)) * 1000)
69 return values
70 except ValueError:
71 log.warning("Invalid timestamp: %s", value)
72 return ()
73
75 """
76 When querying archived events we need to make sure that
77 we do not link to devices and components that are no longer valid
78 """
79 manager = self.manager
80 for event_summary in events:
81 occurrence = event_summary['occurrence'][0]
82 actor = occurrence['actor']
83
84 if actor.get('element_uuid') and \
85 actor.get('element_uuid') not in manager.table:
86 del actor['element_uuid']
87
88
89 if actor.get('element_sub_uuid') and \
90 actor.get('element_sub_uuid') not in manager.table:
91 del actor['element_sub_uuid']
92 yield event_summary
93
94 @serviceConnectionError
95 @require('ZenCommon')
96 - def queryArchive(self, page=None, limit=0, start=0, sort='lastTime', dir='desc', params=None, exclusion_filter=None, keys=None, uid=None, detailFormat=False):
97 if not self._canViewEvents():
98 return DirectResponse.succeed(
99 events = [],
100 totalCount = 0,
101 asof = time.time()
102 )
103
104 filter = self._buildFilter(uid, params)
105 if exclusion_filter is not None:
106 exclusion_filter = self._buildFilter(uid, exclusion_filter)
107 events = self.zep.getEventSummariesFromArchive(limit=limit, offset=start, sort=self._buildSort(sort,dir),
108 filter=filter, exclusion_filter=exclusion_filter)
109 eventFormat = EventCompatInfo
110 if detailFormat:
111 eventFormat = EventCompatDetailInfo
112
113 dmd = self.context.dmd
114
115 evdata = self._filterInvalidUuids(events['events'])
116 eventObs = [eventFormat(dmd, e) for e in evdata]
117 return DirectResponse.succeed(
118 events = Zuul.marshal(eventObs, list(set(keys))),
119 totalCount = events['total'],
120 asof = time.time()
121 )
122
123 @serviceConnectionError
124 @require('ZenCommon')
125 - def query(self, limit=0, start=0, sort='lastTime', dir='desc', params=None, exclusion_filter=None, keys=None,
126 page=None, archive=False, uid=None, detailFormat=False):
127 """
128 Query for events.
129
130 @type limit: integer
131 @param limit: (optional) Max index of events to retrieve (default: 0)
132 @type start: integer
133 @param start: (optional) Min index of events to retrieve (default: 0)
134 @type sort: string
135 @param sort: (optional) Key on which to sort the return results (default:
136 'lastTime')
137 @type dir: string
138 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC'
139 (default: 'DESC')
140 @type params: dictionary
141 @param params: (optional) Key-value pair of filters for this search.
142 (default: None)
143 @type history: boolean
144 @param history: (optional) True to search the event history table instead
145 of active events (default: False)
146 @type uid: string
147 @param uid: (optional) Context for the query (default: None)
148 @rtype: dictionary
149 @return: B{Properties}:
150 - events: ([dictionary]) List of objects representing events
151 - totalCount: (integer) Total count of events returned
152 - asof: (float) Current time
153 """
154 if not self._canViewEvents():
155 return DirectResponse.succeed(
156 events = [],
157 totalCount = 0,
158 asof = time.time()
159 )
160
161 if archive:
162 return self.queryArchive(limit=limit, start=start, sort=sort,
163 dir=dir, params=params, exclusion_filter=exclusion_filter, keys=keys, uid=uid,
164 detailFormat=detailFormat)
165
166
167 if uid == "/zport/dmd/Devices":
168 uid = "/zport/dmd"
169 filter = self._buildFilter(uid, params)
170 if exclusion_filter is not None:
171 exclusion_filter = self._buildFilter(uid, exclusion_filter)
172 events = self.zep.getEventSummaries(limit=limit, offset=start, sort=self._buildSort(sort,dir), filter=filter, exclusion_filter=exclusion_filter)
173 eventFormat = EventCompatInfo
174 if detailFormat:
175 eventFormat = EventCompatDetailInfo
176
177 dmd = self.context.dmd
178 eventObs = [eventFormat(dmd, e) for e in events['events']]
179
180 return DirectResponse.succeed(
181 events = Zuul.marshal(eventObs, list(set(keys))),
182 totalCount = events['total'],
183 asof = time.time()
184 )
185
186
187 @serviceConnectionError
188 @require('ZenCommon')
189 - def queryGenerator(self, sort='lastTime', dir='desc', evids=None, excludeIds=None, params=None,
190 archive=False, uid=None, detailFormat=False):
191 """
192 Query for events.
193
194 @type sort: string
195 @param sort: (optional) Key on which to sort the return results (default:
196 'lastTime')
197 @type dir: string
198 @param dir: (optional) Sort order; can be either 'ASC' or 'DESC'
199 (default: 'DESC')
200 @type params: dictionary
201 @param params: (optional) Key-value pair of filters for this search.
202 (default: None)
203 @type archive: boolean
204 @param archive: (optional) True to search the event archive instead
205 of active events (default: False)
206 @type uid: string
207 @param uid: (optional) Context for the query (default: None)
208 @rtype: generator
209 @return: Generator returning events.
210 """
211 if not self._canViewEvents():
212 return
213 includeFilter, excludeFilter = self._buildRequestFilters(uid, params, evids, excludeIds)
214
215 events = self.zep.getEventSummariesGenerator(filter=includeFilter, exclude=excludeFilter,
216 sort=self._buildSort(sort,dir), archive=archive)
217 eventFormat = EventCompatInfo
218 if detailFormat:
219 eventFormat = EventCompatDetailInfo
220 for event in events:
221 yield Zuul.marshal(eventFormat(self.context.dmd, event))
222
223 - def _buildSort(self, sort='lastTime', dir='desc'):
224 sort_list = [(sort,dir)]
225
226 if sort not in ('lastTime','evid'):
227 sort_list.append(('lastTime','desc'))
228 return sort_list
229
230
231 - def _buildFilter(self, uid, params, specificEventUuids=None):
232 """
233 Construct a dictionary that can be converted into an EventFilter protobuf.
234
235 @type params: dictionary
236 @param params: (optional) Key-value pair of filters for this search.
237 (default: None)
238 @type uid: string
239 @param uid: (optional) Context for the query (default: None)
240 """
241 if params:
242 log.debug('logging params for building filter: %s', params)
243 if isinstance(params, basestring):
244 params = loads(params)
245
246
247
248
249
250 params, details = self.zep.parseParameterDetails(params)
251
252 filterEventUuids = []
253
254
255 if specificEventUuids is None:
256 log.debug('No specific event uuids were passed in.')
257
258
259
260
261 evid = params.get('evid')
262 if evid:
263 if not isinstance(evid,(list, tuple)):
264 evid = [evid]
265 filterEventUuids.extend(evid)
266
267
268 else:
269 log.debug('Specific event uuids passed in: %s', specificEventUuids)
270 if not isinstance(specificEventUuids,(list, tuple)):
271 filterEventUuids = [specificEventUuids]
272 else:
273 filterEventUuids = specificEventUuids
274
275 log.debug('FilterEventUuids is: %s', filterEventUuids)
276
277 event_filter = self.zep.createEventFilter(
278 severity = params.get('severity'),
279 status = [i for i in params.get('eventState', [])],
280 event_class = filter(None, [params.get('eventClass')]),
281 first_seen = params.get('firstTime') and self._timeRange(params.get('firstTime')),
282 last_seen = params.get('lastTime') and self._timeRange(params.get('lastTime')),
283 status_change = params.get('stateChange') and self._timeRange(params.get('stateChange')),
284 uuid = filterEventUuids,
285 count_range = params.get('count'),
286 element_title = params.get('device'),
287 element_sub_title = params.get('component'),
288 event_summary = params.get('summary'),
289 current_user_name = params.get('ownerid'),
290 agent = params.get('agent'),
291 monitor = params.get('monitor'),
292 fingerprint = params.get('dedupid'),
293
294
295
296 tags = params.get('tags'),
297
298 details = details,
299 event_key = params.get('eventKey'),
300 event_class_key = params.get('eventClassKey'),
301 event_group = params.get('eventGroup'),
302 message = params.get('message'),
303 )
304 log.debug('Found params for building filter, ended up building the following:')
305 log.debug(event_filter)
306 elif specificEventUuids:
307
308 event_filter = self.zep.createEventFilter(
309 uuid = specificEventUuids
310 )
311 else:
312 log.debug('Did not get parameters, using empty filter.')
313 event_filter = {}
314
315 if uid is None and isinstance(self.context, EventClass):
316 uid = self.context
317
318 context = resolve_context(uid)
319
320 if context and context.id not in ('Events', 'dmd'):
321 try:
322
323 context_tag_filter = {
324 'tag_uuids': [IGlobalIdentifier(context).getGUID()]
325 }
326
327
328 tag_filter = event_filter.setdefault('tag_filter', [])
329 tag_filter.append(context_tag_filter)
330 except TypeError:
331 if isinstance(context, EventClass):
332 event_filter['event_class'] = [context.getDmdKey()]
333 else:
334 raise Exception('Unknown context %s' % context)
335
336 log.debug('Final filter will be:')
337 log.debug(event_filter)
338
339 return event_filter
340
342 """
343 Get event details.
344
345 @type evid: string
346 @param evid: Event ID to get details
347 @type history: boolean
348 @param history: Deprecated
349 @rtype: DirectResponse
350 @return: B{Properties}:
351 - event: ([dictionary]) List containing a dictionary representing
352 event details
353 """
354 event_summary = self.zep.getEventSummary(evid)
355 if event_summary:
356 eventData = Zuul.marshal(EventCompatDetailInfo(self.context.dmd, event_summary))
357 return DirectResponse.succeed(event=[eventData])
358 else:
359 raise Exception('Could not find event %s' % evid)
360
361 @require('Manage Events')
362 - def write_log(self, evid=None, message=None):
363 """
364 Write a message to an event's log.
365
366 @type evid: string
367 @param evid: Event ID to log to
368 @type message: string
369 @param message: Message to log
370 @rtype: DirectResponse
371 @return: Success message
372 """
373
374 userName = getSecurityManager().getUser().getId()
375
376 self.zep.addNote(uuid=evid, message=message, userName=userName)
377
378 return DirectResponse.succeed()
379
380 @require('Manage Events')
381 - def postNote(self, uuid, note):
382 self.zep.postNote(uuid, note)
383 return DirectResponse.succeed()
384
386 """
387 Given common request parameters, build the inclusive and exclusive
388 filters for event update requests.
389 """
390
391 if uid is None and isinstance(self.context, EventClass):
392 uid = self.context
393
394 log.debug('Context while building request filters is: %s', uid)
395
396
397
398
399
400 includeUuids = None
401 if isinstance(evids, (list, tuple)):
402 log.debug('Found specific event ids, adding to params.')
403 includeUuids = evids
404
405 includeFilter = self._buildFilter(uid, params, specificEventUuids=includeUuids)
406
407
408
409 excludeFilter = None
410 if excludeIds:
411 excludeFilter = self._buildFilter(uid, params, specificEventUuids=excludeIds.keys())
412
413 log.debug('The exclude filter:' + str(excludeFilter))
414 log.debug('Finished building request filters.')
415
416 return includeFilter, excludeFilter
417
418 @require('Manage Events')
420 """
421 When performing updates from the event console, updates are performed in batches
422 to allow the user to see the progress of event changes and cancel out of updates
423 while they are in progress. This works by specifying a limit to one of the close,
424 acknowledge, or reopen calls in this router. The response will contain an
425 EventSummaryUpdateResponse, and if there are additional updates to be performed,
426 it will contain a next_request field with all of the parameters used to update
427 the next range of events.
428
429 @type next_request: dictionary
430 @param next_request: The next_request field from the previous updates.
431 """
432 log.debug('Starting next batch of updates')
433 status, summaryUpdateResponse = self.zep.nextEventSummaryUpdate(next_request)
434
435 log.debug('Completed updates: %s', summaryUpdateResponse)
436 return DirectResponse.succeed(data=summaryUpdateResponse)
437
438 @require('Manage Events')
440 """
441 @type params: dictionary
442 @param params: Key-value pair of filters for this search.
443 """
444 if isinstance(params, basestring):
445 params = loads(params)
446
447 device = params['device']
448
449 log.debug('Clearing heartbeats for device: {device}'.format(device=device))
450
451 params['eventState'] = [STATUS_NEW, STATUS_ACKNOWLEDGED]
452 params['eventClass'] = '/Status/Heartbeat'
453
454 includeFilter, excludeFilter = self._buildRequestFilters(None, params, None, None)
455
456 status, summaryUpdateResponse = self.zep.closeEventSummaries(
457 eventFilter=includeFilter,
458 exclusionFilter=excludeFilter,
459 limit=limit,
460 )
461
462 log.debug('Done clearing heartbeats for device: {device}'.format(device=device))
463 log.debug(summaryUpdateResponse)
464 audit('UI.Device.ClearHeartbeats', device=device)
465
466 return DirectResponse.succeed(data=summaryUpdateResponse)
467
468 @require('Manage Events')
469 - def close(self, evids=None, excludeIds=None, params=None, uid=None, asof=None, limit=None):
470 """
471 Close event(s).
472
473 @type evids: [string]
474 @param evids: (optional) List of event IDs to close (default: None)
475 @type excludeIds: [string]
476 @param excludeIds: (optional) List of event IDs to exclude from
477 close (default: None)
478 @type params: dictionary
479 @param params: (optional) Key-value pair of filters for this search.
480 (default: None)
481 @type uid: string
482 @param uid: (optional) Context for the query (default: None)
483 @type asof: float
484 @param asof: (optional) Only close if there has been no state
485 change since this time (default: None)
486 @type limit: The maximum number of events to update in this batch.
487 @param limit: (optional) Maximum number of events to update (default: None).
488 @rtype: DirectResponse
489 @return: Success message
490 """
491
492 log.debug('Issuing a close request.')
493
494 includeFilter, excludeFilter = self._buildRequestFilters(uid, params, evids, excludeIds)
495
496 status, summaryUpdateResponse = self.zep.closeEventSummaries(
497 eventFilter=includeFilter,
498 exclusionFilter=excludeFilter,
499 limit=limit,
500 )
501
502 log.debug('Done issuing close request.')
503 log.debug(summaryUpdateResponse)
504
505 return DirectResponse.succeed(data=summaryUpdateResponse)
506
507 @require('Manage Events')
508 - def acknowledge(self, evids=None, excludeIds=None, params=None, uid=None, asof=None, limit=None):
509 """
510 Acknowledge event(s).
511
512 @type evids: [string]
513 @param evids: (optional) List of event IDs to acknowledge (default: None)
514 @type excludeIds: [string]
515 @param excludeIds: (optional) List of event IDs to exclude from
516 acknowledgment (default: None)
517 @type params: dictionary
518 @param params: (optional) Key-value pair of filters for this search.
519 (default: None)
520 @type uid: string
521 @param uid: (optional) Context for the query (default: None)
522 @type asof: float
523 @param asof: (optional) Only acknowledge if there has been no state
524 change since this time (default: None)
525 @type limit: The maximum number of events to update in this batch.
526 @param limit: (optional) Maximum number of events to update (default: None).
527 @rtype: DirectResponse
528 @return: Success message
529 """
530 log.debug('Issuing an acknowledge request.')
531
532 includeFilter, excludeFilter = self._buildRequestFilters(uid, params, evids, excludeIds)
533
534 status, summaryUpdateResponse = self.zep.acknowledgeEventSummaries(
535 eventFilter=includeFilter,
536 exclusionFilter=excludeFilter,
537 limit=limit,
538 )
539
540 log.debug('Done issuing acknowledge request.')
541 log.debug(summaryUpdateResponse)
542
543 return DirectResponse.succeed(data=summaryUpdateResponse)
544
545 @require('Manage Events')
546 @deprecated
548 """
549 Deprecated, Use reopen
550 """
551 return self.reopen(*args, **kwargs)
552
553 @require('Manage Events')
554 - def reopen(self, evids=None, excludeIds=None, params=None, uid=None, asof=None, limit=None):
555 """
556 Reopen event(s).
557
558 @type evids: [string]
559 @param evids: (optional) List of event IDs to reopen (default: None)
560 @type excludeIds: [string]
561 @param excludeIds: (optional) List of event IDs to exclude from
562 reopen (default: None)
563 @type params: dictionary
564 @param params: (optional) Key-value pair of filters for this search.
565 (default: None)
566 @type uid: string
567 @param uid: (optional) Context for the query (default: None)
568 @type asof: float
569 @param asof: (optional) Only reopen if there has been no state
570 change since this time (default: None)
571 @type limit: The maximum number of events to update in this batch.
572 @param limit: (optional) Maximum number of events to update (Default: None).
573 @rtype: DirectResponse
574 @return: Success message
575 """
576
577 log.debug('Issuing a reopen request.')
578
579 includeFilter, excludeFilter = self._buildRequestFilters(uid, params, evids, excludeIds)
580
581 status, summaryUpdateResponse = self.zep.reopenEventSummaries(
582 eventFilter=includeFilter,
583 exclusionFilter=excludeFilter,
584 limit=limit,
585 )
586
587 log.debug('Done issuing reopen request.')
588 log.debug(summaryUpdateResponse)
589
590 return DirectResponse.succeed(data=summaryUpdateResponse)
591
592
593 @require("Manage Events")
595 status, response = self.zep.updateEventSummaries(update, event_filter, exclusion_filter, limit)
596 return DirectResponse.succeed(data=response)
597
598
599 @require('Manage Events')
600 - def add_event(self, summary, device, component, severity, evclasskey, evclass=None):
601 """
602 Create a new event.
603
604 @type summary: string
605 @param summary: New event's summary
606 @type device: string
607 @param device: Device uid to use for new event
608 @type component: string
609 @param component: Component uid to use for new event
610 @type severity: string
611 @param severity: Severity of new event. Can be one of the following:
612 Critical, Error, Warning, Info, Debug, or Clear
613 @type evclasskey: string
614 @param evclasskey: The Event Class Key to assign to this event
615 @type evclass: string
616 @param evclass: Event class for the new event
617 @rtype: DirectResponse
618 """
619 try:
620 self.zep.create(summary, severity, device, component, eventClassKey=evclasskey,
621 eventClass=evclass, immediate=True)
622 return DirectResponse.succeed("Created event")
623 except NoConsumersException:
624
625
626 msg = 'Queued event. Check zeneventd status on <a href="/zport/About/zenossInfo">Daemons</a>'
627 return DirectResponse.succeed(msg, sticky=True)
628 except PublishException, e:
629
630 log.exception("Failed creating event")
631 return DirectResponse.exception(e, "Failed to create event")
632
633 @property
635 configSchema =[{
636 'id': 'event_age_disable_severity',
637 'name': _t("Don't Age This Severity and Above"),
638 'xtype': 'eventageseverity',
639 },{
640 'id': 'event_age_severity_inclusive',
641 'xtype': 'hidden',
642 },{
643 'id': 'event_age_interval_minutes',
644 'name': _t('Event Aging Threshold (minutes)'),
645 'xtype': 'numberfield',
646 'minValue': 0,
647 'allowNegative': False,
648 },{
649 'id': 'aging_interval_milliseconds',
650 'name': _t('Event Aging Interval (milliseconds)'),
651 'xtype': 'numberfield',
652 'minValue': 1,
653 'allowNegative': False
654 },{
655 'id': 'aging_limit',
656 'name': _t('Event Aging Limit'),
657 'xtype': 'numberfield',
658 'minValue': 1,
659 'allowNegative': False
660 },{
661 'id': 'event_archive_interval_minutes',
662 'name': _t('Event Archive Threshold (minutes)'),
663 'xtype': 'numberfield',
664 'minValue': 1,
665 'maxValue': 43200,
666 'allowNegative': False,
667 },{
668 'id': 'archive_interval_milliseconds',
669 'name': _t('Event Archive Interval (milliseconds)'),
670 'xtype': 'numberfield',
671 'minValue': 1,
672 'allowNegative': False,
673 },{
674 'id': 'archive_limit',
675 'name': _t('Event Archive Limit'),
676 'xtype': 'numberfield',
677 'minValue': 1,
678 'allowNegative': False,
679 },{
680 'id': 'event_archive_purge_interval_days',
681 'minValue': 1,
682 'name': _t('Delete Archived Events Older Than (days)'),
683 'xtype': 'numberfield',
684 'allowNegative': False,
685 },{
686 'id': 'default_syslog_priority',
687 'name': _t('Default Syslog Priority'),
688 'xtype': 'numberfield',
689 'allowNegative': False,
690 'value': self.context.dmd.ZenEventManager.defaultPriority
691 },{
692 'id': 'default_availability_days',
693 'name': _t('Default Availability Report (days)'),
694 'xtype': 'numberfield',
695 'allowNegative': False,
696 'minValue': 1,
697 'value': self.context.dmd.ZenEventManager.defaultAvailabilityDays
698 },{
699 'id': 'event_max_size_bytes',
700 'name': _t('Max Event Size In Bytes'),
701 'xtype': 'numberfield',
702 'allowNegative': False,
703 'minValue': 8192,
704 'maxValue': 102400,
705 },{
706 'id': 'index_summary_interval_milliseconds',
707 'name': _t('Summary Index Interval (milliseconds)'),
708 'xtype': 'numberfield',
709 'allowNegative': False,
710 'minValue': 1
711 },{
712 'id': 'index_archive_interval_milliseconds',
713 'name': _t('Archive Index Interval (milliseconds)'),
714 'xtype': 'numberfield',
715 'allowNegative': False,
716 'minValue': 1
717 },{
718 'id': 'index_limit',
719 'name': _t('Index Limit'),
720 'xtype': 'numberfield',
721 'allowNegative': False,
722 'minValue': 1
723 },{
724 'id': 'event_time_purge_interval_days',
725 'name': _t('Event Time Purge Interval (days)'),
726 'xtype': 'numberfield',
727 'allowNegative': False,
728 'minValue': 1
729 }]
730 return configSchema
731
733 """
734 Copy the values and defaults from ZEP to our schema
735 """
736 for conf in configSchema:
737 if not data.get(conf['id']):
738 continue
739 prop = data[conf['id']]
740 conf.update(prop)
741 return configSchema
742
743 @require('ZenCommon')
751
752 @require('Manage DMD')
754 """
755 @type values: Dictionary
756 @param values: Key Value pairs of config values
757 """
758
759 empty_keys = [k for k,v in values.iteritems() if isinstance(v, basestring) and not len(v)]
760 for empty_key in empty_keys:
761 del values[empty_key]
762
763
764 defaultSyslogPriority = values.pop('default_syslog_priority', None)
765 if defaultSyslogPriority is not None:
766 self.context.dmd.ZenEventManager.defaultPriority = int(defaultSyslogPriority)
767
768 defaultAvailabilityDays = values.pop('default_availability_days', None)
769 if defaultAvailabilityDays is not None:
770 self.context.dmd.ZenEventManager.defaultAvailabilityDays = int(defaultAvailabilityDays)
771
772 self.zep.setConfigValues(values)
773 return DirectResponse.succeed()
774
776 """
777 Get the current event console field column configuration.
778
779 @type uid: string
780 @param uid: (optional) UID context to use (default: None)
781 @type archive: boolean
782 @param archive: (optional) True to use the event archive instead
783 of active events (default: False)
784 @rtype: [dictionary]
785 @return: A list of objects representing field columns
786 """
787 return column_config(self.request, archive)
788
789 @require('Manage Events')
791 """
792 Associate event(s) with an event class.
793
794 @type evrows: [dictionary]
795 @param evrows: List of event rows to classify
796 @type evclass: string
797 @param evclass: Event class to associate events to
798 @rtype: DirectResponse
799 @return: B{Properties}:
800 - msg: (string) Success/failure message
801 - success: (boolean) True if class update successful
802 """
803 msg, url = self.zep.createEventMapping(evrows, evclass)
804 if url:
805 msg += "<br/><a href='%s'>Go to the new mapping.</a>" % url
806 return DirectResponse(msg, success=bool(url))
807
808 @require('Manage Events')
810 """
811 Clear all heartbeat events
812
813 @rtype: DirectResponse
814 @return: B{Properties}:
815 - success: (boolean) True if heartbeats deleted successfully
816 """
817 self.zep.deleteHeartbeats()
818 audit('UI.Event.ClearHeartbeats', self.context)
819 return DirectResponse.succeed()
820