Package Products :: Package Zuul :: Package routers :: Module zep
[hide private]
[frames] | no frames]

Source Code for Module Products.Zuul.routers.zep

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2009, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  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__) 
40 41 42 -class EventsRouter(DirectRouter):
43 """ 44 A JSON/ExtDirect interface to operations on events in ZEP 45 """ 46
47 - def __init__(self, context, request):
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
53 - def _canViewEvents(self):
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 # make sure they have view permission on something 62 return len(user.getAllAdminRoles()) > 0
63
64 - def _timeRange(self, value):
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
74 - def _filterInvalidUuids(self, events):
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 # element 84 if actor.get('element_uuid') and \ 85 actor.get('element_uuid') not in manager.table: 86 del actor['element_uuid'] 87 88 # sub element 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 # filter out the component and device UUIDs that no longer exist in our system 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 # special case for dmd/Devices in which case we want to show all events 166 # by default events are not tagged with the root device classes because it would be on all events 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 # Add secondary sort of last time descending 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 # params comes from the grid's filtering column - 247 # some of these properties are normal properties on an event 248 # while others are considered event details. Separate the 249 # two here. 250 params, details = self.zep.parseParameterDetails(params) 251 252 filterEventUuids = [] 253 # No specific event uuids passed in- 254 # check for event ids from the grid parameters 255 if specificEventUuids is None: 256 log.debug('No specific event uuids were passed in.') 257 258 # The evid's from params only ever mean anything for filtering - if 259 # specific uuids are passed in, this filter will ignore the grid 260 # parameters and just act on or filter using these specific event uuids. 261 evid = params.get('evid') 262 if evid: 263 if not isinstance(evid,(list, tuple)): 264 evid = [evid] 265 filterEventUuids.extend(evid) 266 267 # Specific event uuids were passed in, use those for this filter. 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 # 'tags' comes from managed object guids. 295 # see Zuul/security/security.py 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 # if they passed in specific uuids but not other params 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 # make a specific instance of tag_filter just for the context tag. 323 context_tag_filter = { 324 'tag_uuids': [IGlobalIdentifier(context).getGUID()] 325 } 326 # if it exists, filter['tag_filter'] will be a list. just append the special 327 # context tag filter to whatever that list is. 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
341 - def detail(self, evid):
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
385 - def _buildRequestFilters(self, uid, params, evids, excludeIds):
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 # if the request contains specific event summaries to act on, they will 397 # be passed in as evids. Excluded event summaries are passed in under 398 # the keyword argument 'excludeIds'. If these exist, pass them in as 399 # parameters to be used to construct the EventFilter. 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 # the only thing excluded in an event filter is a list of event uuids 408 # which are passed as EventTagFilter using the OR operator. 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')
419 - def nextEventSummaryUpdate(self, next_request):
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')
439 - def clear_device_heartbeats(self, params, limit=None):
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
547 - def unacknowledge(self, *args, **kwargs):
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")
594 - def updateEventSummaries(self, update, event_filter=None, exclusion_filter=None, limit=None):
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 # This occurs if the event is queued but there are no consumers - i.e. zeneventd is not 625 # currently running. 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 # This occurs if there is a failure publishing the event to the queue. 630 log.exception("Failed creating event") 631 return DirectResponse.exception(e, "Failed to create event")
632 633 @property
634 - def configSchema(self):
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
732 - def _mergeSchemaAndZepConfig(self, data, configSchema):
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')
744 - def getConfig(self):
745 # this data var is not a ZepConfig, it's a config structure that has been 746 # constructed to include default values and be keyed by the protobuf 747 # property name. 748 data = self.zep.getConfig() 749 config = self._mergeSchemaAndZepConfig(data, self.configSchema) 750 return DirectResponse.succeed(data=config)
751 752 @require('Manage DMD')
753 - def setConfigValues(self, values):
754 """ 755 @type values: Dictionary 756 @param values: Key Value pairs of config values 757 """ 758 # Remove empty strings from values 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 # we store default syslog priority and default availability days on the event manager 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
775 - def column_config(self, uid=None, archive=False):
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')
790 - def classify(self, evrows, evclass):
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')
809 - def clear_heartbeats(self):
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