1
2
3
4
5
6
7
8
9
10
11 import sys
12 from Globals import DTMLFile
13 from Globals import InitializeClass
14 from AccessControl import ClassSecurityInfo, Permissions
15 from Products.ZenModel.ZenossSecurity import *
16 from zope.interface import implements
17 from Acquisition import aq_parent
18 from ZenModelRM import ZenModelRM
19 from Products.ZenModel.interfaces import IIndexed
20
21 from Products.ZenRelations.RelSchema import *
22 from Products.ZenModel.RRDDataSource import SimpleRRDDataSource
23 from Products.ZenModel.BasicDataSource import BasicDataSource
24 from Products.ZenModel.BuiltInDS import BuiltInDS
25 from Products.ZenModel.PingDataSource import PingDataSource
26 from Products.ZenModel.ConfigurationError import ConfigurationError
27 from Products.ZenUtils.Utils import importClass
28 from Products.ZenWidgets import messaging
29 from RRDDataPoint import SEPARATOR
30 from ZenPackable import ZenPackable
31
32 import logging
33 log = logging.getLogger('zen.RRDTemplate')
34
35 RRDTEMPLATE_CATALOG = 'searchRRDTemplates'
36
37
57
58
60 """
61 Yield all templates in the searchRRDTemplates catalog which fall under
62 the given root and match the given criteria. To get all RRDTemplates
63 pass dmd in as root. If criteria contains a
64 value for getPhysicalRoot then the root parameter will be ignored.
65
66 If the searchRRDTemplates catalog is not present then fall back to using
67 DeviceClass.getAllRRDTemplatesPainfully(). In this case root must
68 be a DeviceClass and criteria is ignored. (This is compatible with
69 previous DeviceClass.getAllRRDTemplates usage.)
70
71 The searchRRDTemplates catalog was added in 2.2
72 """
73 zcat = getattr(root, RRDTEMPLATE_CATALOG, None)
74 if zcat is not None:
75 criteria = criteria or {}
76 criteria.setdefault('getPhysicalPath', root.getPrimaryId())
77 brains = zcat(criteria)
78 for result in brains:
79 yield result.getObject()
80 else:
81 for t in root.getAllRRDTemplatesPainfully():
82 yield t
83
84
91
92
93 addRRDTemplate = DTMLFile('dtml/addRRDTemplate',globals())
94
95
97 """Create the crumbs path for sub objects of an RRDTemplate.
98 """
99 return crumbs
100
101
103
104 implements(IIndexed)
105 meta_type = 'RRDTemplate'
106
107 default_catalog = RRDTEMPLATE_CATALOG
108
109 security = ClassSecurityInfo()
110
111 description = ""
112 targetPythonClass = "Products.ZenModel.Device"
113
114 _properties = (
115 {'id':'description', 'type':'text', 'mode':'w'},
116 {'id':'targetPythonClass', 'type':'string', 'mode':'w'},
117 )
118
119
120
121
122 _relations = ZenPackable._relations + (
123 ("deviceClass", ToOne(
124 ToManyCont,"Products.ZenModel.TemplateContainer", "rrdTemplates")),
125 ("datasources", ToManyCont(
126 ToOne,"Products.ZenModel.RRDDataSource", "rrdTemplate")),
127 ("graphs", ToManyCont(
128 ToOne,"Products.ZenModel.RRDGraph", "rrdTemplate")),
129 ("thresholds", ToManyCont(
130 ToOne,"Products.ZenModel.ThresholdClass", "rrdTemplate")),
131 ("graphDefs", ToManyCont(
132 ToOne,"Products.ZenModel.GraphDefinition", "rrdTemplate")),
133 )
134
135
136
137 factory_type_information = (
138 {
139 'immediate_view' : 'viewRRDTemplate',
140 'actions' :
141 (
142 { 'id' : 'overview'
143 , 'name' : 'Performance Template'
144 , 'action' : 'viewRRDTemplate'
145 , 'permissions' : ( Permissions.view, )
146 },
147 )
148 },
149 )
150
152 """Return the breadcrumb links for this object add ActionRules list.
153 [('url','id'), ...]
154 """
155 crumbs = super(RRDTemplate, self).breadCrumbs(terminator)
156 return crumbspath(self, crumbs)
157
158
164
165
167 ''' Return an ordered list of the graph definitions
168 '''
169 def graphDefSortKey(a):
170 try:
171 return int(a.sequence)
172 except ValueError:
173 return sys.maxint
174 return sorted(self.graphDefs(), key=graphDefSortKey)
175
176
181
182
184 ''' Return a list of names of graphable thresholds
185 '''
186 return [t for t in self.thresholds()]
187
188
190 """Return the list of all datapoint names.
191 """
192
193
194
195 datasources = [ds for ds in self.datasources()
196 if hasattr(ds, 'datapoints')]
197 return [dp.name() for ds in datasources for dp in ds.datapoints()]
198
199
207
208
210 """Return a list of all datapoints on this template.
211 """
212 result = []
213 for s in self.datasources():
214 result.extend(s.datapoints())
215 return result
216
217
237
238
239 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
261
262
264 """
265 Returns the python class object that this template can be bound to.
266 """
267 from Products.ZenModel.Device import Device
268 cname = getattr(self, "targetPythonClass", None)
269 if cname:
270 try:
271 return importClass(cname)
272 except ImportError:
273 log.exception("Unable to import class " + cname)
274 return Device
275
276
277 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDDataSources')
287
288 if not ids: return self.callZenScreen(REQUEST)
289 for id in ids:
290 self._p_changed = True
291 if getattr(self.datasources,id,False):
292 if getattr(self, 'device', False):
293 perfConf = self.device().getPerformanceServer()
294 if perfConf:
295 perfConf.deleteRRDFiles(device=self.device().id,
296 datasource=id)
297 else:
298 for d in self.deviceClass.obj.getSubDevicesGen():
299 perfConf = d.getPerformanceServer()
300 if perfConf:
301 perfConf.deleteRRDFiles(device=d, datasource=id)
302
303 self.datasources._delObject(id)
304 clean(self.graphs, id)
305 clean(self.thresholds, id)
306
307 if REQUEST:
308 messaging.IMessageSender(self).sendToBrowser(
309 'Datasources Deleted',
310 'Datasource%s %s deleted.' % ('' if len(ids)==1 else 's',
311 ', '.join(ids))
312 )
313 return self.callZenScreen(REQUEST)
314
315
316 security.declareProtected('Add DMD Objects', 'manage_addRRDThreshold')
335
336
337 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
352
353
354 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
373
374
375 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
389
390
391 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
398
399
400 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
402 """
403 Create GraphPoints for all datapoints in the given datasources (ids)
404 in each of the graphDefs (graphIds.)
405 If a graphpoint already exists for a datapoint in a graphDef then
406 don't create a 2nd one.
407 """
408 newGraphPoints = []
409 for dsId in ids:
410 ds = self.datasources._getOb(dsId, None)
411 if ds:
412 newGraphPoints += ds.manage_addDataPointsToGraphs(
413 [dp.id for dp in ds.datapoints()],
414 graphIds)
415 numAdded = len(newGraphPoints)
416 if REQUEST:
417 messaging.IMessageSender(self).sendToBrowser(
418 'Graph Points Added',
419 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
420 )
421 return self.callZenScreen(REQUEST)
422 return newGraphPoints
423
424
425 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
448
449
455
456
466
467
469 ''' Given one of the dsOptions returned by getDataSourceOptions)
470 return an instance of the that RRDDataSource subclass.
471 '''
472 dsClassName, dsType = dsOption.split('.')
473 for c in self.getDataSourceClasses():
474 if dsClassName == c.__name__:
475 ds = c(id)
476 ds.sourcetype = dsType
477 break
478 else:
479 raise ConfigurationError('Cannot find datasource class'
480 ' for %s' % dsOption)
481 return ds
482
483
491
492
494 ''' Given one of the dsOptions returned by getDataSourceOptions)
495 return an instance of the that RRDDataSource subclass.
496 '''
497 for c, name in self.getThresholdClasses():
498 if thresholdClassName == c.__name__:
499 return c(id)
500 raise ConfigurationError('Cannot find threshold class %s' %
501 thresholdClassName)
502
503
505 """
506 Get a list of all event class names within the permission scope.
507 """
508 return self.primaryAq().Events.getOrganizerNames()
509
510
512 """
513 Given a separator and a template this method returns the UI path that we display
514 to the user.
515 @param RRDTemplate template
516 @param String separator e.g. '/'
517 @returns String e.g. '/Devices' or '/Server'
518 """
519 obj = self.deviceClass()
520 if obj is None:
521
522 obj = aq_parent(self)
523 path = list(obj.getPrimaryPath())
524
525 path.pop(-2)
526 else:
527
528 path = list(obj.getPrimaryPath())
529 parts = path[4:-1]
530 parts.append(obj.titleOrId())
531 return separator + separator.join(parts)
532
533
534 InitializeClass(RRDTemplate)
535