| Trees | Indices | Help |
|
|---|
|
|
1 ##############################################################################
2 #
3 # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
4 #
5 # This content is made available according to terms specified in
6 # License.zenoss under the directory where your Zenoss product is installed.
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
39 """
40 Create the searchRRDTemplates catalog if it does not already exist.
41 Return the catalog.
42 """
43 from Products.ZCatalog.ZCatalog import manage_addZCatalog
44 from Products.ZenUtils.Search import makeCaseSensitiveFieldIndex, \
45 makePathIndex
46 zcat = getattr(dmd, RRDTEMPLATE_CATALOG, None)
47 if zcat and rebuild:
48 dmd._delObject(RRDTEMPLATE_CATALOG)
49 zcat = None
50 if zcat is None:
51 manage_addZCatalog(dmd, RRDTEMPLATE_CATALOG, RRDTEMPLATE_CATALOG)
52 zcat = dmd._getOb(RRDTEMPLATE_CATALOG)
53 cat = zcat._catalog
54 cat.addIndex('id', makeCaseSensitiveFieldIndex('id'))
55 cat.addIndex('getPhysicalPath', makePathIndex('getPhysicalPath'))
56 return zcat
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
86 """make a RRDTemplate"""
87 tt = RRDTemplate(id)
88 context._setObject(tt.id, tt)
89 if REQUEST is not None:
90 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
91
92
93 addRRDTemplate = DTMLFile('dtml/addRRDTemplate',globals())
94
95
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 # The graphs relationship can be removed post 2.1. It is needed
120 # by the graphDefinitionAndFriends migrate script for 2.1
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 # Screen action bindings (and tab definitions)
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
160 """Is this template editable in context.
161 """
162 return ((context == self or context.isLocalName(self.id))
163 and self.checkRemotePerm(ZEN_CHANGE_DEVICE, self))
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
178 """Return the path on which this template is defined.
179 """
180 return self.getPrimaryParent().getPrimaryDmdId(subrel="rrdTemplates")
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 # We check for the presence of datapoints on the datasources
193 # to better handle situation where the datasource is broken
194 # (usually because of a missing zenpack.)
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
201 """Return a list of all datapoints on this template.
202 """
203 if dsType is None: return self.datasources()
204 return [ds for ds in self.datasources()
205 if ds.sourcetype == dsType
206 or (dsType=='COMMAND' and ds.useZenCommand())]
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
219 """Return a datapoint based on its name.
220 """
221 source = name
222 point = name
223 if name.find(SEPARATOR) >= 0:
224 source, point = name.split(SEPARATOR, 1)
225 ds = self.datasources._getOb(source, None)
226 if ds is None:
227 results = []
228 for ds in self.datasources():
229 for dp in ds.datapoints():
230 if dp.name() == name:
231 results.append(dp)
232 if len(results) == 1:
233 return results[0]
234 else:
235 return ds.datapoints._getOb(point)
236 raise ConfigurationError('Unknown data point "%s"' % name)
237
238
239 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
241 """Add an RRDDataSource to this DeviceClass.
242 """
243 ds = None
244 if id and dsOption:
245 ds = self.getDataSourceInstance(id, dsOption)
246 self.datasources._setObject(ds.id, ds)
247 ds = self.datasources._getOb(ds.id)
248 if ds:
249 ds.addDataPoints()
250 if REQUEST:
251 if ds:
252 messaging.IMessageSender(self).sendToBrowser(
253 'Datasource Added',
254 "Data source %s added" % ds.id
255 )
256 url = '%s/datasources/%s' % (self.getPrimaryUrlPath(), ds.id)
257 return REQUEST['RESPONSE'].redirect(url)
258 else:
259 return self.callZenScreen(REQUEST)
260 return ds
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')
279 """Delete RRDDataSources from this DeviceClass
280 """
281 def clean(rel, id):
282 for obj in rel():
283 if id in obj.dsnames:
284 obj.dsnames.remove(id)
285 if not obj.dsnames:
286 rel._delObject(obj.id)
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')
318 """Add an RRDThreshold to this DeviceClass.
319 """
320 if not id: return self.callZenScreen(REQUEST)
321 org = self.getThresholdClass(id, thresholdClassName)
322 self.thresholds._setObject(org.id, org)
323 org = self.thresholds._getOb(org.id)
324 if REQUEST:
325 if org:
326 messaging.IMessageSender(self).sendToBrowser(
327 'Threshold Added',
328 'Threshold "%s" added' % org.id
329 )
330 url = '%s/thresholds/%s' % (self.getPrimaryUrlPath(), org.id)
331 return REQUEST['RESPONSE'].redirect(url)
332 else:
333 return self.callZenScreen(REQUEST)
334 return org
335
336
337 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
339 """Delete RRDThresholds from this DeviceClass
340 """
341 if not ids: return self.callZenScreen(REQUEST)
342 for id in ids:
343 if getattr(self.thresholds,id,False):
344 self.thresholds._delObject(id)
345 if REQUEST:
346 messaging.IMessageSender(self).sendToBrowser(
347 'Thresholds Deleted',
348 'Threshold%s %s deleted.' % ('' if len(ids)==1 else 's',
349 ', '.join(ids))
350 )
351 return self.callZenScreen(REQUEST)
352
353
354 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
356 """Add a GraphDefinition to our RRDTemplate.
357 """
358 from GraphDefinition import GraphDefinition
359 self.getGraphDefs()
360 graph = None
361 graph = GraphDefinition(new_id)
362 graph.sequence = len(self.graphDefs())
363 self.graphDefs._setObject(graph.id, graph)
364 graph = self.graphDefs._getOb(graph.id)
365 if REQUEST:
366 messaging.IMessageSender(self).sendToBrowser(
367 'Graph Added',
368 'Graph "%s" added' % graph.id
369 )
370 url = '%s/graphDefs/%s' % (self.getPrimaryUrlPath(), graph.id)
371 return REQUEST['RESPONSE'].redirect(url)
372 return graph
373
374
375 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
377 """Remove GraphDefinitions from this RRDTemplate.
378 """
379 for id in ids:
380 self.graphDefs._delObject(id)
381 self.manage_resequenceGraphDefs()
382 if REQUEST:
383 messaging.IMessageSender(self).sendToBrowser(
384 'Graphs Deleted',
385 'Graph%s %s deleted.' % ('' if len(ids)==1 else 's',
386 ', '.join(ids))
387 )
388 return self.callZenScreen(REQUEST)
389
390
391 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
393 """Reorder the sequence of the GraphDefinitions.
394 """
395 from Products.ZenUtils.Utils import resequence
396 return resequence(self, self.getGraphDefs(),
397 seqmap, origseq, REQUEST)
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')
427 """
428 Create GraphPoints for all given thresholds that are not already
429 graphed. in the given datasources (ids)
430 """
431 newGps = []
432 for graphId in graphIds:
433 graphDef = self.graphDefs._getOb(graphId, None)
434 if graphDef:
435 for threshId in ids:
436 thresh = self.thresholds._getOb(threshId, None)
437 if thresh and not graphDef.isThresholdGraphed(thresh.id):
438 newGps += graphDef.manage_addThresholdGraphPoints(
439 [thresh.id])
440 if REQUEST:
441 numAdded = len(newGps)
442 messaging.IMessageSender(self).sendToBrowser(
443 'Graph Points Added',
444 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
445 )
446 return self.callZenScreen(REQUEST)
447 return newGps
448
449
451 dsClasses = [BasicDataSource, BuiltInDS, PingDataSource]
452 for zp in self.dmd.ZenPackManager.packs():
453 dsClasses += zp.getDataSourceClasses()
454 return dsClasses
455
456
458 ''' Returns a list of the available datasource options as a list
459 of (display name, dsOption)
460 '''
461 dsTypes = []
462 for dsClass in self.getDataSourceClasses():
463 dsTypes += [(t, '%s.%s' % (dsClass.__name__, t))
464 for t in dsClass.sourcetypes]
465 return dsTypes
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
485 from Products.ZenModel.MinMaxThreshold import MinMaxThreshold
486 from Products.ZenModel.ValueChangeThreshold import ValueChangeThreshold
487 thresholdClasses = [MinMaxThreshold, ValueChangeThreshold]
488 for zp in self.dmd.ZenPackManager.packs():
489 thresholdClasses += zp.getThresholdClasses()
490 return map(lambda x: (x, x.__name__), thresholdClasses)
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 # this template is in a Device
522 obj = aq_parent(self)
523 path = list(obj.getPrimaryPath())
524 # remove the "devices" relationship
525 path.pop(-2)
526 else:
527 # this template is in a DeviceClass.rrdTemplates relationship
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
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Mon Jul 30 17:11:20 2012 | http://epydoc.sourceforge.net |