Package ZenEvents :: Module ActionRule
[hide private]
[frames] | no frames]

Source Code for Module ZenEvents.ActionRule

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13  import time 
 14  import re 
 15  from sets import Set 
 16  import logging 
 17  log = logging.getLogger("zen.ActionRule") 
 18   
 19  from Globals import InitializeClass 
 20  from Globals import DTMLFile 
 21  from AccessControl import ClassSecurityInfo 
 22  from Products.ZenModel.ZenossSecurity import *  
 23  from Acquisition import aq_parent 
 24   
 25  from Products.ZenModel.ZenModelRM import ZenModelRM 
 26  from Products.ZenRelations.RelSchema import * 
 27  from Products.ZenUtils import Time 
 28  from Products.ZenEvents.EventFilter import EventFilter 
 29  from Products.ZenWidgets import messaging 
 30   
 31  from ActionRuleWindow import ActionRuleWindow 
32 -def _downcase(s):
33 return s[0:1].lower() + s[1:]
34
35 -def manage_addActionRule(context, id, REQUEST=None):
36 """Create an action rule""" 37 ed = ActionRule(id) 38 context._setObject(id, ed) 39 if REQUEST is not None: 40 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
41 42 addActionRule = DTMLFile('dtml/addActionRule',globals()) 43
44 -class ActionRule(ZenModelRM, EventFilter):
45 """ 46 Rule applied to events that then executes an action on matching events. 47 """ 48 49 meta_type = "ActionRule" 50 51 where = "severity >= 4 and eventState = 0 and prodState = 1000" 52 delay = 0 53 repeatTime = 0 54 action = "email" 55 format = "[zenoss] %(device)s %(summary)s" 56 body = "Device: %(device)s\n" \ 57 "Component: %(component)s\n" \ 58 "Severity: %(severityString)s\n" \ 59 "Time: %(firstTime)s\n" \ 60 "Message:\n%(message)s\n" \ 61 "<a href=\"%(eventUrl)s\">Event Detail</a>\n" \ 62 "<a href=\"%(ackUrl)s\">Acknowledge</a>\n" \ 63 "<a href=\"%(deleteUrl)s\">Delete</a>\n" \ 64 "<a href=\"%(eventsUrl)s\">Device Events</a>\n" 65 sendClear = True 66 clearFormat = "[zenoss] CLEAR: %(device)s %(clearOrEventSummary)s" 67 clearBody = \ 68 "Event: '%(summary)s'\n" \ 69 "Cleared by: '%(clearSummary)s'\n" \ 70 "At: %(clearFirstTime)s\n" \ 71 "Device: %(device)s\n" \ 72 "Component: %(component)s\n" \ 73 "Severity: %(severityString)s\n" \ 74 "Message:\n%(message)s\n" 75 enabled = False 76 actionTypes = ("page", "email") 77 targetAddr = "" 78 plainText = False 79 80 _properties = ZenModelRM._properties + ( 81 {'id':'where', 'type':'text', 'mode':'w'}, 82 {'id':'format', 'type':'text', 'mode':'w'}, 83 {'id':'body', 'type':'text', 'mode':'w'}, 84 {'id':'sendClear', 'type':'boolean', 'mode':'w'}, 85 {'id':'clearFormat', 'type':'text', 'mode':'w'}, 86 {'id':'clearBody', 'type':'text', 'mode':'w'}, 87 {'id':'delay', 'type':'int', 'mode':'w'}, 88 {'id':'action', 'type':'selection', 'mode':'w', 89 'select_variable': 'actionTypes',}, 90 {'id':'enabled', 'type':'boolean', 'mode':'w'}, 91 {'id':'targetAddr', 'type':'string', 'mode':'w'}, 92 {'id':'repeatTime', 'type':'int', 'mode':'w'}, 93 {'id':'plainText', 'type':'boolean', 'mode':'w'}, 94 ) 95 96 _relations = ( 97 ("windows", ToManyCont(ToOne,"Products.ZenEvents.ActionRuleWindow","actionRule")), 98 ) 99 100 factory_type_information = ( 101 { 102 'id' : 'ActionRule', 103 'meta_type' : 'ActionRule', 104 'description' : """Define action taken against events""", 105 'icon' : 'ActionRule.gif', 106 'product' : 'ZenEvents', 107 'factory' : 'manage_addActionRule', 108 'immediate_view' : 'editActionRule', 109 'actions' : 110 ( 111 { 'id' : 'edit' 112 , 'name' : 'Edit' 113 , 'action' : 'editActionRule' 114 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 115 }, 116 { 'id' : 'message' 117 , 'name' : 'Message' 118 , 'action' : 'editActionRuleMessage' 119 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 120 }, 121 { 'id' : 'schedule' 122 , 'name' : 'Schedule' 123 , 'action' : 'editActionRuleSchedule' 124 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 125 }, 126 ) 127 }, 128 ) 129 130 security = ClassSecurityInfo() 131 132
133 - def breadCrumbs(self, terminator='dmd'):
134 """Return the breadcrumb links for this object add ActionRules list. 135 [('url','id'), ...] 136 """ 137 crumbs = super(ActionRule, self).breadCrumbs(terminator) 138 url = aq_parent(self).absolute_url_path() + "/editActionRules" 139 crumbs.insert(-1,(url,'Alerting Rules')) 140 return crumbs
141
142 - def getEventFields(self):
143 """Return list of fields used in format. 144 """ 145 result = Set() 146 result.update(re.findall("%\((\S+)\)s", self.format)) 147 result.update(re.findall("%\((\S+)\)s", self.body)) 148 result.update([ f for f in re.findall("%\((\S+)\)s", self.clearFormat) \ 149 if not f.startswith('clear') ]) 150 result.update([ f for f in re.findall("%\((\S+)\)s", self.clearBody) \ 151 if not f.startswith('clear') ]) 152 result.update(map(_downcase, re.findall("%\(clear(\S+)\)s", self.clearFormat))) 153 result.update(map(_downcase, re.findall("%\(clear(\S+)\)s", self.clearBody))) 154 notDb = Set('orEventSummary eventUrl eventsUrl ackUrl deleteUrl severityString'.split()) 155 notMsg = ['severity', 'summary'] 156 return list(result - notDb) + notMsg
157 158
159 - def checkFormat(self):
160 """Check that the format string has valid fields. 161 """ 162 evtfields = self.dmd.ZenEventManager.getFieldList() 163 for field in self.getEventFields(): 164 if field not in evtfields: 165 return False 166 return True
167 168
169 - def getAddresses(self):
170 """Return the correct addresses for the action this rule uses. 171 """ 172 if self.targetAddr: 173 return [self.targetAddr] 174 elif self.action == "page": 175 return self.getUser().getPagerAddresses() 176 elif self.action == "email": 177 return self.getUser().getEmailAddresses()
178 179
180 - def getUser(self):
181 """Return the user this action is for. 182 """ 183 return self.getPrimaryParent()
184
185 - def getUserid(self):
186 """Return the userid this action is for. 187 """ 188 return self.getUser().getId()
189 190 191 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 'manage_editActionRule')
192 - def manage_editActionRule(self, REQUEST=None):
193 """Update user settings. 194 """ 195 if not self.enabled: 196 self._clearAlertState() 197 import WhereClause 198 if REQUEST.form.has_key('onRulePage') \ 199 and not REQUEST.form.has_key('where'): 200 clause = WhereClause.fromFormVariables(self.genMeta(), REQUEST.form) 201 if clause: 202 REQUEST.form['where'] = clause 203 else: 204 messaging.IMessageSender(self).sendToBrowser( 205 'Invalid', 206 'An alerting rule must have at least one criterion.', 207 priority=messaging.WARNING 208 ) 209 return self.callZenScreen(REQUEST) 210 return self.zmanage_editProperties(REQUEST)
211 212
213 - def manage_beforeDelete(self, item, container):
214 """ 215 Clear state in alert_state before we are deleted. 216 Also need to unindex the actionrulewindows 217 """ 218 self._clearAlertState() 219 super(ActionRule, self).manage_beforeDelete(item, container)
220 221
222 - def _clearAlertState(self):
223 """Clear state in alert_state before we are deleted. 224 """ 225 zem = self.dmd.ZenEventManager 226 conn = zem.connect() 227 try: 228 delcmd = "delete from alert_state where %s" % self.sqlwhere() 229 log.debug("clear alert state '%s'", delcmd) 230 curs = conn.cursor() 231 curs.execute(delcmd) 232 finally: zem.close(conn)
233
234 - def sqlwhere(self):
235 """Return sql where to select alert_state data for this event. 236 """ 237 return "userid = '%s' and rule = '%s'" % (self.getUserid(), self.id)
238
239 - def nextActiveWindow(self):
240 next = None 241 w = None 242 for ar in self.windows(): 243 if next is None or ar.next() < next: 244 next = ar.next() 245 w = ar 246 return w
247
248 - def nextActive(self):
249 if self.enabled: 250 return time.time() 251 w = self.nextActiveWindow() 252 if w: 253 return w.next()
254
255 - def nextActiveNice(self):
256 if self.enabled: 257 return "Now" 258 t = self.nextActive() 259 if t is None: 260 return "Never" 261 return Time.LocalDateTime(t)
262
263 - def nextDurationNice(self):
264 w = self.nextActiveWindow() 265 if w is None: 266 return "Forever" 267 if self.enabled: 268 next = w.next() 269 if next: 270 return Time.Duration((next + w.duration) - time.time()) 271 return Time.Duration(w.duration)
272
273 - def repeatNice(self):
274 w = self.nextActiveWindow() 275 if w is None: 276 return "Never" 277 return w.repeat
278 279 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 280 'manage_addActionRuleWindow')
281 - def manage_addActionRuleWindow(self, newId, REQUEST=None):
282 "Add a ActionRule Window to this device" 283 if newId: 284 mw = ActionRuleWindow(newId) 285 self.windows._setObject(newId, mw) 286 if REQUEST: 287 messaging.IMessageSender(self).sendToBrowser( 288 'Active Period Added', 289 'The action rule window has been created successfully.' 290 ) 291 return self.callZenScreen(REQUEST)
292 293 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 294 'manage_deleteActionRuleWindow')
295 - def manage_deleteActionRuleWindow(self, windowIds, REQUEST=None):
296 "Delete a ActionRule Window to this device" 297 import types 298 if type(windowIds) in types.StringTypes: 299 windowIds = [windowIds] 300 for id in windowIds: 301 self.windows._delObject(id) 302 if REQUEST: 303 messaging.IMessageSender(self).sendToBrowser( 304 'Active Period Deleted', 305 'The action rule window has been removed.' 306 ) 307 return self.callZenScreen(REQUEST)
308 309 310 InitializeClass(ActionRule) 311