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

Source Code for Module Products.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
144 - def getEventFields(self):
145 """Return list of fields used in format. 146 """ 147 regex = re.compile(r'%\(([^\)]+)\)s') 148 clearRegex = re.compile(r'%\(clear([^\)]+)\)s') 149 result = Set() 150 result.update(regex.findall(self.format)) 151 result.update(regex.findall(self.body)) 152 result.update([ f for f in regex.findall(self.clearFormat) \ 153 if not f.startswith('clear') ]) 154 result.update([ f for f in regex.findall(self.clearBody) \ 155 if not f.startswith('clear') ]) 156 result.update(map(_downcase, clearRegex.findall(self.clearFormat))) 157 result.update(map(_downcase, clearRegex.findall(self.clearBody))) 158 notDb = Set('orEventSummary eventUrl eventsUrl ackUrl deleteUrl undeleteUrl severityString'.split()) 159 notMsg = ['severity', 'summary', 'ownerid', 'stateChange'] 160 return list(result - notDb) + notMsg
161 162
163 - def checkFormat(self):
164 """Check that the format string has valid fields. 165 """ 166 evtfields = self.dmd.ZenEventManager.getFieldList() 167 for field in self.getEventFields(): 168 if field not in evtfields: 169 return False 170 return True
171 172
173 - def getAddresses(self):
174 """Return the correct addresses for the action this rule uses. 175 """ 176 if self.targetAddr: 177 return [self.targetAddr] 178 elif self.action == "page": 179 return self.getUser().getPagerAddresses() 180 elif self.action == "email": 181 return self.getUser().getEmailAddresses()
182 183
184 - def getUser(self):
185 """Return the user this action is for. 186 """ 187 return self.getPrimaryParent()
188
189 - def getUserid(self):
190 """Return the userid this action is for. 191 """ 192 return self.getUser().getId()
193 194 195 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 'manage_editActionRule')
196 - def manage_editActionRule(self, REQUEST=None):
197 """Update user settings. 198 """ 199 if not self.enabled: 200 self._clearAlertState() 201 import WhereClause 202 if REQUEST.form.has_key('onRulePage') \ 203 and not REQUEST.form.has_key('where'): 204 clause = WhereClause.fromFormVariables(self.genMeta(), REQUEST.form) 205 if clause: 206 REQUEST.form['where'] = clause 207 else: 208 messaging.IMessageSender(self).sendToBrowser( 209 'Invalid', 210 'An alerting rule must have at least one criterion.', 211 priority=messaging.WARNING 212 ) 213 return self.callZenScreen(REQUEST) 214 return self.zmanage_editProperties(REQUEST)
215 216
217 - def _clearAlertState(self):
218 """Clear state in alert_state before we are deleted. 219 """ 220 zem = self.dmd.ZenEventManager 221 conn = zem.connect() 222 try: 223 delcmd = "delete from alert_state where %s" % self.sqlwhere() 224 log.debug("clear alert state '%s'", delcmd) 225 curs = conn.cursor() 226 curs.execute(delcmd) 227 finally: zem.close(conn)
228
229 - def sqlwhere(self):
230 """Return sql where to select alert_state data for this event. 231 """ 232 return "userid = '%s' and rule = '%s'" % (self.getUserid(), self.id)
233
234 - def nextActiveWindow(self):
235 next = None 236 w = None 237 for ar in self.windows(): 238 if next is None or ar.next() < next: 239 next = ar.next() 240 w = ar 241 return w
242
243 - def nextActive(self):
244 if self.enabled: 245 return time.time() 246 w = self.nextActiveWindow() 247 if w: 248 return w.next()
249
250 - def nextActiveNice(self):
251 if self.enabled: 252 return "Now" 253 t = self.nextActive() 254 if t is None: 255 return "Never" 256 return Time.LocalDateTime(t)
257
258 - def nextDurationNice(self):
259 w = self.nextActiveWindow() 260 if w is None: 261 return "Forever" 262 if self.enabled: 263 next = w.next() 264 if next: 265 return Time.Duration((next + w.duration) - time.time()) 266 return Time.Duration(w.duration)
267
268 - def repeatNice(self):
269 w = self.nextActiveWindow() 270 if w is None: 271 return "Never" 272 return w.repeat
273 274 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 275 'manage_addActionRuleWindow')
276 - def manage_addActionRuleWindow(self, newId, REQUEST=None):
277 "Add a ActionRule Window to this device" 278 if newId: 279 mw = ActionRuleWindow(newId) 280 self.windows._setObject(newId, mw) 281 if REQUEST: 282 messaging.IMessageSender(self).sendToBrowser( 283 'Active Period Added', 284 'The action rule window has been created successfully.' 285 ) 286 return self.callZenScreen(REQUEST)
287 288 security.declareProtected(ZEN_CHANGE_ALERTING_RULES, 289 'manage_deleteActionRuleWindow')
290 - def manage_deleteActionRuleWindow(self, windowIds, REQUEST=None):
291 "Delete a ActionRule Window to this device" 292 import types 293 if type(windowIds) in types.StringTypes: 294 windowIds = [windowIds] 295 for id in windowIds: 296 self.windows._delObject(id) 297 if REQUEST: 298 messaging.IMessageSender(self).sendToBrowser( 299 'Active Period Deleted', 300 'The action rule window has been removed.' 301 ) 302 return self.callZenScreen(REQUEST)
303 304 305 InitializeClass(ActionRule) 306