| 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 ZEN_MANAGE_DMD
19
20 from ZenModelRM import ZenModelRM
21
22 from Products.ZenRelations.RelSchema import *
23 from Products.ZenModel.RRDDataSource import SimpleRRDDataSource
24 from Products.ZenModel.BasicDataSource import BasicDataSource
25 from Products.ZenModel.BuiltInDS import BuiltInDS
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
97 """Create the crumbs path for sub objects of an RRDTemplate.
98 """
99 dc = templ.deviceClass()
100 if dc:
101 url = '%s/perfConfig' % dc.getPrimaryUrlPath()
102 else:
103 url = '%s/objTemplates' % templ.getPrimaryParent().getPrimaryUrlPath()
104 crumbs.insert(idx,(url,'Templates'))
105 return crumbs
106
107
109
110 meta_type = 'RRDTemplate'
111
112 default_catalog = RRDTEMPLATE_CATALOG
113
114 security = ClassSecurityInfo()
115
116 description = ""
117 targetPythonClass = "Products.ZenModel.Device"
118
119 _properties = (
120 {'id':'description', 'type':'text', 'mode':'w'},
121 {'id':'targetPythonClass', 'type':'string', 'mode':'w'},
122 )
123
124 # The graphs relationship can be removed post 2.1. It is needed
125 # by the graphDefinitionAndFriends migrate script for 2.1
126
127 _relations = ZenPackable._relations + (
128 ("deviceClass", ToOne(
129 ToManyCont,"Products.ZenModel.TemplateContainer", "rrdTemplates")),
130 ("datasources", ToManyCont(
131 ToOne,"Products.ZenModel.RRDDataSource", "rrdTemplate")),
132 ("graphs", ToManyCont(
133 ToOne,"Products.ZenModel.RRDGraph", "rrdTemplate")),
134 ("thresholds", ToManyCont(
135 ToOne,"Products.ZenModel.ThresholdClass", "rrdTemplate")),
136 ("graphDefs", ToManyCont(
137 ToOne,"Products.ZenModel.GraphDefinition", "rrdTemplate")),
138 )
139
140
141 # Screen action bindings (and tab definitions)
142 factory_type_information = (
143 {
144 'immediate_view' : 'viewRRDTemplate',
145 'actions' :
146 (
147 { 'id' : 'overview'
148 , 'name' : 'Performance Template'
149 , 'action' : 'viewRRDTemplate'
150 , 'permissions' : ( Permissions.view, )
151 },
152 )
153 },
154 )
155
157 """Return the breadcrumb links for this object add ActionRules list.
158 [('url','id'), ...]
159 """
160 crumbs = super(RRDTemplate, self).breadCrumbs(terminator)
161 return crumbspath(self, crumbs)
162
163
164 # manage_afterAdd, manage_afterClose and manage_beforeDelete
165 # are the magic methods that make the indexing happen
166
168 """
169 """
170 self.index_object()
171 super(RRDTemplate,self).manage_afterAdd(item, container)
172
173
179
180
182 """
183 """
184 super(RRDTemplate,self).manage_beforeDelete(item, container)
185 self.unindex_object()
186
187
189 """Is this template editable in context.
190 """
191 return ((context == self or context.isLocalName(self.id))
192 and self.isManager(obj=self))
193
194
196 ''' Return an ordered list of the graph definitions
197 '''
198 def cmpGraphDefs(a, b):
199 try: a = int(a.sequence)
200 except ValueError: a = sys.maxint
201 try: b = int(b.sequence)
202 except ValueError: b = sys.maxint
203 return cmp(a, b)
204 graphDefs = [g for g in self.graphDefs()]
205 graphDefs.sort(cmpGraphDefs)
206 return graphDefs
207
208
210 """Return the path on which this template is defined.
211 """
212 return self.getPrimaryParent().getPrimaryDmdId(subrel="rrdTemplates")
213
214
216 ''' Return a list of names of graphable thresholds
217 '''
218 return [t for t in self.thresholds()]
219
220
222 """Return the list of all datapoint names.
223 """
224 # We check for the presence of datapoints on the datasources
225 # to better handle situation where the datasource is broken
226 # (usually because of a missing zenpack.)
227 datasources = [ds for ds in self.datasources()
228 if hasattr(ds, 'datapoints')]
229 return [dp.name() for ds in datasources for dp in ds.datapoints()]
230
231
233 """Return a list of all datapoints on this template.
234 """
235 if dsType is None: return self.datasources()
236 return [ds for ds in self.datasources()
237 if ds.sourcetype == dsType
238 or (dsType=='COMMAND' and ds.useZenCommand())]
239
240
242 """Return a list of all datapoints on this template.
243 """
244 result = []
245 for s in self.datasources():
246 result.extend(s.datapoints())
247 return result
248
249
251 """Return a datapoint based on its name.
252 """
253 source = name
254 point = name
255 if name.find(SEPARATOR) >= 0:
256 source, point = name.split(SEPARATOR, 1)
257 ds = self.datasources._getOb(source, None)
258 if ds is None:
259 results = []
260 for ds in self.datasources():
261 for dp in ds.datapoints():
262 if dp.name() == name:
263 results.append(dp)
264 if len(results) == 1:
265 return results[0]
266 else:
267 return ds.datapoints._getOb(point)
268 raise ConfigurationError('Unknown data point "%s"' % name)
269
270
271 security.declareProtected('Add DMD Objects', 'manage_addRRDDataSource')
273 """Add an RRDDataSource to this DeviceClass.
274 """
275 ds = None
276 if id and dsOption:
277 ds = self.getDataSourceInstance(id, dsOption)
278 self.datasources._setObject(ds.id, ds)
279 ds = self.datasources._getOb(ds.id)
280 if isinstance(ds, SimpleRRDDataSource): ds.addDataPoints()
281 if REQUEST:
282 if ds:
283 messaging.IMessageSender(self).sendToBrowser(
284 'Datasource Added',
285 "Data source %s added" % ds.id
286 )
287 url = '%s/datasources/%s' % (self.getPrimaryUrlPath(), ds.id)
288 return REQUEST['RESPONSE'].redirect(url)
289 else:
290 return self.callZenScreen(REQUEST)
291 return ds
292
293
295 """
296 Returns the python class object that this template can be bound to.
297 """
298 from Products.ZenModel.Device import Device
299 cname = getattr(self, "targetPythonClass", None)
300 if cname:
301 try:
302 return importClass(cname)
303 except ImportError:
304 log.exception("Unable to import class " + cname)
305 return Device
306
307
308 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDDataSources')
310 """Delete RRDDataSources from this DeviceClass
311 """
312 def clean(rel, id):
313 for obj in rel():
314 if id in obj.dsnames:
315 obj.dsnames.remove(id)
316 if not obj.dsnames:
317 rel._delObject(obj.id)
318
319 if not ids: return self.callZenScreen(REQUEST)
320 for id in ids:
321 self._p_changed = True
322 if getattr(self.datasources,id,False):
323 if getattr(self, 'device', False):
324 perfConf = self.device().getPerformanceServer()
325 if perfConf:
326 perfConf.deleteRRDFiles(device=self.device().id,
327 datasource=id)
328 else:
329 for d in self.deviceClass.obj.getSubDevicesGen():
330 perfConf = d.getPerformanceServer()
331 if perfConf:
332 perfConf.deleteRRDFiles(device=d, datasource=id)
333
334 self.datasources._delObject(id)
335 clean(self.graphs, id)
336 clean(self.thresholds, id)
337
338 if REQUEST:
339 messaging.IMessageSender(self).sendToBrowser(
340 'Datasources Deleted',
341 'Datasource%s %s deleted.' % (len(ids)==1 and '' or 's',
342 ', '.join(ids))
343 )
344 return self.callZenScreen(REQUEST)
345
346
347 security.declareProtected('Add DMD Objects', 'manage_addRRDThreshold')
349 """Add an RRDThreshold to this DeviceClass.
350 """
351 if not id: return self.callZenScreen(REQUEST)
352 org = self.getThresholdClass(id, thresholdClassName)
353 self.thresholds._setObject(org.id, org)
354 org = self.thresholds._getOb(org.id)
355 if REQUEST:
356 if org:
357 messaging.IMessageSender(self).sendToBrowser(
358 'Threshold Added',
359 'Threshold "%s" added' % org.id
360 )
361 url = '%s/thresholds/%s' % (self.getPrimaryUrlPath(), org.id)
362 return REQUEST['RESPONSE'].redirect(url)
363 else:
364 return self.callZenScreen(REQUEST)
365 return org
366
367
368 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDThresholds')
370 """Delete RRDThresholds from this DeviceClass
371 """
372 if not ids: return self.callZenScreen(REQUEST)
373 for id in ids:
374 if getattr(self.thresholds,id,False):
375 self.thresholds._delObject(id)
376 if REQUEST:
377 messaging.IMessageSender(self).sendToBrowser(
378 'Thresholds Deleted',
379 'Threshold%s %s deleted.' % (len(ids)==1 and '' or 's',
380 ', '.join(ids))
381 )
382 return self.callZenScreen(REQUEST)
383
384
385 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addGraphDefinition')
387 """Add a GraphDefinition to our RRDTemplate.
388 """
389 from GraphDefinition import GraphDefinition
390 self.getGraphDefs()
391 graph = None
392 graph = GraphDefinition(new_id)
393 graph.sequence = len(self.graphDefs())
394 self.graphDefs._setObject(graph.id, graph)
395 graph = self.graphDefs._getOb(graph.id)
396 if REQUEST:
397 messaging.IMessageSender(self).sendToBrowser(
398 'Graph Added',
399 'Graph "%s" added' % graph.id
400 )
401 url = '%s/graphDefs/%s' % (self.getPrimaryUrlPath(), graph.id)
402 return REQUEST['RESPONSE'].redirect(url)
403 return graph
404
405
406 security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteGraphDefinitions')
408 """Remove GraphDefinitions from this RRDTemplate.
409 """
410 for id in ids:
411 self.graphDefs._delObject(id)
412 self.manage_resequenceGraphDefs()
413 if REQUEST:
414 messaging.IMessageSender(self).sendToBrowser(
415 'Graphs Deleted',
416 'Graph%s %s deleted.' % (len(ids)==1 and '' or 's',
417 ', '.join(ids))
418 )
419 return self.callZenScreen(REQUEST)
420
421
422 security.declareProtected(ZEN_MANAGE_DMD, 'manage_resequenceGraphDefs')
424 """Reorder the sequence of the GraphDefinitions.
425 """
426 from Products.ZenUtils.Utils import resequence
427 return resequence(self, self.getGraphDefs(),
428 seqmap, origseq, REQUEST)
429
430
431 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
433 """
434 Create GraphPoints for all datapoints in the given datasources (ids)
435 in each of the graphDefs (graphIds.)
436 If a graphpoint already exists for a datapoint in a graphDef then
437 don't create a 2nd one.
438 """
439 newGraphPoints = []
440 for dsId in ids:
441 ds = self.datasources._getOb(dsId, None)
442 if ds:
443 newGraphPoints += ds.manage_addDataPointsToGraphs(
444 [dp.id for dp in ds.datapoints()],
445 graphIds)
446 numAdded = len(newGraphPoints)
447 if REQUEST:
448 messaging.IMessageSender(self).sendToBrowser(
449 'Graph Points Added',
450 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
451 )
452 return self.callZenScreen(REQUEST)
453 return newGraphPoints
454
455
456 security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataSourcesToGraphs')
458 """
459 Create GraphPoints for all given thresholds that are not already
460 graphed. in the given datasources (ids)
461 """
462 newGps = []
463 for graphId in graphIds:
464 graphDef = self.graphDefs._getOb(graphId, None)
465 if graphDef:
466 for threshId in ids:
467 thresh = self.thresholds._getOb(threshId, None)
468 if thresh and not graphDef.isThresholdGraphed(thresh.id):
469 newGps += graphDef.manage_addThresholdGraphPoints(
470 [thresh.id])
471 if REQUEST:
472 numAdded = len(newGps)
473 messaging.IMessageSender(self).sendToBrowser(
474 'Graph Points Added',
475 'Added %s GraphPoint%s' % (numAdded, numAdded != 1 and 's' or '')
476 )
477 return self.callZenScreen(REQUEST)
478 return newGps
479
480
482 dsClasses = [BasicDataSource, BuiltInDS]
483 for zp in self.dmd.ZenPackManager.packs():
484 dsClasses += zp.getDataSourceClasses()
485 return dsClasses
486
487
489 ''' Returns a list of the available datasource options as a list
490 of (display name, dsOption)
491 '''
492 dsTypes = []
493 for dsClass in self.getDataSourceClasses():
494 dsTypes += [(t, '%s.%s' % (dsClass.__name__, t))
495 for t in dsClass.sourcetypes]
496 return dsTypes
497
498
500 ''' Given one of the dsOptions returned by getDataSourceOptions)
501 return an instance of the that RRDDataSource subclass.
502 '''
503 dsClassName, dsType = dsOption.split('.')
504 for c in self.getDataSourceClasses():
505 if dsClassName == c.__name__:
506 ds = c(id)
507 ds.sourcetype = dsType
508 break
509 else:
510 raise ConfigurationError('Cannot find datasource class'
511 ' for %s' % dsOption)
512 return ds
513
514
516 from Products.ZenModel.MinMaxThreshold import MinMaxThreshold
517 thresholdClasses = [MinMaxThreshold]
518 for zp in self.dmd.ZenPackManager.packs():
519 thresholdClasses += zp.getThresholdClasses()
520 return map(lambda x: (x, x.__name__), thresholdClasses)
521
522
524 ''' Given one of the dsOptions returned by getDataSourceOptions)
525 return an instance of the that RRDDataSource subclass.
526 '''
527 for c, name in self.getThresholdClasses():
528 if thresholdClassName == c.__name__:
529 return c(id)
530 raise ConfigurationError('Cannot find threshold class %s' %
531 thresholdClassName)
532
533
535 """
536 Get a list of all event class names within the permission scope.
537 """
538 return self.primaryAq().Events.getOrganizerNames()
539
540
541 InitializeClass(RRDTemplate)
542
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Thu May 7 11:46:33 2009 | http://epydoc.sourceforge.net |