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