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

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