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 "<a href=\"%(undeleteUrl)s\">Undelete</a>\n" 76 enabled = False 77 actionTypes = ("page", "email") 78 targetAddr = "" 79 plainText = False 80 81 _properties = ZenModelRM._properties + ( 82 {'id':'where', 'type':'text', 'mode':'w'}, 83 {'id':'format', 'type':'text', 'mode':'w'}, 84 {'id':'body', 'type':'text', 'mode':'w'}, 85 {'id':'sendClear', 'type':'boolean', 'mode':'w'}, 86 {'id':'clearFormat', 'type':'text', 'mode':'w'}, 87 {'id':'clearBody', 'type':'text', 'mode':'w'}, 88 {'id':'delay', 'type':'int', 'mode':'w'}, 89 {'id':'action', 'type':'selection', 'mode':'w', 90 'select_variable': 'actionTypes',}, 91 {'id':'enabled', 'type':'boolean', 'mode':'w'}, 92 {'id':'targetAddr', 'type':'string', 'mode':'w'}, 93 {'id':'repeatTime', 'type':'int', 'mode':'w'}, 94 {'id':'plainText', 'type':'boolean', 'mode':'w'}, 95 ) 96 97 _relations = ( 98 ("windows", ToManyCont(ToOne,"Products.ZenEvents.ActionRuleWindow","actionRule")), 99 ) 100 101 factory_type_information = ( 102 { 103 'id' : 'ActionRule', 104 'meta_type' : 'ActionRule', 105 'description' : """Define action taken against events""", 106 'icon' : 'ActionRule.gif', 107 'product' : 'ZenEvents', 108 'factory' : 'manage_addActionRule', 109 'immediate_view' : 'editActionRule', 110 'actions' : 111 ( 112 { 'id' : 'edit' 113 , 'name' : 'Edit' 114 , 'action' : 'editActionRule' 115 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 116 }, 117 { 'id' : 'message' 118 , 'name' : 'Message' 119 , 'action' : 'editActionRuleMessage' 120 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 121 }, 122 { 'id' : 'schedule' 123 , 'name' : 'Schedule' 124 , 'action' : 'editActionRuleSchedule' 125 , 'permissions' : (ZEN_CHANGE_ALERTING_RULES,) 126 }, 127 ) 128 }, 129 ) 130 131 security = ClassSecurityInfo() 132 133
134 - def breadCrumbs(self, terminator='dmd'):
135 """Return the breadcrumb links for this object add ActionRules list. 136 [('url','id'), ...] 137 """ 138 crumbs = super(ActionRule, self).breadCrumbs(terminator) 139 url = aq_parent(self).absolute_url_path() + "/editActionRules" 140 crumbs.insert(-1,(url,'Alerting Rules')) 141 return crumbs
142
143 - def getEventFields(self):
144 """Return list of fields used in format. 145 """ 146 result = Set() 147 result.update(re.findall("%\((\S+)\)s", self.format)) 148 result.update(re.findall("%\((\S+)\)s", self.body)) 149 result.update([ f for f in re.findall("%\((\S+)\)s", self.clearFormat) \ 150 if not f.startswith('clear') ]) 151 result.update([ f for f in re.findall("%\((\S+)\)s", self.clearBody) \ 152 if not f.startswith('clear') ]) 153 result.update(map(_downcase, re.findall("%\(clear(\S+)\)s", self.clearFormat))) 154 result.update(map(_downcase, re.findall("%\(clear(\S+)\)s", self.clearBody))) 155 notDb = Set('orEventSummary eventUrl eventsUrl ackUrl deleteUrl undeleteUrl severityString'.split()) 156 notMsg = ['severity', 'summary'] 157 return list(result - notDb) + notMsg
158 159
160 - def checkFormat(self):
161 """Check that the format string has valid fields. 162 """ 163 evtfields = self.dmd.ZenEventManager.getFieldList() 164 for field in self.getEventFields(): 165 if field not in evtfields: 166 return False 167 return True
168 169
170 - def getAddresses(self):
171 """Return the correct addresses for the action this rule uses. 172 """ 173 if self.targetAddr: 174 return [self.targetAddr] 175 elif self.action == "page": 176 return self.getUser().getPagerAddresses() 177 elif self.action == "email": 178 return self.getUser().getEmailAddresses()
179 180
181 - def getUser(self):
182 """Return the user this action is for. 183 """ 184 return self.getPrimaryParent()
185
186 - def getUserid(self):
187 """Return the userid this action is for. 188 """ 189 return self.getUser().getId()
190 191 192 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 'manage_editActionRule')
193 - def manage_editActionRule(self, REQUEST=None):
194 """Update user settings. 195 """ 196 if not self.enabled: 197 self._clearAlertState() 198 import WhereClause 199 if REQUEST.form.has_key('onRulePage') \ 200 and not REQUEST.form.has_key('where'): 201 clause = WhereClause.fromFormVariables(self.genMeta(), REQUEST.form) 202 if clause: 203 REQUEST.form['where'] = clause 204 else: 205 messaging.IMessageSender(self).sendToBrowser( 206 'Invalid', 207 'An alerting rule must have at least one criterion.', 208 priority=messaging.WARNING 209 ) 210 return self.callZenScreen(REQUEST) 211 return self.zmanage_editProperties(REQUEST)
212 213
214 - def manage_beforeDelete(self, item, container):
215 """ 216 Clear state in alert_state before we are deleted. 217 Also need to unindex the actionrulewindows 218 """ 219 self._clearAlertState() 220 super(ActionRule, self).manage_beforeDelete(item, container)
221 222
223 - def _clearAlertState(self):
224 """Clear state in alert_state before we are deleted. 225 """ 226 zem = self.dmd.ZenEventManager 227 conn = zem.connect() 228 try: 229 delcmd = "delete from alert_state where %s" % self.sqlwhere() 230 log.debug("clear alert state '%s'", delcmd) 231 curs = conn.cursor() 232 curs.execute(delcmd) 233 finally: zem.close(conn)
234
235 - def sqlwhere(self):
236 """Return sql where to select alert_state data for this event. 237 """ 238 return "userid = '%s' and rule = '%s'" % (self.getUserid(), self.id)
239
240 - def nextActiveWindow(self):
241 next = None 242 w = None 243 for ar in self.windows(): 244 if next is None or ar.next() < next: 245 next = ar.next() 246 w = ar 247 return w
248
249 - def nextActive(self):
250 if self.enabled: 251 return time.time() 252 w = self.nextActiveWindow() 253 if w: 254 return w.next()
255
256 - def nextActiveNice(self):
257 if self.enabled: 258 return "Now" 259 t = self.nextActive() 260 if t is None: 261 return "Never" 262 return Time.LocalDateTime(t)
263
264 - def nextDurationNice(self):
265 w = self.nextActiveWindow() 266 if w is None: 267 return "Forever" 268 if self.enabled: 269 next = w.next() 270 if next: 271 return Time.Duration((next + w.duration) - time.time()) 272 return Time.Duration(w.duration)
273
274 - def repeatNice(self):
275 w = self.nextActiveWindow() 276 if w is None: 277 return "Never" 278 return w.repeat
279 280 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 281 'manage_addActionRuleWindow')
282 - def manage_addActionRuleWindow(self, newId, REQUEST=None):
283 "Add a ActionRule Window to this device" 284 if newId: 285 mw = ActionRuleWindow(newId) 286 self.windows._setObject(newId, mw) 287 if REQUEST: 288 messaging.IMessageSender(self).sendToBrowser( 289 'Active Period Added', 290 'The action rule window has been created successfully.' 291 ) 292 return self.callZenScreen(REQUEST)
293 294 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 295 'manage_deleteActionRuleWindow')
296 - def manage_deleteActionRuleWindow(self, windowIds, REQUEST=None):
297 "Delete a ActionRule Window to this device" 298 import types 299 if type(windowIds) in types.StringTypes: 300 windowIds = [windowIds] 301 for id in windowIds: 302 self.windows._delObject(id) 303 if REQUEST: 304 messaging.IMessageSender(self).sendToBrowser( 305 'Active Period Deleted', 306 'The action rule window has been removed.' 307 ) 308 return self.callZenScreen(REQUEST)
309 310 311 InitializeClass(ActionRule) 312