1
2
3
4
5
6
7
8
9
10
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.PingDataSource import PingDataSource
29 from Products.ZenModel.ConfigurationError import ConfigurationError
30 from Products.ZenUtils.Utils import importClass
31 from Products.ZenWidgets import messaging
32 from RRDDataPoint import SEPARATOR
33 from ZenPackable import ZenPackable
34
35 import logging
36 log = logging.getLogger('zen.RRDTemplate')
37
38 RRDTEMPLATE_CATALOG = 'searchRRDTemplates'
39
40
60
61
63 """
64 Yield all templates in the searchRRDTemplates catalog which fall under
65 the given root and match the given criteria. To get all RRDTemplates
66 pass dmd in as root. If criteria contains a
67 value for getPhysicalRoot then the root parameter will be ignored.
68
69 If the searchRRDTemplates catalog is not present then fall back to using
70 DeviceClass.getAllRRDTemplatesPainfully(). In this case root must
71 be a DeviceClass and criteria is ignored. (This is compatible with
72 previous DeviceClass.getAllRRDTemplates usage.)
73
74 The searchRRDTemplates catalog was added in 2.2
75 """
76 zcat = getattr(root, RRDTEMPLATE_CATALOG, None)
77 if zcat is not None:
78 criteria = criteria or {}
79 criteria.setdefault('getPhysicalPath', root.getPrimaryId())
80 brains = zcat(criteria)
81 for result in brains:
82 yield result.getObject()
83 else:
84 for t in root.getAllRRDTemplatesPainfully():
85 yield t
86
87
94
95
96 addRRDTemplate = DTMLFile('dtml/addRRDTemplate',globals())
97
98
100 """Create the crumbs path for sub objects of an RRDTemplate.
101 """
102 return crumbs
103
104
106
107 implements(IIndexed)
108 meta_type = 'RRDTemplate'
109
110 default_catalog = RRDTEMPLATE_CATALOG
111
112 security = ClassSecurityInfo()
113
114 description = ""
115 targetPythonClass = "Products.ZenModel.Device"
116
117 _properties = (
118 {'id':'description', 'type':'text', 'mode':'w'},
119 {'id':'targetPythonClass', 'type':'string', 'mode':'w'},
120 )
121
122
123
124
125 _relations = ZenPackable._relations + (
126 ("deviceClass", ToOne(
127 ToManyCont,"Products.ZenModel.TemplateContainer", "rrdTemplates")),
128 ("datasources", ToManyCont(
129 ToOne,"Products.ZenModel.RRDDataSource", "rrdTemplate")),
130 ("graphs", ToManyCont(
131 ToOne,"Products.ZenModel.RRDGraph", "rrdTemplate")),
132 ("thresholds", ToManyCont(
133 ToOne,"Products.ZenModel.ThresholdClass", "rrdTemplate")),
134 ("graphDefs", ToManyCont(
135 ToOne,"Products.ZenModel.GraphDefinition", "rrdTemplate")),
136 )
137
138
139
140 factory_type_information = (
141 {
142 'immediate_view' : 'viewRRDTemplate',
143 'actions' :
144 (
145 { 'id' : 'overview'
146 , 'name' : 'Performance Template'
147 , 'action' : 'viewRRDTemplate'
148 , 'permissions' : ( Permissions.view, )
149 },
150 )
151 },
152 )
153
155 """Return the breadcrumb links for this object add ActionRules list.
156 [('url','id'), ...]
157 """
158 crumbs = super(RRDTemplate, self).breadCrumbs(terminator)
159 return crumbspath(self, crumbs)
160
161
167
168
170 ''' Return an ordered list of the graph definitions
171 '''
172 def cmpGraphDefs(a, b):
173 try: a = int(a.sequence)
174 except ValueError: a = sys.maxint
175 try: b = int(b.sequence)
176 except ValueError: b = sys.maxint
177 return cmp(a, b)
178 graphDefs = [g for g in self.graphDefs()]
179 graphDefs.sort(cmpGraphDefs)
180 return graphDefs
181
182
187
188
190 ''' Return a list of names of graphable thresholds
191 '''
192 return [t for t in self.thresholds()]
193
194
196 """Return the list of all datapoint names.
197 """
198
199
200
201 datasources = [ds for ds in self.datasources()
202 if hasattr(ds, 'datapoints')]
203 return [dp.name() for ds in datasources for dp in ds.datapoints()]
204
205
213
214
216 """Return a list of all datapoints on this template.
217 """
218 result = []
219 for s in self.datasources():
220 result.extend(s.datapoints())
221 return result
222
223
243
244
245 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
267
268
270 """
271 Returns the python class object that this template can be bound to.
272 """
273 from Products.ZenModel.Device import Device
274 cname = getattr(self, "targetPythonClass", None)
275 if cname:
276 try:
277 return importClass(cname)
278 except ImportError:
279 log.exception("Unable to import class " + cname)
280 return Device
281
282
283 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDDataSources')
293
294 if not ids: return self.callZenScreen(REQUEST)
295 for id in ids:
296 self._p_changed = True
297 if getattr(self.datasources,id,False):
298 if getattr(self, 'device', False):
299 perfConf = self.device().getPerformanceServer()
300 if perfConf:
301 perfConf.deleteRRDFiles(device=self.device().id,
302 datasource=id)
303 else:
304 for d in self.deviceClass.obj.getSubDevicesGen():
305 perfConf = d.getPerformanceServer()
306 if perfConf:
307 perfConf.deleteRRDFiles(device=d, datasource=id)
308
309 self.datasources._delObject(id)
310 clean(self.graphs, id)
311 clean(self.thresholds, id)
312
313 if REQUEST:
314 messaging.IMessageSender(self).sendToBrowser(
315 'Datasources Deleted',
316 'Datasource%s %s deleted.' % ('' if len(ids)==1 else 's',
317 ', '.join(ids))
318 )
319 return self.callZenScreen(REQUEST)
320
321
322 security.declareProtected('Add DMD Objects', 'manage_addRRDThreshold')
341
342
343 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
358
359
360 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
379
380
381 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
395
396
397 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
404
405
406 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
408 """
409 Create GraphPoints for all datapoints in the given datasources (ids)
410 in each of the graphDefs (graphIds.)
411 If a graphpoint already exists for a datapoint in a graphDef then
412 don't create a 2nd one.
413 """
414 newGraphPoints = []
415 for dsId in ids:
416 ds = self.datasources._getOb(dsId, None)
417 if ds:
418 newGraphPoints += ds.manage_addDataPointsToGraphs(
419 [dp.id for dp in ds.datapoints()],
420 graphIds)
421 numAdded = len(newGraphPoints)
422 if REQUEST:
423 messaging.IMessageSender(self).sendToBrowser(
424 'Graph Points Added',
425 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
426 )
427 return self.callZenScreen(REQUEST)
428 return newGraphPoints
429
430
431 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
454
455
461
462
472
473
475 ''' Given one of the dsOptions returned by getDataSourceOptions)
476 return an instance of the that RRDDataSource subclass.
477 '''
478 dsClassName, dsType = dsOption.split('.')
479 for c in self.getDataSourceClasses():
480 if dsClassName == c.__name__:
481 ds = c(id)
482 ds.sourcetype = dsType
483 break
484 else:
485 raise ConfigurationError('Cannot find datasource class'
486 ' for %s' % dsOption)
487 return ds
488
489
496
497
499 ''' Given one of the dsOptions returned by getDataSourceOptions)
500 return an instance of the that RRDDataSource subclass.
501 '''
502 for c, name in self.getThresholdClasses():
503 if thresholdClassName == c.__name__:
504 return c(id)
505 raise ConfigurationError('Cannot find threshold class %s' %
506 thresholdClassName)
507
508
510 """
511 Get a list of all event class names within the permission scope.
512 """
513 return self.primaryAq().Events.getOrganizerNames()
514
515
517 """
518 Given a separator and a template this method returns the UI path that we display
519 to the user.
520 @param RRDTemplate template
521 @param String separator e.g. '/'
522 @returns String e.g. '/Devices' or '/Server'
523 """
524 obj = self.deviceClass()
525 if obj is None:
526
527 obj = aq_parent(self)
528 path = list(obj.getPrimaryPath())
529
530 path.pop(-2)
531 else:
532
533 path = list(obj.getPrimaryPath())
534 parts = path[4:-1]
535 parts.append(obj.titleOrId())
536 return separator + separator.join(parts)
537
538
539 InitializeClass(RRDTemplate)
540