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.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
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
93
94
95 addRRDTemplate = DTMLFile('dtml/addRRDTemplate',globals())
96
97
99 """Create the crumbs path for sub objects of an RRDTemplate.
100 """
101 return crumbs
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
122
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
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
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
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
198
199
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
242
243
244 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
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')
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')
340
341
342 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
357
358
359 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
378
379
380 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
394
395
396 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
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')
453
454
460
461
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
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
526 obj = aq_parent(self)
527 path = list(obj.getPrimaryPath())
528
529 path.pop(-2)
530 else:
531
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