1
2
3
4
5
6
7
8
9
10
11
12
13
14 import re
15 import simplejson
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.ZenUtils.json import json
22 from Products.ZenUtils.Utils import formreq, extractPostContent
23 from Products.ZenWidgets import messaging
24 from Products.ZenModel.ZenossSecurity import *
25 from Products.ZenEvents.browser.EventPillsAndSummaries import \
26 getDashboardObjectsEventSummary, \
27 ObjectsEventSummary, \
28 getEventPillME
29
30
32 """
33 Return JSON event summaries for a root organizer.
34 """
35 @formreq
39
42
43
45 """
46 Return a map of device to production state in a format suitable for a
47 YUI data table.
48 """
49 @formreq
52
53 @json
55 """
56 Return a map of device to production state in a format suitable for a
57 YUI data table.
58
59 @return: A JSON representation of a dictionary describing devices
60 @rtype: "{
61 'columns':['Device', 'Prod State'],
62 'data':[
63 {'Device':'<a href=/>', 'Prod State':'Production'},
64 {'Device':'<a href=/>', 'Prod State':'Maintenance'},
65 ]}"
66 """
67 devroot = self.context.dmd.Devices
68 if type(prodStates)==type(''):
69 prodStates = [prodStates]
70 orderby, orderdir = 'id', 'asc'
71 catalog = getattr(devroot, devroot.default_catalog)
72 queries = []
73 for state in prodStates:
74 queries.append(Eq('getProdState', state))
75 query = Or(*queries)
76 objects = catalog.evalAdvancedQuery(query, ((orderby, orderdir),))
77 devs = (x.getObject() for x in objects)
78 mydict = {'columns':['Device', 'Prod State'], 'data':[]}
79 for dev in devs:
80 if not self.context.checkRemotePerm(ZEN_VIEW, dev): continue
81 mydict['data'].append({
82 'Device' : dev.getPrettyLink(),
83 'Prod State' : dev.getProdState()
84 })
85 mydict['data'] = mydict['data'][:100]
86 return mydict
87
88
90 """
91 Accepts a list of paths to Zope objects which it then attempts to resolve.
92 If no list of paths is given, it will try to read them from the POST data
93 of the REQUEST object.
94
95 @param entities: A list of paths that should be resolved into objects
96 and passed to L{getDashboardObjectsEventSummaryJSON}.
97 @type entities: list
98 @return: A JSON-formatted string representation of the columns and rows
99 of the table
100 @rtype: string
101 """
102 @formreq
105
106 @json
108 if entities is None:
109 entities = []
110 elif isinstance(entities, basestring):
111 entities = [entities]
112 def getob(e):
113 e = str(e)
114 try:
115 if not e.startswith('/zport/dmd'):
116 bigdev = '/zport/dmd' + e
117 obj = self.context.dmd.unrestrictedTraverse(bigdev)
118 except (AttributeError, KeyError):
119 obj = self.context.dmd.Devices.findDevice(e)
120 if self.context.has_permission("View", obj): return obj
121 entities = filter(lambda x:x is not None, map(getob, entities))
122 return getDashboardObjectsEventSummary(
123 self.context.dmd.ZenEventManager, entities)
124
125
127 """
128 A list of devices with issues.
129 """
132
133 @json
135 """
136 Get devices with issues in a form suitable for a portlet on the
137 dashboard.
138
139 @return: A JSON representation of a dictionary describing devices
140 @rtype: "{
141 'columns':['Device', "Events'],
142 'data':[
143 {'Device':'<a href=/>', 'Events':'<div/>'},
144 {'Device':'<a href=/>', 'Events':'<div/>'},
145 ]}"
146 """
147 mydict = {'columns':[], 'data':[]}
148 mydict['columns'] = ['Device', 'Events']
149 deviceinfo = self.getDeviceDashboard()
150 for alink, pill in deviceinfo:
151 mydict['data'].append({'Device':alink,
152 'Events':pill})
153 return mydict
154
156 """return device info for bad device to dashboard"""
157 zem = self.context.dmd.ZenEventManager
158 devices = [d[0] for d in zem.getDeviceIssues(
159 severity=4, state=1)]
160 devdata = []
161 devclass = zem.getDmdRoot("Devices")
162 getcolor = re.compile(r'class=\"evpill-(.*?)\"', re.S|re.I|re.M).search
163 colors = "red orange yellow blue grey green".split()
164 def pillcompare(a,b):
165 a, b = map(lambda x:getcolor(x[1]), (a, b))
166 def getindex(x):
167 try:
168 color = x.groups()[0]
169 smallcolor = x.groups()[0].replace('-acked','')
170 isacked = 'acked' in color
171 index = colors.index(x.groups()[0].replace('-acked',''))
172 if isacked: index += .5
173 return index
174 except: return 5
175 a, b = map(getindex, (a, b))
176 return cmp(a, b)
177 for devname in devices:
178 dev = devclass.findDevice(devname)
179 if dev and dev.id == devname:
180 if (not zem.checkRemotePerm(ZEN_VIEW, dev)
181 or dev.productionState < zem.prodStateDashboardThresh
182 or dev.priority < zem.priorityDashboardThresh):
183 continue
184 alink = dev.getPrettyLink()
185 try:
186 pill = getEventPillME(zem, dev)[0]
187 except IndexError:
188 continue
189 evts = [alink,pill]
190 devdata.append(evts)
191 devdata.sort(pillcompare)
192 return devdata[:100]
193
194
196 """
197 Heartbeat issues in YUI table form, for the dashboard portlet
198 """
201
202 @json
204 """
205 Get heartbeat issues in a form suitable for a portlet on the dashboard.
206
207 @return: A JSON representation of a dictionary describing heartbeats
208 @rtype: "{
209 'columns':['Device', 'Daemon', 'Seconds'],
210 'data':[
211 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10}
212 ]}"
213 """
214 mydict = {'columns':[], 'data':[]}
215 mydict['columns'] = ['Device', 'Daemon', 'Seconds']
216 heartbeats = self.context.dmd.ZenEventManager.getHeartbeat()
217 for Device, Daemon, Seconds, dummy in heartbeats:
218 mydict['data'].append({'Device':Device,
219 'Daemon':Daemon, 'Seconds':Seconds})
220 return mydict
221
222
224 """
225 User messages in YUI table form, for the dashboard portlet.
226 """
227 @json
229 """
230 Get heartbeat issues in a form suitable for a portlet on the dashboard.
231
232 @return: A JSON representation of a dictionary describing heartbeats
233 @rtype: "{
234 'columns':['Device', 'Daemon', 'Seconds'],
235 'data':[
236 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10}
237 ]}"
238 """
239 ICONS = ['/zport/dmd/img/agt_action_success-32.png',
240 '/zport/dmd/img/messagebox_warning-32.png',
241 '/zport/dmd/img/agt_stop-32.png']
242 msgbox = messaging.IUserMessages(self.context)
243 msgs = msgbox.get_messages()
244 cols = ['Message']
245 res = []
246 for msg in msgs:
247 res.append(dict(
248 title = msg.title,
249 imgpath = ICONS[msg.priority],
250 body = msg.body,
251 ago = relative_time(msg.timestamp),
252 deletelink = msg.absolute_url_path() + '/delMsg'
253 ))
254 res.reverse()
255 return { 'columns': cols, 'data': res }
256