| Trees | Indices | Help |
|
|---|
|
|
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
14 import sys
15 from Globals import DTMLFile
16 from Globals import InitializeClass
17 from AccessControl import ClassSecurityInfo, Permissions
18 from Products.ZenModel.ZenossSecurity import *
19 from zope.interface import implements
20 from Acquisition import aq_parent
21 from ZenModelRM import ZenModelRM
22 from Products.ZenModel.interfaces import IIndexed
23
24 from Products.ZenRelations.RelSchema import *
25 from Products.ZenModel.RRDDataSource import SimpleRRDDataSource
26 from Products.ZenModel.BasicDataSource import BasicDataSource
27 from Products.ZenModel.BuiltInDS import BuiltInDS
28 from Products.ZenModel.ConfigurationError import ConfigurationError
29 from Products.ZenUtils.Utils import importClass
30 from Products.ZenWidgets import messaging
31 from RRDDataPoint import SEPARATOR
32 from ZenPackable import ZenPackable
33
34 import logging
35 log = logging.getLogger('zen.RRDTemplate')
36
37 RRDTEMPLATE_CATALOG = 'searchRRDTemplates'
38
39
41 """
42 Create the searchRRDTemplates catalog if it does not already exist.
43 Return the catalog.
44 """
45 from Products.ZCatalog.ZCatalog import manage_addZCatalog
46 from Products.ZenUtils.Search import makeCaseSensitiveFieldIndex, \
47 makePathIndex
48 zcat = getattr(dmd, RRDTEMPLATE_CATALOG, None)
49 if zcat and rebuild:
50 dmd._delObject(RRDTEMPLATE_CATALOG)
51 zcat = None
52 if zcat is None:
53 manage_addZCatalog(dmd, RRDTEMPLATE_CATALOG, RRDTEMPLATE_CATALOG)
54 zcat = dmd._getOb(RRDTEMPLATE_CATALOG)
55 cat = zcat._catalog
56 cat.addIndex('id', makeCaseSensitiveFieldIndex('id'))
57 cat.addIndex('getPhysicalPath', makePathIndex('getPhysicalPath'))
58 return zcat
59
60
62 """
63 Yield all templates in the searchRRDTemplates catalog which fall under
64 the given root and match the given criteria. To get all RRDTemplates
65 pass dmd in as root. If criteria contains a
66 value for getPhysicalRoot then the root parameter will be ignored.
67
68 If the searchRRDTemplates catalog is not present then fall back to using
69 DeviceClass.getAllRRDTemplatesPainfully(). In this case root must
70 be a DeviceClass and criteria is ignored. (This is compatible with
71 previous DeviceClass.getAllRRDTemplates usage.)
72
73 The searchRRDTemplates catalog was added in 2.2
74 """
75 zcat = getattr(root, RRDTEMPLATE_CATALOG, None)
76 if zcat is not None:
77 criteria = criteria or {}
78 criteria.setdefault('getPhysicalPath', root.getPrimaryId())
79 brains = zcat(criteria)
80 for result in brains:
81 yield result.getObject()
82 else:
83 for t in root.getAllRRDTemplatesPainfully():
84 yield t
85
86
88 """make a RRDTemplate"""
89 tt = RRDTemplate(id)
90 context._setObject(tt.id, tt)
91 if REQUEST is not None:
92 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
93
94
95 addRRDTemplate = DTMLFile('dtml/addRRDTemplate',globals())
96
97
102
103
105
106 implements(IIndexed)
107 meta_type = 'RRDTemplate'
108
109 default_catalog = RRDTEMPLATE_CATALOG
110
111 security = ClassSecurityInfo()
112
113 description = ""
114 targetPythonClass = "Products.ZenModel.Device"
115
116 _properties = (
117 {'id':'description', 'type':'text', 'mode':'w'},
118 {'id':'targetPythonClass', 'type':'string', 'mode':'w'},
119 )
120
121 # The graphs relationship can be removed post 2.1. It is needed
122 # by the graphDefinitionAndFriends migrate script for 2.1
123
124 _relations = ZenPackable._relations + (
125 ("deviceClass", ToOne(
126 ToManyCont,"Products.ZenModel.TemplateContainer", "rrdTemplates")),
127 ("datasources", ToManyCont(
128 ToOne,"Products.ZenModel.RRDDataSource", "rrdTemplate")),
129 ("graphs", ToManyCont(
130 ToOne,"Products.ZenModel.RRDGraph", "rrdTemplate")),
131 ("thresholds", ToManyCont(
132 ToOne,"Products.ZenModel.ThresholdClass", "rrdTemplate")),
133 ("graphDefs", ToManyCont(
134 ToOne,"Products.ZenModel.GraphDefinition", "rrdTemplate")),
135 )
136
137
138 # Screen action bindings (and tab definitions)
139 factory_type_information = (
140 {
141 'immediate_view' : 'viewRRDTemplate',
142 'actions' :
143 (
144 { 'id' : 'overview'
145 , 'name' : 'Performance Template'
146 , 'action' : 'viewRRDTemplate'
147 , 'permissions' : ( Permissions.view, )
148 },
149 )
150 },
151 )
152
154 """Return the breadcrumb links for this object add ActionRules list.
155 [('url','id'), ...]
156 """
157 crumbs = super(RRDTemplate, self).breadCrumbs(terminator)
158 return crumbspath(self, crumbs)
159
160
162 """Is this template editable in context.
163 """
164 return ((context == self or context.isLocalName(self.id))
165 and self.checkRemotePerm(ZEN_CHANGE_DEVICE, self))
166
167
169 ''' Return an ordered list of the graph definitions
170 '''
171 def cmpGraphDefs(a, b):
172 try: a = int(a.sequence)
173 except ValueError: a = sys.maxint
174 try: b = int(b.sequence)
175 except ValueError: b = sys.maxint
176 return cmp(a, b)
177 graphDefs = [g for g in self.graphDefs()]
178 graphDefs.sort(cmpGraphDefs)
179 return graphDefs
180
181
183 """Return the path on which this template is defined.
184 """
185 return self.getPrimaryParent().getPrimaryDmdId(subrel="rrdTemplates")
186
187
189 ''' Return a list of names of graphable thresholds
190 '''
191 return [t for t in self.thresholds()]
192
193
195 """Return the list of all datapoint names.
196 """
197 # We check for the presence of datapoints on the datasources
198 # to better handle situation where the datasource is broken
199 # (usually because of a missing zenpack.)
200 datasources = [ds for ds in self.datasources()
201 if hasattr(ds, 'datapoints')]
202 return [dp.name() for ds in datasources for dp in ds.datapoints()]
203
204
206 """Return a list of all datapoints on this template.
207 """
208 if dsType is None: return self.datasources()
209 return [ds for ds in self.datasources()
210 if ds.sourcetype == dsType
211 or (dsType=='COMMAND' and ds.useZenCommand())]
212
213
215 """Return a list of all datapoints on this template.
216 """
217 result = []
218 for s in self.datasources():
219 result.extend(s.datapoints())
220 return result
221
222
224 """Return a datapoint based on its name.
225 """
226 source = name
227 point = name
228 if name.find(SEPARATOR) >= 0:
229 source, point = name.split(SEPARATOR, 1)
230 ds = self.datasources._getOb(source, None)
231 if ds is None:
232 results = []
233 for ds in self.datasources():
234 for dp in ds.datapoints():
235 if dp.name() == name:
236 results.append(dp)
237 if len(results) == 1:
238 return results[0]
239 else:
240 return ds.datapoints._getOb(point)
241 raise ConfigurationError('Unknown data point "%s"' % name)
242
243
244 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
246 """Add an RRDDataSource to this DeviceClass.
247 """
248 ds = None
249 if id and dsOption:
250 ds = self.getDataSourceInstance(id, dsOption)
251 self.datasources._setObject(ds.id, ds)
252 ds = self.datasources._getOb(ds.id)
253 if ds:
254 ds.addDataPoints()
255 if REQUEST:
256 if ds:
257 messaging.IMessageSender(self).sendToBrowser(
258 'Datasource Added',
259 "Data source %s added" % ds.id
260 )
261 url = '%s/datasources/%s' % (self.getPrimaryUrlPath(), ds.id)
262 return REQUEST['RESPONSE'].redirect(url)
263 else:
264 return self.callZenScreen(REQUEST)
265 return ds
266
267
269 """
270 Returns the python class object that this template can be bound to.
271 """
272 from Products.ZenModel.Device import Device
273 cname = getattr(self, "targetPythonClass", None)
274 if cname:
275 try:
276 return importClass(cname)
277 except ImportError:
278 log.exception("Unable to import class " + cname)
279 return Device
280
281
282 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDDataSources')
284 """Delete RRDDataSources from this DeviceClass
285 """
286 def clean(rel, id):
287 for obj in rel():
288 if id in obj.dsnames:
289 obj.dsnames.remove(id)
290 if not obj.dsnames:
291 rel._delObject(obj.id)
292
293 if not ids: return self.callZenScreen(REQUEST)
294 for id in ids:
295 self._p_changed = True
296 if getattr(self.datasources,id,False):
297 if getattr(self, 'device', False):
298 perfConf = self.device().getPerformanceServer()
299 if perfConf:
300 perfConf.deleteRRDFiles(device=self.device().id,
301 datasource=id)
302 else:
303 for d in self.deviceClass.obj.getSubDevicesGen():
304 perfConf = d.getPerformanceServer()
305 if perfConf:
306 perfConf.deleteRRDFiles(device=d, datasource=id)
307
308 self.datasources._delObject(id)
309 clean(self.graphs, id)
310 clean(self.thresholds, id)
311
312 if REQUEST:
313 messaging.IMessageSender(self).sendToBrowser(
314 'Datasources Deleted',
315 'Datasource%s %s deleted.' % ('' if len(ids)==1 else 's',
316 ', '.join(ids))
317 )
318 return self.callZenScreen(REQUEST)
319
320
321 security.declareProtected('Add DMD Objects', 'manage_addRRDThreshold')
323 """Add an RRDThreshold to this DeviceClass.
324 """
325 if not id: return self.callZenScreen(REQUEST)
326 org = self.getThresholdClass(id, thresholdClassName)
327 self.thresholds._setObject(org.id, org)
328 org = self.thresholds._getOb(org.id)
329 if REQUEST:
330 if org:
331 messaging.IMessageSender(self).sendToBrowser(
332 'Threshold Added',
333 'Threshold "%s" added' % org.id
334 )
335 url = '%s/thresholds/%s' % (self.getPrimaryUrlPath(), org.id)
336 return REQUEST['RESPONSE'].redirect(url)
337 else:
338 return self.callZenScreen(REQUEST)
339 return org
340
341
342 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
344 """Delete RRDThresholds from this DeviceClass
345 """
346 if not ids: return self.callZenScreen(REQUEST)
347 for id in ids:
348 if getattr(self.thresholds,id,False):
349 self.thresholds._delObject(id)
350 if REQUEST:
351 messaging.IMessageSender(self).sendToBrowser(
352 'Thresholds Deleted',
353 'Threshold%s %s deleted.' % ('' if len(ids)==1 else 's',
354 ', '.join(ids))
355 )
356 return self.callZenScreen(REQUEST)
357
358
359 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
361 """Add a GraphDefinition to our RRDTemplate.
362 """
363 from GraphDefinition import GraphDefinition
364 self.getGraphDefs()
365 graph = None
366 graph = GraphDefinition(new_id)
367 graph.sequence = len(self.graphDefs())
368 self.graphDefs._setObject(graph.id, graph)
369 graph = self.graphDefs._getOb(graph.id)
370 if REQUEST:
371 messaging.IMessageSender(self).sendToBrowser(
372 'Graph Added',
373 'Graph "%s" added' % graph.id
374 )
375 url = '%s/graphDefs/%s' % (self.getPrimaryUrlPath(), graph.id)
376 return REQUEST['RESPONSE'].redirect(url)
377 return graph
378
379
380 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
382 """Remove GraphDefinitions from this RRDTemplate.
383 """
384 for id in ids:
385 self.graphDefs._delObject(id)
386 self.manage_resequenceGraphDefs()
387 if REQUEST:
388 messaging.IMessageSender(self).sendToBrowser(
389 'Graphs Deleted',
390 'Graph%s %s deleted.' % ('' if len(ids)==1 else 's',
391 ', '.join(ids))
392 )
393 return self.callZenScreen(REQUEST)
394
395
396 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
398 """Reorder the sequence of the GraphDefinitions.
399 """
400 from Products.ZenUtils.Utils import resequence
401 return resequence(self, self.getGraphDefs(),
402 seqmap, origseq, REQUEST)
403
404
405 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
407 """
408 Create GraphPoints for all datapoints in the given datasources (ids)
409 in each of the graphDefs (graphIds.)
410 If a graphpoint already exists for a datapoint in a graphDef then
411 don't create a 2nd one.
412 """
413 newGraphPoints = []
414 for dsId in ids:
415 ds = self.datasources._getOb(dsId, None)
416 if ds:
417 newGraphPoints += ds.manage_addDataPointsToGraphs(
418 [dp.id for dp in ds.datapoints()],
419 graphIds)
420 numAdded = len(newGraphPoints)
421 if REQUEST:
422 messaging.IMessageSender(self).sendToBrowser(
423 'Graph Points Added',
424 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
425 )
426 return self.callZenScreen(REQUEST)
427 return newGraphPoints
428
429
430 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
432 """
433 Create GraphPoints for all given thresholds that are not already
434 graphed. in the given datasources (ids)
435 """
436 newGps = []
437 for graphId in graphIds:
438 graphDef = self.graphDefs._getOb(graphId, None)
439 if graphDef:
440 for threshId in ids:
441 thresh = self.thresholds._getOb(threshId, None)
442 if thresh and not graphDef.isThresholdGraphed(thresh.id):
443 newGps += graphDef.manage_addThresholdGraphPoints(
444 [thresh.id])
445 if REQUEST:
446 numAdded = len(newGps)
447 messaging.IMessageSender(self).sendToBrowser(
448 'Graph Points Added',
449 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
450 )
451 return self.callZenScreen(REQUEST)
452 return newGps
453
454
456 dsClasses = [BasicDataSource, BuiltInDS]
457 for zp in self.dmd.ZenPackManager.packs():
458 dsClasses += zp.getDataSourceClasses()
459 return dsClasses
460
461
463 ''' Returns a list of the available datasource options as a list
464 of (display name, dsOption)
465 '''
466 dsTypes = []
467 for dsClass in self.getDataSourceClasses():
468 dsTypes += [(t, '%s.%s' % (dsClass.__name__, t))
469 for t in dsClass.sourcetypes]
470 return dsTypes
471
472
474 ''' Given one of the dsOptions returned by getDataSourceOptions)
475 return an instance of the that RRDDataSource subclass.
476 '''
477 dsClassName, dsType = dsOption.split('.')
478 for c in self.getDataSourceClasses():
479 if dsClassName == c.__name__:
480 ds = c(id)
481 ds.sourcetype = dsType
482 break
483 else:
484 raise ConfigurationError('Cannot find datasource class'
485 ' for %s' % dsOption)
486 return ds
487
488
490 from Products.ZenModel.MinMaxThreshold import MinMaxThreshold
491 thresholdClasses = [MinMaxThreshold]
492 for zp in self.dmd.ZenPackManager.packs():
493 thresholdClasses += zp.getThresholdClasses()
494 return map(lambda x: (x, x.__name__), thresholdClasses)
495
496
498 ''' Given one of the dsOptions returned by getDataSourceOptions)
499 return an instance of the that RRDDataSource subclass.
500 '''
501 for c, name in self.getThresholdClasses():
502 if thresholdClassName == c.__name__:
503 return c(id)
504 raise ConfigurationError('Cannot find threshold class %s' %
505 thresholdClassName)
506
507
509 """
510 Get a list of all event class names within the permission scope.
511 """
512 return self.primaryAq().Events.getOrganizerNames()
513
514
516 """
517 Given a separator and a template this method returns the UI path that we display
518 to the user.
519 @param RRDTemplate template
520 @param String separator e.g. '/'
521 @returns String e.g. '/Devices' or '/Server'
522 """
523 obj = self.deviceClass()
524 if obj is None:
525 # this template is in a Device
526 obj = aq_parent(self)
527 path = list(obj.getPrimaryPath())
528 # remove the "devices" relationship
529 path.pop(-2)
530 else:
531 # this template is in a DeviceClass.rrdTemplates relationship
532 path = list(obj.getPrimaryPath())
533 parts = path[4:-1]
534 parts.append(obj.titleOrId())
535 return separator + separator.join(parts)
536
537
538 InitializeClass(RRDTemplate)
539
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Wed Jul 14 12:01:48 2010 | http://epydoc.sourceforge.net |