Package Products :: Package ZenModel :: Module DeviceClass
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.DeviceClass

  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  __doc__="""DeviceClass 
 15  The primary organizer of device objects, managing zProperties and 
 16  their acquisition. 
 17  """ 
 18   
 19  import types 
 20  import time 
 21  import transaction 
 22  import logging 
 23  log = logging.getLogger('zen.DeviceClass') 
 24   
 25  import DateTime 
 26  from zope.event import notify 
 27  from zope.app.container.contained import ObjectMovedEvent 
 28  from Globals import DTMLFile 
 29  from Globals import InitializeClass 
 30  from Acquisition import aq_base, aq_chain 
 31  from AccessControl import ClassSecurityInfo 
 32  from AccessControl import Permissions as permissions 
 33   
 34  from Products.AdvancedQuery import MatchGlob, Or, Eq, RankByQueries_Max 
 35  from Products.CMFCore.utils import getToolByName 
 36   
 37  from Products.ZenModel.ZenossSecurity import * 
 38  from Products.ZenRelations.RelSchema import * 
 39  from Products.ZenRelations.ZenPropertyManager import Z_PROPERTIES 
 40  from Products.ZenUtils.Search import makeCaseInsensitiveFieldIndex 
 41  from Products.ZenUtils.Search import makeCaseInsensitiveKeywordIndex 
 42  from Products.ZenUtils.Search import makePathIndex, makeMultiPathIndex 
 43  from Products.ZenUtils.Utils import importClass, zenPath 
 44  from Products.ZenWidgets import messaging 
 45  from Products.ZenUtils.FakeRequest import FakeRequest 
 46  from Products.Zuul.catalog.events import IndexingEvent 
 47   
 48  import RRDTemplate 
 49  from DeviceOrganizer import DeviceOrganizer 
 50  from ZenPackable import ZenPackable 
 51  from TemplateContainer import TemplateContainer 
 52   
 53  _marker = "__MARKER___" 
 54   
55 -def manage_addDeviceClass(context, id, title = None, REQUEST = None):
56 """make a device class""" 57 dc = DeviceClass(id, title) 58 context._setObject(id, dc) 59 if REQUEST is not None: 60 REQUEST['RESPONSE'].redirect(context.absolute_url() + '/manage_main')
61 62 63 addDeviceClass = DTMLFile('dtml/addDeviceClass',globals()) 64 65
66 -class DeviceClass(DeviceOrganizer, ZenPackable, TemplateContainer):
67 """ 68 DeviceClass is a device organizer that manages the primary classification 69 of device objects within the Zenoss system. It manages properties 70 that are inherited through acquisition that modify the behavior of 71 many different sub systems within Zenoss. 72 It also handles the creation of new devices in the system. 73 """ 74 75 # Organizer configuration 76 dmdRootName = "Devices" 77 78 manageDeviceSearch = DTMLFile('dtml/manageDeviceSearch',globals()) 79 manageDeviceSearchResults = DTMLFile('dtml/manageDeviceSearchResults', 80 globals()) 81 82 portal_type = meta_type = event_key = "DeviceClass" 83 84 default_catalog = 'deviceSearch' 85 86 _properties = DeviceOrganizer._properties + ( 87 {'id':'devtypes', 'type':'lines', 'mode':'w'}, 88 ) 89 90 _relations = DeviceOrganizer._relations + ZenPackable._relations + \ 91 TemplateContainer._relations + ( 92 ("devices", ToManyCont(ToOne,"Products.ZenModel.Device","deviceClass")), 93 ) 94 95 # Screen action bindings (and tab definitions) 96 factory_type_information = ( 97 { 98 'id' : 'DeviceClass', 99 'meta_type' : 'DeviceClass', 100 'description' : """Base class for all devices""", 101 'icon' : 'DeviceClass_icon.gif', 102 'product' : 'ZenModel', 103 'factory' : 'manage_addDeviceClass', 104 'immediate_view' : 'deviceOrganizerStatus', 105 'actions' : 106 ( 107 { 'name' : 'Classes' 108 , 'action' : 'deviceOrganizerStatus' 109 , 'permissions' : ( permissions.view, ) 110 }, 111 { 'name' : 'Events' 112 , 'action' : 'viewEvents' 113 , 'permissions' : ( permissions.view, ) 114 }, 115 { 'name' : 'Configuration Properties' 116 , 'action' : 'zPropertyEdit' 117 , 'permissions' : (permissions.view,) 118 }, 119 { 'name' : 'Templates' 120 , 'action' : 'perfConfig' 121 , 'permissions' : ('Manage DMD',) 122 }, 123 ) 124 }, 125 ) 126 127 security = ClassSecurityInfo() 128
129 - def getPeerDeviceClassNames(self, pyclass=None):
130 """ 131 Return a list of all device paths that have the Python class pyclass 132 133 @param pyclass: Python class (default is this class) 134 @type pyclass: Python class 135 @return: list of device paths 136 @rtype: list of strings 137 """ 138 dcnames = [] 139 if pyclass == None: 140 pyclass = self.getPythonDeviceClass() 141 dclass = self.getDmdRoot("Devices") 142 for orgname in dclass.getOrganizerNames(): 143 org = dclass.getOrganizer(orgname) 144 if issubclass(org.getPythonDeviceClass(), pyclass): 145 dcnames.append(orgname) 146 dcnames.sort(lambda a, b: cmp(a.lower(), b.lower())) 147 return dcnames
148 149 deviceMoveTargets = getPeerDeviceClassNames 150 childMoveTargets = getPeerDeviceClassNames 151 152
153 - def createInstance(self, id):
154 """ 155 Create an instance based on its location in the device tree 156 walk up the primary aq path looking for a python instance class that 157 matches the name of the closest node in the device tree. 158 159 @param id: id in DMD path 160 @type id: string 161 @return: new device object 162 @rtype: device object 163 """ 164 pyClass = self.getPythonDeviceClass() 165 dev = pyClass(id) 166 self.devices._setObject(id, dev) 167 return self.devices._getOb(id)
168 169
170 - def getPythonDeviceClass(self):
171 """ 172 Return the Python class object to be used for device instances in this 173 device class. This is done by walking up the aq_chain of a deviceclass 174 to find a node that has the same name as a Python class or has an 175 attribute named zPythonClass that matches a Python class. 176 177 @return: device class 178 @rtype: device class 179 """ 180 from Device import Device 181 cname = getattr(self, "zPythonClass", None) 182 if cname: 183 try: 184 return importClass(cname) 185 except ImportError: 186 log.exception("Unable to import class " + cname) 187 return Device
188 189
190 - def moveDevices(self, moveTarget, deviceNames=None, REQUEST=None):
191 """ 192 Override default moveDevices because this is a contained relation. 193 If the Python class bound to a DeviceClass is different we convert to 194 the new Python class adding / removing relationships as needed. 195 196 @param moveTarget: organizer in DMD path 197 @type moveTarget: string 198 @param deviceNames: devices to move 199 @type deviceNames: list of stringa 200 @param REQUEST: Zope REQUEST object 201 @type REQUEST: Zope REQUEST object 202 """ 203 if not moveTarget or not deviceNames: return self() 204 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 205 if type(deviceNames) == types.StringType: deviceNames = (deviceNames,) 206 newPath = target.absolute_url_path() + '/' 207 for devname in deviceNames: 208 dev = self.findDeviceByIdExact(devname) 209 if not dev: continue 210 source = dev.deviceClass().primaryAq() 211 oldPath = source.absolute_url_path() + '/' 212 if dev.__class__ != target.getPythonDeviceClass(): 213 import StringIO 214 from Products.ZenRelations.ImportRM import NoLoginImportRM 215 216 def switchClass(o, module, klass): 217 """ 218 Create an XML string representing the module in a 219 new class. 220 221 @param o: file-type object 222 @type o: file-type object 223 @param module: location in DMD 224 @type module: string 225 @param klass: class name 226 @type klass: string 227 @return: XML representation of the class 228 @rtype: string 229 """ 230 o.seek(0) 231 l = o.readline() 232 al = l[1:-2].split() 233 for i in range(len(al)): 234 if al[i].startswith('module'): 235 al[i] = "module='%s'" % module 236 elif al[i].startswith('class'): 237 al[i] = "class='%s'" % klass 238 nl = "<" + " ".join(al) + ">\n" 239 o.seek(0) 240 nf = ["<objects>", nl] 241 data = [line.replace(oldPath, newPath) \ 242 for line in o.readlines()[1:]] 243 nf.extend(data) 244 nf.append('</objects>') 245 return StringIO.StringIO("".join(nf))
246 247 def devExport(d, module, klass): 248 """ 249 Create an XML string representing the device d 250 at the DMD location module of type klass. 251 252 @param module: location in DMD 253 @type module: string 254 @param klass: class name 255 @type klass: string 256 @return: XML representation of the class 257 @rtype: string 258 """ 259 o = StringIO.StringIO() 260 d.exportXml(o) 261 return switchClass(o, module, klass)
262 263 def devImport(xmlfile): 264 """ 265 Load a new device from a file. 266 267 @param xmlfile: file type object 268 @type xmlfile: file type object 269 """ 270 im = NoLoginImportRM(target.devices) 271 im.loadObjectFromXML(xmlfile) 272 273 module = target.zPythonClass 274 if module: 275 klass = target.zPythonClass.split('.')[-1] 276 else: 277 module = 'Products.ZenModel.Device' 278 klass = 'Device' 279 xmlfile = devExport(dev, module, klass) 280 log.info('Removing device %s from %s', devname, source) 281 source.devices._delObject(devname) 282 devImport(xmlfile) 283 else: 284 dev._operation = 1 285 source.devices._delObject(devname) 286 target.devices._setObject(devname, dev) 287 dev = target.devices._getOb(devname) 288 dev.setLastChange() 289 dev.setAdminLocalRoles() 290 dev.index_object() 291 transaction.commit() 292 293 294 security.declareProtected(ZEN_DELETE_DEVICE, 'removeDevices')
295 - def removeDevices(self, deviceNames=None, deleteStatus=False, 296 deleteHistory=False, deletePerf=False,REQUEST=None):
297 """ 298 See IManageDevice overrides DeviceManagerBase.removeDevices 299 """ 300 if not deviceNames: return self() 301 if type(deviceNames) in types.StringTypes: deviceNames = (deviceNames,) 302 for devname in deviceNames: 303 dev = self.findDevice(devname) 304 dev.deleteDevice(deleteStatus=deleteStatus, 305 deleteHistory=deleteHistory, deletePerf=deletePerf) 306 if REQUEST: 307 messaging.IMessageSender(self).sendToBrowser( 308 'Devices Deleted', 309 "Devices were deleted: %s." % ', '.join(deviceNames) 310 ) 311 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 312 return 'Devices were deleted: %s.' % ', '.join(deviceNames) 313 else: 314 return self.callZenScreen(REQUEST)
315 316 317 security.declareProtected('View', 'getEventDeviceInfo')
318 - def getEventDeviceInfo(self):
319 """ 320 getEventDeviceInfo() -> return the info for NcoEventPopulator 321 """ 322 deviceInfo = {} 323 for device in self.getSubDevices(): 324 systemNames = [] 325 for sys in device.systems.objectValuesAll(): 326 systemNames.append(sys.getOrganizerName()) 327 systemNames = "|".join(systemNames) 328 location = device.getLocationName() 329 if not location: location = "Unknown" 330 deviceInfo[device.id] = (systemNames, location, 331 device.productionState, 332 device.getDeviceClassPath()) 333 return deviceInfo
334 335 336 security.declareProtected('View', 'getDeviceWinInfo')
337 - def getDeviceWinInfo(self, lastPoll=0, eventlog=False):
338 """ 339 Return list of (devname,user,passwd,url) for each device. 340 user and passwd are used to connect via wmi. 341 """ 342 ffunc = None 343 starttime = time.time() 344 if lastPoll > 0: 345 lastPoll = DateTime.DateTime(lastPoll) 346 ffunc = lambda x: x.getSnmpLastCollection() > lastPoll 347 if eventlog: 348 ffunc = lambda x: x.zWinEventlog 349 devinfo = [] 350 for dev in self.getSubDevices(devfilter=ffunc): 351 if not dev.monitorDevice(): continue 352 if dev.getProperty('zWmiMonitorIgnore', False): continue 353 user = dev.getProperty('zWinUser','') 354 passwd = dev.getProperty( 'zWinPassword', '') 355 sev = dev.getProperty( 'zWinEventlogMinSeverity', '') 356 devinfo.append((dev.id, str(user), str(passwd), sev, dev.absolute_url())) 357 return starttime, devinfo
358 359
360 - def getWinServices(self):
361 """ 362 Return a list of (devname, user, passwd, {'EvtSys':0,'Exchange':0}) 363 """ 364 svcinfo = [] 365 allsvcs = {} 366 for s in self.getSubComponents("WinService"): 367 svcs=allsvcs.setdefault(s.hostname(),{}) 368 name = s.name() 369 if type(name) == type(u''): 370 name = name.encode(s.zCollectorDecoding) 371 svcs[name] = (s.getStatus(), s.getAqProperty('zFailSeverity')) 372 for dev in self.getSubDevices(): 373 if not dev.monitorDevice(): continue 374 if dev.getProperty( 'zWmiMonitorIgnore', False): continue 375 svcs = allsvcs.get(dev.getId(), {}) 376 if not svcs and not dev.zWinEventlog: continue 377 user = dev.getProperty('zWinUser','') 378 passwd = dev.getProperty( 'zWinPassword', '') 379 svcinfo.append((dev.id, str(user), str(passwd), svcs)) 380 return svcinfo
381 382 383 security.declareProtected('View', 'searchDeviceSummary')
384 - def searchDeviceSummary(self, query):
385 """ 386 Search device summary index and return device objects 387 """ 388 if not query: return [] 389 zcatalog = self._getCatalog() 390 if not zcatalog: return [] 391 results = zcatalog({'summary':query}) 392 return self._convertResultsToObj(results)
393 394 395 security.declareProtected('View', 'searchInterfaces')
396 - def searchInterfaces(self, query):
397 """ 398 Search interfaces index and return interface objects 399 """ 400 if not query: return [] 401 zcatalog = getattr(self, 'interfaceSearch', None) 402 if not zcatalog: return [] 403 results = zcatalog(query) 404 return self._convertResultsToObj(results)
405 406
407 - def _convertResultsToObj(self, results):
408 devices = [] 409 for brain in results: 410 try: 411 devobj = self.getObjByPath(brain.getPrimaryId) 412 devices.append(devobj) 413 except KeyError: 414 log.warn("bad path '%s' in index" % brain.getPrimaryId) 415 416 return devices
417
418 - def _findDevice(self, devicename, useTitle=True):
419 """ 420 Returns all devices whose ip/id/title match devicename. 421 ip/id matches are at the front of the list. 422 423 @rtype: list of brains 424 """ 425 idIpQuery = Or( MatchGlob('id', devicename), 426 Eq('getDeviceIp', devicename) ) 427 if useTitle: 428 titleOrIdQuery = MatchGlob('titleOrId', devicename) 429 query = Or( idIpQuery, titleOrIdQuery ) 430 rankSort = RankByQueries_Max( ( idIpQuery, 16 ), 431 ( titleOrIdQuery, 8 ) ) 432 devices = self._getCatalog().evalAdvancedQuery(query, (rankSort,)) 433 else: 434 devices = self._getCatalog().evalAdvancedQuery(idIpQuery) 435 return devices
436
437 - def findDevicePath(self, devicename):
438 """ 439 Look up a device and return its path 440 """ 441 ret = self._findDevice(devicename) 442 if not ret: return "" 443 return ret[0].getPrimaryId
444
445 - def findDevice(self, devicename):
446 """ 447 Returns the first device whose ip/id matches devicename. If 448 there is no ip/id match, return the first device whose title 449 matches devicename. 450 """ 451 ret = self._findDevice(devicename) 452 if ret: return ret[0].getObject()
453
454 - def findDeviceByIdOrIp(self, devicename):
455 """ 456 Returns the first device that has an ip/id that matches devicename 457 """ 458 ret = self._findDevice( devicename, False ) 459 if ret: return ret[0].getObject()
460
461 - def findDeviceByIdExact(self, devicename):
462 """ 463 Look up device in catalog and return it. devicename 464 must match device id exactly 465 """ 466 for brains in self._getCatalog()(id=devicename): 467 dev = brains.getObject() 468 if dev.id == devicename: 469 return dev
470
471 - def findDevicePingStatus(self, devicename):
472 """ 473 look up device in catalog and return its pingStatus 474 """ 475 dev = self.findDevice(devicename) 476 if dev: return dev.getPingStatusNumber()
477 478
479 - def getSubComponents(self, meta_type="", monitored=True):
480 """ 481 Return generator of components, by meta_type if specified 482 """ 483 zcat = self.componentSearch 484 res = zcat({'meta_type': meta_type, 'monitored': monitored}) 485 for b in res: 486 try: 487 c = self.getObjByPath(b.getPrimaryId) 488 if self.checkRemotePerm("View", c): 489 yield c 490 except KeyError: 491 log.warn("bad path '%s' in index 'componentSearch'", 492 b.getPrimaryId)
493 494 495 security.declareProtected("ZenCommon", "getMonitoredComponents")
496 - def getMonitoredComponents(self):
497 """ 498 Return monitored components for devices within this DeviceDeviceClass 499 """ 500 return self.getSubComponents()
501 502 503 security.declareProtected('View', 'getRRDTemplates')
504 - def getRRDTemplates(self, context=None):
505 """ 506 Return the actual RRDTemplate instances. 507 """ 508 templates = {} 509 if not context: context = self 510 mychain = aq_chain(context) 511 mychain.reverse() 512 for obj in mychain: 513 try: 514 templates.update(dict([(t.id, t) for t in obj.rrdTemplates()])) 515 except AttributeError: 516 pass 517 return templates.values()
518 519
520 - def getAvailableTemplates(self):
521 """ 522 Returns all available templates 523 """ 524 def cmpTemplates(a, b): 525 return cmp(a.id.lower(), b.id.lower())
526 templates = self.getRRDTemplates() 527 templates.sort(cmpTemplates) 528 pdc = self.getPythonDeviceClass() 529 return [ t for t in templates 530 if issubclass(pdc, t.getTargetPythonClass()) ] 531 532
533 - def bindTemplates(self, ids=(), REQUEST=None):
534 """ 535 This will bind available templates to the zDeviceTemplates 536 """ 537 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
538
539 - def removeZDeviceTemplates(self, REQUEST=None):
540 """ 541 Deletes the local zProperty, zDeviceTemplates 542 """ 543 if self.getPrimaryPath()[-2:] == ('dmd', 'Devices'): 544 self.setZenProperty('zDeviceTemplates', ['Device']) 545 else: 546 self.deleteZenProperty('zDeviceTemplates') 547 messaging.IMessageSender(self).sendToBrowser( 548 'Bindings Reset', 549 'Template bindings for this class were reset.' 550 ) 551 return self.callZenScreen(REQUEST)
552 553
554 - def getAllRRDTemplates(self, rrdts=None):
555 """ 556 Return all RRDTemplates at this level and below in the object tree. 557 If rrdts is provided then it must be a list of RRDTemplates which 558 will be extended with the templates from here and returned. 559 560 The original getAllRRDTemplates() method has been renamed 561 getAllRRDTemplatesPainfully(). It walks the object tree looking 562 for templates which is a very slow way of going about things. 563 The newer RRDTemplate.YieldAllRRDTemplate() method uses the 564 searchRRDTemplates catalog to speed things up dramatically. 565 YieldAllRRDTemplates is smart enough to revert to 566 getAllRRDTemplatesPainfully if the catalog is not present. 567 568 The searchRRDTemplates catalog was added in 2.2 569 """ 570 if rrdts == None: 571 rrdts = [] 572 rrdts.extend(RRDTemplate.YieldAllRRDTemplates(self)) 573 return rrdts
574 575
576 - def getAllRRDTemplatesPainfully(self, rrdts=None):
577 """ 578 RRDTemplate.YieldAllRRDTemplates() is probably what you want. 579 It takes advantage of the searchRRDTemplates catalog to get 580 much better performance. This method iterates over objects looking 581 for templates which is a slow, painful process. 582 """ 583 if rrdts is None: rrdts = [] 584 rrdts.extend(self.rrdTemplates()) 585 for dev in self.devices(): 586 rrdts += dev.objectValues('RRDTemplate') 587 for comps in dev.getDeviceComponents(): 588 rrdts += comps.objectValues('RRDTemplate') 589 for child in self.children(): 590 child.getAllRRDTemplatesPainfully(rrdts) 591 return rrdts
592 593 594 security.declareProtected('Add DMD Objects', 'manage_addRRDTemplate')
595 - def manage_addRRDTemplate(self, id, REQUEST=None):
596 """ 597 Add an RRDTemplate to this DeviceClass. 598 """ 599 if not id: return self.callZenScreen(REQUEST) 600 id = self.prepId(id) 601 org = RRDTemplate.RRDTemplate(id) 602 self.rrdTemplates._setObject(org.id, org) 603 if REQUEST: 604 messaging.IMessageSender(self).sendToBrowser( 605 'Template Added', 606 'The "%s" template has been created.' % id 607 ) 608 return self.callZenScreen(REQUEST)
609 610 611 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 612 'manage_copyRRDTemplates')
613 - def manage_copyRRDTemplates(self, ids=(), REQUEST=None):
614 """ 615 Put a reference to the objects named in ids in the clip board 616 """ 617 if not ids: return self.callZenScreen(REQUEST) 618 ids = [ id for id in ids if self.rrdTemplates._getOb(id, None) != None] 619 if not ids: return self.callZenScreen(REQUEST) 620 cp = self.rrdTemplates.manage_copyObjects(ids) 621 if REQUEST: 622 resp=REQUEST['RESPONSE'] 623 resp.setCookie('__cp', cp, path='/zport/dmd') 624 REQUEST['__cp'] = cp 625 messaging.IMessageSender(self).sendToBrowser( 626 'Templates Copied', 627 'Templates have been copied: %s' % ', '.join(ids) 628 ) 629 return self.callZenScreen(REQUEST) 630 return cp
631 632 633 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 634 'manage_pasteRRDTemplates')
635 - def manage_pasteRRDTemplates(self, moveTarget=None, cb_copy_data=None, REQUEST=None):
636 """ 637 Paste RRDTemplates that have been copied before. 638 """ 639 cp = None 640 if cb_copy_data: cp = cb_copy_data 641 elif REQUEST: 642 cp = REQUEST.get("__cp",None) 643 644 if cp: 645 if moveTarget: 646 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 647 else: 648 target = self 649 target.rrdTemplates.manage_pasteObjects(cp) 650 else: 651 target = None 652 653 if REQUEST: 654 REQUEST['RESPONSE'].setCookie('__cp', 'deleted', path='/zport/dmd', 655 expires='Wed, 31-Dec-97 23:59:59 GMT') 656 REQUEST['__cp'] = None 657 if target: 658 message = "Template(s) copied to %s" % moveTarget 659 else: 660 message = None 661 messaging.IMessageSender(self).sendToBrowser( 662 'Template(s) Copied', 663 message 664 ) 665 if not isinstance(REQUEST, FakeRequest): 666 url = target.getPrimaryUrlPath() + '/perfConfig' 667 if message: 668 url += '?message=%s' % message 669 REQUEST['RESPONSE'].redirect(url) 670 else: 671 return self.callZenScreen(REQUEST)
672 673 674 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 675 'manage_copyAndPasteRRDTemplates')
676 - def manage_copyAndPasteRRDTemplates(self, ids=(), copyTarget=None, REQUEST=None):
677 """ 678 Copy the selected templates into the specified device class. 679 """ 680 if not ids: 681 messaging.IMessageSender(self).sendToBrowser( 682 'Invalid', 683 'No templates were selected.', 684 priority=messaging.WARNING 685 ) 686 return self.callZenScreen(REQUEST) 687 if copyTarget is None: 688 messaging.IMessageSender(self).sendToBrowser( 689 'Invalid', 690 'No target was selected.', 691 priority=messaging.WARNING 692 ) 693 return self.callZenScreen(REQUEST) 694 cp = self.manage_copyRRDTemplates(ids) 695 return self.manage_pasteRRDTemplates(copyTarget, cp, REQUEST)
696 697 698 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 699 'manage_deleteRRDTemplates')
700 - def manage_deleteRRDTemplates(self, ids=(), paths=(), REQUEST=None):
701 """ 702 Delete RRDTemplates from this DeviceClass 703 (skips ones in other Classes) 704 """ 705 if not ids and not paths: 706 return self.callZenScreen(REQUEST) 707 for id in ids: 708 if (getattr(aq_base(self), 'rrdTemplates', False) 709 and getattr(aq_base(self.rrdTemplates),id,False)): 710 self.rrdTemplates._delObject(id) 711 for path in paths: 712 temp = self.dmd.getObjByPath(path) 713 if temp.deviceClass(): 714 temp.deviceClass().rrdTemplates._delObject(temp.id) 715 else: 716 temp.device()._delObject(temp.id) 717 if REQUEST: 718 messaging.IMessageSender(self).sendToBrowser( 719 'Templates Deleted', 720 'Templates were deleted: %s' % ", ".join(ids) 721 ) 722 return self.callZenScreen(REQUEST)
723 724
725 - def createCatalog(self):
726 """ 727 Make the catalog for device searching 728 """ 729 from Products.ZCatalog.ZCatalog import manage_addZCatalog 730 731 # Make catalog for Devices 732 manage_addZCatalog(self, self.default_catalog, 733 self.default_catalog) 734 zcat = self._getOb(self.default_catalog) 735 cat = zcat._catalog 736 for idxname in ['id', 737 'getDeviceIp','getDeviceClassPath','getProdState','titleOrId']: 738 cat.addIndex(idxname, makeCaseInsensitiveFieldIndex(idxname)) 739 cat.addIndex('getPhysicalPath', makePathIndex('getPhysicalPath')) 740 cat.addIndex('path', makeMultiPathIndex('path')) 741 zcat.addColumn('getPrimaryId') 742 zcat.addColumn('id') 743 zcat.addColumn('path') 744 745 # make catalog for device components 746 manage_addZCatalog(self, "componentSearch", "componentSearch") 747 zcat = self._getOb("componentSearch") 748 cat = zcat._catalog 749 cat.addIndex('meta_type', makeCaseInsensitiveFieldIndex('meta_type')) 750 cat.addIndex('getParentDeviceName', 751 makeCaseInsensitiveFieldIndex('getParentDeviceName')) 752 cat.addIndex('getCollectors', 753 makeCaseInsensitiveKeywordIndex('getCollectors')) 754 # XXX still using regular FieldIndex here for now, since this contains 755 # binary information 756 zcat.addIndex('monitored', 'FieldIndex') 757 zcat.addColumn('getPrimaryId') 758 zcat.addColumn('meta_type')
759 760
761 - def reIndex(self):
762 """ 763 Go through all devices in this tree and reindex them. 764 """ 765 zcat = getToolByName(self, self.default_catalog) 766 zcat.manage_catalogClear() 767 self.componentSearch.manage_catalogClear() 768 transaction.savepoint() 769 for dev in self.getSubDevicesGen_recursive(): 770 dev.index_object() 771 notify(IndexingEvent(dev)) 772 for comp in dev.getDeviceComponentsNoIndexGen(): 773 comp.index_object() 774 notify(IndexingEvent(comp)) 775 transaction.savepoint()
776 777
778 - def buildDeviceTreeProperties(self):
779 """ 780 Create a new device tree with a default configuration 781 """ 782 devs = self.getDmdRoot("Devices") 783 for id, value, type in Z_PROPERTIES: 784 if not devs.hasProperty(id): 785 devs._setProperty(id, value, type)
786
787 - def zenPropertyOptions(self, propname):
788 """ 789 Provide a set of default options for a zProperty 790 791 @param propname: zProperty name 792 @type propname: string 793 @return: list of zProperty options 794 @rtype: list 795 """ 796 if propname == 'zCollectorPlugins': 797 from Products.DataCollector.Plugins import loadPlugins 798 names = [ldr.pluginName for ldr in loadPlugins(self.dmd)] 799 names.sort() 800 return names 801 if propname == 'zCommandProtocol': 802 return ['ssh', 'telnet'] 803 if propname == 'zSnmpVer': 804 return ['v1', 'v2c', 'v3'] 805 if propname == 'zSnmpAuthType': 806 return ['', 'MD5', 'SHA'] 807 if propname == 'zSnmpPrivType': 808 return ['', 'DES', 'AES'] 809 return DeviceOrganizer.zenPropertyOptions(self, propname)
810 811
812 - def pushConfig(self, REQUEST=None):
813 """ 814 This will result in a push of all the devices to live collectors 815 816 @param REQUEST: Zope REQUEST object 817 @type REQUEST: Zope REQUEST object 818 """ 819 self._p_changed = True 820 if REQUEST: 821 messaging.IMessageSender(self).sendToBrowser( 822 'Pushed Changes', 823 'Changes to %s were pushed to collectors.' % self.id 824 ) 825 return self.callZenScreen(REQUEST)
826 827 828 security.declareProtected('Change Device', 'setLastChange')
829 - def setLastChange(self, value=None):
830 """ 831 Set the changed datetime for this device. 832 833 @param value: changed datetime. Default is now. 834 @type value: number 835 """ 836 if value is None: 837 value = time.time() 838 self._lastChange = float(value)
839
840 - def register_devtype(self, description, protocol):
841 """ 842 Define this class in terms of a description of the devices it should 843 contain and the protocol by which they would normally be monitored. 844 """ 845 t = (description, protocol) 846 if not hasattr(self, 'devtypes'): 847 self._setProperty('devtypes', [], 'lines') 848 if t not in self.devtypes: 849 self.devtypes.append(t) 850 self._p_changed = True
851
852 - def unregister_devtype(self, description, protocol):
853 t = (description, protocol) 854 if hasattr(self, 'devtypes'): 855 if t in self.devtypes: 856 self.devtypes.remove(t) 857 self._p_changed = True
858 859 860 InitializeClass(DeviceClass) 861