Package Products :: Package ZenWidgets :: Package browser :: Module Portlets
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenWidgets.browser.Portlets

  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 or (at your 
  8  # option) any later version as published by the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  import re 
 15  import json 
 16   
 17  from Products.Five.browser import BrowserView 
 18  from Products.AdvancedQuery import Eq, Or 
 19   
 20  from Products.ZenUtils.Utils import relative_time 
 21  from Products.Zuul import getFacade 
 22  from Products.ZenEvents.HeartbeatUtils import getHeartbeatObjects 
 23  from zenoss.protocols.services import ServiceException 
 24  from zenoss.protocols.services.zep import ZepConnectionError 
 25  from Products.ZenUtils.guid.interfaces import IGUIDManager 
 26  from Products.ZenUtils.jsonutils import json 
 27  from Products.ZenUtils.Utils import nocache, formreq, extractPostContent 
 28  from Products.ZenWidgets import messaging 
 29  from Products.ZenModel.Device import Device 
 30  from Products.ZenModel.ZenossSecurity import * 
 31  from Products.ZenEvents.browser.EventPillsAndSummaries import \ 
 32                                     getDashboardObjectsEventSummary, \ 
 33                                     ObjectsEventSummary,    \ 
 34                                     getEventPillME 
 35   
 36  import logging 
 37  log = logging.getLogger('zen.portlets') 
38 39 40 -def zepConnectionError(retval=None):
41 def outer(func): 42 def inner(self, *args, **kwargs): 43 try: 44 return func(self, *args, **kwargs) 45 except ZepConnectionError, e: 46 msg = 'Connection refused. Check zeneventserver status on <a href="/zport/About/zenossInfo">Daemons</a>' 47 messaging.IMessageSender(self.context).sendToBrowser("ZEP connection error", 48 msg, 49 priority=messaging.CRITICAL, 50 sticky=True) 51 log.warn("Could not connect to ZEP") 52 return retval
53 return inner 54 return outer 55
56 -class TopLevelOrganizerPortletView(ObjectsEventSummary):
57 """ 58 Return JSON event summaries for a root organizer. 59 """ 60 @nocache 61 @formreq
62 - def __call__(self, dataRoot):
63 self.dataRoot = dataRoot 64 return super(TopLevelOrganizerPortletView, self).__call__()
65
66 - def _getObs(self):
67 return self.context.dmd.getDmdRoot(self.dataRoot).children()
68
69 70 -class ProductionStatePortletView(BrowserView):
71 """ 72 Return a map of device to production state in a format suitable for a 73 YUI data table. 74 """ 75 @nocache 76 @formreq
77 - def __call__(self, *args, **kwargs):
78 return self.getDevProdStateJSON(*args, **kwargs)
79 80 @json
81 - def getDevProdStateJSON(self, prodStates=['Maintenance']):
82 """ 83 Return a map of device to production state in a format suitable for a 84 YUI data table. 85 86 @return: A JSON representation of a dictionary describing devices 87 @rtype: "{ 88 'columns':['Device', 'Prod State'], 89 'data':[ 90 {'Device':'<a href=/>', 'Prod State':'Production'}, 91 {'Device':'<a href=/>', 'Prod State':'Maintenance'}, 92 ]}" 93 """ 94 devroot = self.context.dmd.Devices 95 if isinstance(prodStates, basestring): 96 prodStates = [prodStates] 97 orderby, orderdir = 'id', 'asc' 98 catalog = getattr(devroot, devroot.default_catalog) 99 queries = [] 100 for state in prodStates: 101 queries.append(Eq('getProdState', state)) 102 query = Or(*queries) 103 objects = catalog.evalAdvancedQuery(query, ((orderby, orderdir),)) 104 devs = (x.getObject() for x in objects) 105 mydict = {'columns':['Device', 'Prod State'], 'data':[]} 106 for dev in devs: 107 if not self.context.checkRemotePerm(ZEN_VIEW, dev): continue 108 mydict['data'].append({ 109 'Device' : dev.getPrettyLink(), 110 'Prod State' : dev.getProdState() 111 }) 112 if len(mydict['data'])>=100: 113 break 114 return mydict
115
116 117 -class WatchListPortletView(BrowserView):
118 """ 119 Accepts a list of paths to Zope objects which it then attempts to resolve. 120 If no list of paths is given, it will try to read them from the POST data 121 of the REQUEST object. 122 123 @param entities: A list of paths that should be resolved into objects 124 and passed to L{getDashboardObjectsEventSummaryJSON}. 125 @type entities: list 126 @return: A JSON-formatted string representation of the columns and rows 127 of the table 128 @rtype: string 129 """ 130 @nocache 131 @formreq
132 - def __call__(self, *args, **kwargs):
133 return self.getEntityListEventSummary(*args, **kwargs)
134 135 @json
136 - def getEntityListEventSummary(self, entities=None):
137 if entities is None: 138 entities = [] 139 elif isinstance(entities, basestring): 140 entities = [entities] 141 def getob(e): 142 e = str(e) 143 try: 144 if not e.startswith('/zport/dmd'): 145 bigdev = '/zport/dmd' + e 146 obj = self.context.dmd.unrestrictedTraverse(bigdev) 147 except (AttributeError, KeyError): 148 obj = self.context.dmd.Devices.findDevice(e) 149 if self.context.has_permission("View", obj): return obj
150 entities = filter(lambda x:x is not None, map(getob, entities)) 151 return getDashboardObjectsEventSummary( 152 self.context.dmd.ZenEventManager, entities)
153
154 155 -class DeviceIssuesPortletView(BrowserView):
156 """ 157 A list of devices with issues. 158 """ 159 @nocache
160 - def __call__(self):
161 return self.getDeviceIssuesJSON()
162 163 @json
164 - def getDeviceIssuesJSON(self):
165 """ 166 Get devices with issues in a form suitable for a portlet on the 167 dashboard. 168 169 @return: A JSON representation of a dictionary describing devices 170 @rtype: "{ 171 'columns':['Device', "Events'], 172 'data':[ 173 {'Device':'<a href=/>', 'Events':'<div/>'}, 174 {'Device':'<a href=/>', 'Events':'<div/>'}, 175 ]}" 176 """ 177 mydict = {'columns':[], 'data':[]} 178 mydict['columns'] = ['Device', 'Events'] 179 deviceinfo = self.getDeviceDashboard() 180 for alink, pill in deviceinfo: 181 mydict['data'].append({'Device':alink, 182 'Events':pill}) 183 return mydict
184 185 @zepConnectionError([])
186 - def getDeviceDashboard(self):
187 """return device info for bad device to dashboard""" 188 zep = getFacade('zep') 189 manager = IGUIDManager(self.context.dmd) 190 deviceSeverities = zep.getDeviceIssuesDict() 191 zem = self.context.dmd.ZenEventManager 192 193 devdata = [] 194 for uuid in deviceSeverities.keys(): 195 dev = manager.getObject(uuid) 196 if dev and isinstance(dev, Device): 197 if (not zem.checkRemotePerm(ZEN_VIEW, dev) 198 or dev.productionState < zem.prodStateDashboardThresh 199 or dev.priority < zem.priorityDashboardThresh): 200 continue 201 alink = dev.getPrettyLink() 202 try: 203 severities = deviceSeverities[uuid] 204 severities = dict((zep.getSeverityName(sev).lower(), counts) for (sev, counts) in severities.iteritems()) 205 pill = getEventPillME(dev, severities=severities) 206 except ServiceException: 207 continue 208 evts = [alink,pill] 209 devdata.append((evts, severities)) 210 devdata.sort(key=lambda x:(x[1]['critical'], x[1]['error'], x[1]['warning']), reverse=True) 211 return [x[0] for x in devdata[:100]]
212 213 214 heartbeat_columns = ['Device', 'Daemon', 'Seconds']
215 216 -class HeartbeatPortletView(BrowserView):
217 """ 218 Heartbeat issues in YUI table form, for the dashboard portlet 219 """ 220 @nocache
221 - def __call__(self):
222 return self.getHeartbeatIssuesJSON()
223 224 @zepConnectionError({'columns': heartbeat_columns, 'data':[]}) 225 @json
226 - def getHeartbeatIssuesJSON(self):
227 """ 228 Get heartbeat issues in a form suitable for a portlet on the dashboard. 229 230 @return: A JSON representation of a dictionary describing heartbeats 231 @rtype: "{ 232 'columns':['Device', 'Daemon', 'Seconds'], 233 'data':[ 234 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10} 235 ]}" 236 """ 237 data = getHeartbeatObjects(deviceRoot=self.context.dmd.Devices, 238 keys=heartbeat_columns) 239 return {'columns': heartbeat_columns, 'data': data}
240
241 242 -class UserMessagesPortletView(BrowserView):
243 """ 244 User messages in YUI table form, for the dashboard portlet. 245 """ 246 @nocache 247 @json
248 - def __call__(self):
249 """ 250 Get heartbeat issues in a form suitable for a portlet on the dashboard. 251 252 @return: A JSON representation of a dictionary describing heartbeats 253 @rtype: "{ 254 'columns':['Device', 'Daemon', 'Seconds'], 255 'data':[ 256 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10} 257 ]}" 258 """ 259 ICONS = ['/zport/dmd/img/agt_action_success-32.png', 260 '/zport/dmd/img/messagebox_warning-32.png', 261 '/zport/dmd/img/agt_stop-32.png'] 262 msgbox = messaging.IUserMessages(self.context) 263 msgs = msgbox.get_messages() 264 cols = ['Message'] 265 res = [] 266 for msg in msgs: 267 res.append(dict( 268 title = msg.title, 269 imgpath = ICONS[msg.priority], 270 body = msg.body, 271 ago = relative_time(msg.timestamp), 272 deletelink = msg.absolute_url_path() + '/delMsg' 273 )) 274 res.reverse() 275 return { 'columns': cols, 'data': res }
276