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 if REQUEST: 284 messaging.IMessageSender(self).sendToBrowser(title='Devices Moved', 285 body="Devices were moved to %s." % moveTarget) 286 REQUEST['message'] = "Devices moved to %s" % moveTarget 287 if not isinstance(REQUEST, FakeRequest): 288 REQUEST['RESPONSE'].redirect(target.getPrimaryUrlPath()) 289 else: 290 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 291 return REQUEST['message'] 292 else: 293 return self.callZenScreen(REQUEST) 294 295
296 - def removeDevices(self, deviceNames=None, deleteStatus=False, 297 deleteHistory=False, deletePerf=False,REQUEST=None):
298 """ 299 See IManageDevice overrides DeviceManagerBase.removeDevices 300 """ 301 if not deviceNames: return self() 302 if type(deviceNames) in types.StringTypes: deviceNames = (deviceNames,) 303 for devname in deviceNames: 304 dev = self.findDevice(devname) 305 dev.deleteDevice(deleteStatus=deleteStatus, 306 deleteHistory=deleteHistory, deletePerf=deletePerf) 307 if REQUEST: 308 messaging.IMessageSender(self).sendToBrowser( 309 'Devices Deleted', 310 "Devices were deleted: %s." % ', '.join(deviceNames) 311 ) 312 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 313 return 'Devices were deleted: %s.' % ', '.join(deviceNames) 314 else: 315 return self.callZenScreen(REQUEST)
316 317 318 security.declareProtected('View', 'getEventDeviceInfo')
319 - def getEventDeviceInfo(self):
320 """ 321 getEventDeviceInfo() -> return the info for NcoEventPopulator 322 """ 323 deviceInfo = {} 324 for device in self.getSubDevices(): 325 systemNames = [] 326 for sys in device.systems.objectValuesAll(): 327 systemNames.append(sys.getOrganizerName()) 328 systemNames = "|".join(systemNames) 329 location = device.getLocationName() 330 if not location: location = "Unknown" 331 deviceInfo[device.id] = (systemNames, location, 332 device.productionState, 333 device.getDeviceClassPath()) 334 return deviceInfo
335 336 337 security.declareProtected('View', 'getDeviceWinInfo')
338 - def getDeviceWinInfo(self, lastPoll=0, eventlog=False):
339 """ 340 Return list of (devname,user,passwd,url) for each device. 341 user and passwd are used to connect via wmi. 342 """ 343 ffunc = None 344 starttime = time.time() 345 if lastPoll > 0: 346 lastPoll = DateTime.DateTime(lastPoll) 347 ffunc = lambda x: x.getSnmpLastCollection() > lastPoll 348 if eventlog: 349 ffunc = lambda x: x.zWinEventlog 350 devinfo = [] 351 for dev in self.getSubDevices(devfilter=ffunc): 352 if not dev.monitorDevice(): continue 353 if getattr(dev, 'zWmiMonitorIgnore', False): continue 354 user = getattr(dev,'zWinUser','') 355 passwd = getattr(dev, 'zWinPassword', '') 356 sev = getattr(dev, 'zWinEventlogMinSeverity', '') 357 devinfo.append((dev.id, str(user), str(passwd), sev, dev.absolute_url())) 358 return starttime, devinfo
359 360
361 - def getWinServices(self):
362 """ 363 Return a list of (devname, user, passwd, {'EvtSys':0,'Exchange':0}) 364 """ 365 svcinfo = [] 366 allsvcs = {} 367 for s in self.getSubComponents("WinService"): 368 svcs=allsvcs.setdefault(s.hostname(),{}) 369 name = s.name() 370 if type(name) == type(u''): 371 name = name.encode(s.zCollectorDecoding) 372 svcs[name] = (s.getStatus(), s.getAqProperty('zFailSeverity')) 373 for dev in self.getSubDevices(): 374 if not dev.monitorDevice(): continue 375 if getattr(dev, 'zWmiMonitorIgnore', False): continue 376 svcs = allsvcs.get(dev.getId(), {}) 377 if not svcs and not dev.zWinEventlog: continue 378 user = getattr(dev,'zWinUser','') 379 passwd = getattr(dev, 'zWinPassword', '') 380 svcinfo.append((dev.id, str(user), str(passwd), svcs)) 381 return svcinfo
382 383 384 security.declareProtected('View', 'searchDeviceSummary')
385 - def searchDeviceSummary(self, query):
386 """ 387 Search device summary index and return device objects 388 """ 389 if not query: return [] 390 zcatalog = self._getCatalog() 391 if not zcatalog: return [] 392 results = zcatalog({'summary':query}) 393 return self._convertResultsToObj(results)
394 395 396 security.declareProtected('View', 'searchInterfaces')
397 - def searchInterfaces(self, query):
398 """ 399 Search interfaces index and return interface objects 400 """ 401 if not query: return [] 402 zcatalog = getattr(self, 'interfaceSearch', None) 403 if not zcatalog: return [] 404 results = zcatalog(query) 405 return self._convertResultsToObj(results)
406 407
408 - def _convertResultsToObj(self, results):
409 devices = [] 410 for brain in results: 411 try: 412 devobj = self.getObjByPath(brain.getPrimaryId) 413 devices.append(devobj) 414 except KeyError: 415 log.warn("bad path '%s' in index" % brain.getPrimaryId) 416 417 return devices
418
419 - def _findDevice(self, devicename):
420 query = Or(MatchGlob('id', devicename), 421 Eq('getDeviceIp', devicename)) 422 return self._getCatalog().evalAdvancedQuery(query)
423
424 - def findDevicePath(self, devicename):
425 """ 426 Look up a device and return its path 427 """ 428 ret = self._findDevice(devicename) 429 if not ret: return "" 430 return ret[0].getPrimaryId
431
432 - def findDevice(self, devicename):
433 """ 434 Look up device in catalog and return it 435 """ 436 ret = self._findDevice(devicename) 437 if ret: return ret[0].getObject()
438
439 - def findDeviceExact(self, devicename):
440 """ 441 Look up device in catalog and return it. devicename 442 must match device id exactly 443 """ 444 for brains in self._getCatalog()(id=devicename): 445 dev = brains.getObject() 446 if dev.id == devicename: 447 return dev
448
449 - def findDevicePingStatus(self, devicename):
450 """ 451 look up device in catalog and return its pingStatus 452 """ 453 dev = self.findDevice(devicename) 454 if dev: return dev.getPingStatusNumber()
455 456
457 - def getSubComponents(self, meta_type="", monitored=True):
458 """ 459 Return generator of components, by meta_type if specified 460 """ 461 zcat = self.componentSearch 462 res = zcat({'meta_type': meta_type, 'monitored': monitored}) 463 for b in res: 464 try: 465 c = self.getObjByPath(b.getPrimaryId) 466 if self.checkRemotePerm("View", c): 467 yield c 468 except KeyError: 469 log.warn("bad path '%s' in index 'componentSearch'", 470 b.getPrimaryId)
471 472 473 security.declareProtected("ZenCommon", "getMonitoredComponents")
474 - def getMonitoredComponents(self):
475 """ 476 Return monitored components for devices within this DeviceDeviceClass 477 """ 478 return self.getSubComponents()
479 480 481 security.declareProtected('View', 'getRRDTemplates')
482 - def getRRDTemplates(self, context=None):
483 """ 484 Return the actual RRDTemplate instances. 485 """ 486 templates = {} 487 if not context: context = self 488 mychain = aq_chain(context) 489 mychain.reverse() 490 for obj in mychain: 491 try: 492 templates.update(dict([(t.id, t) for t in obj.rrdTemplates()])) 493 except AttributeError: 494 pass 495 return templates.values()
496 497
498 - def getAvailableTemplates(self):
499 """ 500 Returns all available templates 501 """ 502 def cmpTemplates(a, b): 503 return cmp(a.id.lower(), b.id.lower())
504 templates = self.getRRDTemplates() 505 templates.sort(cmpTemplates) 506 pdc = self.getPythonDeviceClass() 507 return [ t for t in templates 508 if issubclass(pdc, t.getTargetPythonClass()) ] 509 510
511 - def bindTemplates(self, ids=(), REQUEST=None):
512 """ 513 This will bind available templates to the zDeviceTemplates 514 """ 515 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
516
517 - def removeZDeviceTemplates(self, REQUEST=None):
518 """ 519 Deletes the local zProperty, zDeviceTemplates 520 """ 521 if self.getPrimaryPath()[-2:] == ('dmd', 'Devices'): 522 self.setZenProperty('zDeviceTemplates', ['Device']) 523 else: 524 self.deleteZenProperty('zDeviceTemplates') 525 messaging.IMessageSender(self).sendToBrowser( 526 'Bindings Reset', 527 'Template bindings for this class were reset.' 528 ) 529 return self.callZenScreen(REQUEST)
530 531
532 - def getAllRRDTemplates(self, rrdts=None):
533 """ 534 Return all RRDTemplates at this level and below in the object tree. 535 If rrdts is provided then it must be a list of RRDTemplates which 536 will be extended with the templates from here and returned. 537 538 The original getAllRRDTemplates() method has been renamed 539 getAllRRDTemplatesPainfully(). It walks the object tree looking 540 for templates which is a very slow way of going about things. 541 The newer RRDTemplate.YieldAllRRDTemplate() method uses the 542 searchRRDTemplates catalog to speed things up dramatically. 543 YieldAllRRDTemplates is smart enough to revert to 544 getAllRRDTemplatesPainfully if the catalog is not present. 545 546 The searchRRDTemplates catalog was added in 2.2 547 """ 548 if rrdts == None: 549 rrdts = [] 550 rrdts.extend(RRDTemplate.YieldAllRRDTemplates(self)) 551 return rrdts
552 553
554 - def getAllRRDTemplatesPainfully(self, rrdts=None):
555 """ 556 RRDTemplate.YieldAllRRDTemplates() is probably what you want. 557 It takes advantage of the searchRRDTemplates catalog to get 558 much better performance. This method iterates over objects looking 559 for templates which is a slow, painful process. 560 """ 561 if rrdts is None: rrdts = [] 562 rrdts.extend(self.rrdTemplates()) 563 for dev in self.devices(): 564 rrdts += dev.objectValues('RRDTemplate') 565 for comps in dev.getDeviceComponents(): 566 rrdts += comps.objectValues('RRDTemplate') 567 for child in self.children(): 568 child.getAllRRDTemplatesPainfully(rrdts) 569 return rrdts
570 571 572 security.declareProtected('Add DMD Objects', 'manage_addRRDTemplate')
573 - def manage_addRRDTemplate(self, id, REQUEST=None):
574 """ 575 Add an RRDTemplate to this DeviceClass. 576 """ 577 if not id: return self.callZenScreen(REQUEST) 578 id = self.prepId(id) 579 org = RRDTemplate.RRDTemplate(id) 580 self.rrdTemplates._setObject(org.id, org) 581 if REQUEST: 582 messaging.IMessageSender(self).sendToBrowser( 583 'Template Added', 584 'The "%s" template has been created.' % id 585 ) 586 return self.callZenScreen(REQUEST)
587 588 589 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 590 'manage_copyRRDTemplates')
591 - def manage_copyRRDTemplates(self, ids=(), REQUEST=None):
592 """ 593 Put a reference to the objects named in ids in the clip board 594 """ 595 if not ids: return self.callZenScreen(REQUEST) 596 ids = [ id for id in ids if self.rrdTemplates._getOb(id, None) != None] 597 if not ids: return self.callZenScreen(REQUEST) 598 cp = self.rrdTemplates.manage_copyObjects(ids) 599 if REQUEST: 600 resp=REQUEST['RESPONSE'] 601 resp.setCookie('__cp', cp, path='/zport/dmd') 602 REQUEST['__cp'] = cp 603 messaging.IMessageSender(self).sendToBrowser( 604 'Templates Copied', 605 'Templates have been copied: %s' % ', '.join(ids) 606 ) 607 return self.callZenScreen(REQUEST) 608 return cp
609 610 611 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 612 'manage_pasteRRDTemplates')
613 - def manage_pasteRRDTemplates(self, moveTarget=None, cb_copy_data=None, REQUEST=None):
614 """ 615 Paste RRDTemplates that have been copied before. 616 """ 617 cp = None 618 if cb_copy_data: cp = cb_copy_data 619 elif REQUEST: 620 cp = REQUEST.get("__cp",None) 621 622 if cp: 623 if moveTarget: 624 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 625 else: 626 target = self 627 target.rrdTemplates.manage_pasteObjects(cp) 628 else: 629 target = None 630 631 if REQUEST: 632 REQUEST['RESPONSE'].setCookie('__cp', 'deleted', path='/zport/dmd', 633 expires='Wed, 31-Dec-97 23:59:59 GMT') 634 REQUEST['__cp'] = None 635 if target: 636 message = "Template(s) moved to %s" % moveTarget 637 else: 638 message = None 639 messaging.IMessageSender(self).sendToBrowser( 640 'Templates Moved', 641 message 642 ) 643 if not isinstance(REQUEST, FakeRequest): 644 url = target.getPrimaryUrlPath() + '/perfConfig' 645 if message: 646 url += '?message=%s' % message 647 REQUEST['RESPONSE'].redirect(url) 648 else: 649 return self.callZenScreen(REQUEST)
650 651 652 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 653 'manage_copyAndPasteRRDTemplates')
654 - def manage_copyAndPasteRRDTemplates(self, ids=(), copyTarget=None, REQUEST=None):
655 """ 656 Copy the selected templates into the specified device class. 657 """ 658 if not ids: 659 messaging.IMessageSender(self).sendToBrowser( 660 'Invalid', 661 'No templates were selected.', 662 priority=messaging.WARNING 663 ) 664 return self.callZenScreen(REQUEST) 665 if copyTarget is None: 666 messaging.IMessageSender(self).sendToBrowser( 667 'Invalid', 668 'No target was selected.', 669 priority=messaging.WARNING 670 ) 671 return self.callZenScreen(REQUEST) 672 cp = self.manage_copyRRDTemplates(ids) 673 return self.manage_pasteRRDTemplates(copyTarget, cp, REQUEST)
674 675 676 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 677 'manage_deleteRRDTemplates')
678 - def manage_deleteRRDTemplates(self, ids=(), paths=(), REQUEST=None):
679 """ 680 Delete RRDTemplates from this DeviceClass 681 (skips ones in other Classes) 682 """ 683 if not ids and not paths: 684 return self.callZenScreen(REQUEST) 685 for id in ids: 686 if (getattr(aq_base(self), 'rrdTemplates', False) 687 and getattr(aq_base(self.rrdTemplates),id,False)): 688 self.rrdTemplates._delObject(id) 689 for path in paths: 690 temp = self.dmd.getObjByPath(path) 691 if temp.deviceClass(): 692 temp.deviceClass().rrdTemplates._delObject(temp.id) 693 else: 694 temp.device()._delObject(temp.id) 695 if REQUEST: 696 messaging.IMessageSender(self).sendToBrowser( 697 'Templates Deleted', 698 'Templates were deleted: %s' % ", ".join(ids) 699 ) 700 return self.callZenScreen(REQUEST)
701 702
703 - def createCatalog(self):
704 """ 705 Make the catalog for device searching 706 """ 707 from Products.ZCatalog.ZCatalog import manage_addZCatalog 708 709 # Make catalog for Devices 710 manage_addZCatalog(self, self.default_catalog, 711 self.default_catalog) 712 zcat = self._getOb(self.default_catalog) 713 cat = zcat._catalog 714 for idxname in ['id', 715 'getDeviceIp','getDeviceClassPath','getProdState']: 716 cat.addIndex(idxname, makeCaseInsensitiveFieldIndex(idxname)) 717 cat.addIndex('getPhysicalPath', makePathIndex('getPhysicalPath')) 718 cat.addIndex('path', makeMultiPathIndex('path')) 719 zcat.addColumn('getPrimaryId') 720 zcat.addColumn('id') 721 zcat.addColumn('path') 722 723 # make catalog for device components 724 manage_addZCatalog(self, "componentSearch", "componentSearch") 725 zcat = self._getOb("componentSearch") 726 cat = zcat._catalog 727 cat.addIndex('meta_type', makeCaseInsensitiveFieldIndex('meta_type')) 728 cat.addIndex('getParentDeviceName', 729 makeCaseInsensitiveFieldIndex('getParentDeviceName')) 730 cat.addIndex('getCollectors', 731 makeCaseInsensitiveKeywordIndex('getCollectors')) 732 # XXX still using regular FieldIndex here for now, since this contains 733 # binary information 734 zcat.addIndex('monitored', 'FieldIndex') 735 zcat.addColumn('getPrimaryId') 736 zcat.addColumn('meta_type')
737 738
739 - def reIndex(self):
740 """ 741 Go through all devices in this tree and reindex them. 742 """ 743 zcat = getToolByName(self, self.default_catalog) 744 zcat.manage_catalogClear() 745 self.componentSearch.manage_catalogClear() 746 transaction.savepoint() 747 for dev in self.getSubDevicesGen_recursive(): 748 dev.index_object() 749 for comp in dev.getDeviceComponentsNoIndexGen(): 750 comp.index_object() 751 transaction.savepoint()
752 753
754 - def buildDeviceTreeProperties(self):
755 """ 756 Create a new device tree with a default configuration 757 """ 758 devs = self.getDmdRoot("Devices") 759 if getattr(aq_base(devs), "zSnmpCommunities", False): return 760 761 # map deviec class to python classs (seperate from device class name) 762 devs._setProperty("zPythonClass", "") 763 764 # production state threshold at which to start monitoring boxes 765 devs._setProperty("zProdStateThreshold", 300, type="int") 766 767 # Display the ifdescripion field or not 768 devs._setProperty("zIfDescription", False, type="boolean") 769 770 # Snmp collection properties 771 devs._setProperty("zSnmpCommunities",["public", "private"],type="lines") 772 devs._setProperty("zSnmpCommunity", "public") 773 devs._setProperty("zSnmpPort", 161, type="int") 774 devs._setProperty("zSnmpVer", "v1") 775 devs._setProperty("zSnmpTries", 2, type="int") 776 devs._setProperty("zSnmpTimeout", 2.5, type="float") 777 devs._setProperty("zSnmpSecurityName", "") 778 devs._setProperty("zSnmpAuthPassword", "") 779 devs._setProperty("zSnmpPrivPassword", "") 780 devs._setProperty("zSnmpAuthType", "") 781 devs._setProperty("zSnmpPrivType", "") 782 devs._setProperty("zRouteMapCollectOnlyLocal", False, type="boolean") 783 devs._setProperty("zRouteMapCollectOnlyIndirect", False, type="boolean") 784 devs._setProperty("zRouteMapMaxRoutes", 500, type="int") 785 devs._setProperty("zInterfaceMapIgnoreTypes", "") 786 devs._setProperty("zInterfaceMapIgnoreNames", "") 787 devs._setProperty("zFileSystemMapIgnoreTypes", [], type="lines") 788 devs._setProperty("zFileSystemMapIgnoreNames", "") 789 devs._setProperty("zFileSystemSizeOffset", 1.0, type="float") 790 devs._setProperty("zHardDiskMapMatch", "") 791 devs._setProperty("zSysedgeDiskMapIgnoreNames", "") 792 devs._setProperty("zIpServiceMapMaxPort", 1024, type="int") 793 devs._setProperty("zDeviceTemplates", ["Device"], type="lines") 794 devs._setProperty("zLocalIpAddresses", "^127|^0\.0|^169\.254|^224") 795 devs._setProperty("zLocalInterfaceNames", "^lo|^vmnet") 796 797 798 # RRD properties 799 #FIXME - should this be added to allow for more flexability of 800 # RRDTemplate binding? 801 #devs._setProperty("zRRDTemplateName", "") 802 803 # Ping monitor properties 804 devs._setProperty("zPingInterfaceName", "") 805 devs._setProperty("zPingInterfaceDescription", "") 806 807 # Status monitor properites 808 devs._setProperty("zSnmpMonitorIgnore", False, type="boolean") 809 devs._setProperty("zPingMonitorIgnore", False, type="boolean") 810 devs._setProperty("zWmiMonitorIgnore", True, type="boolean") 811 devs._setProperty("zStatusConnectTimeout", 15.0, type="float") 812 813 # DataCollector properties 814 devs._setProperty("zCollectorPlugins", [], type='lines') 815 devs._setProperty("zCollectorClientTimeout", 180, type="int") 816 devs._setProperty("zCollectorDecoding", 'latin-1') 817 devs._setProperty("zCommandUsername", "") 818 devs._setProperty("zCommandPassword", "") 819 devs._setProperty("zCommandProtocol", "ssh") 820 devs._setProperty("zCommandPort", 22, type="int") 821 devs._setProperty("zCommandLoginTries", 1, type="int") 822 devs._setProperty("zCommandLoginTimeout", 10.0, type="float") 823 devs._setProperty("zCommandCommandTimeout", 10.0, type="float") 824 devs._setProperty("zCommandSearchPath", [], type="lines") 825 devs._setProperty("zCommandExistanceTest", "test -f %s") 826 devs._setProperty("zCommandPath", zenPath("libexec")) 827 devs._setProperty("zTelnetLoginRegex", "ogin:.$") 828 devs._setProperty("zTelnetPasswordRegex", "assword:") 829 devs._setProperty("zTelnetSuccessRegexList", 830 ['\$.$', '\#.$'], type="lines") 831 devs._setProperty("zTelnetEnable", False, type="boolean") 832 devs._setProperty("zTelnetEnableRegex", "assword:") 833 devs._setProperty("zTelnetTermLength", True, type="boolean") 834 devs._setProperty("zTelnetPromptTimeout", 10.0, type="float") 835 devs._setProperty("zKeyPath", "~/.ssh/id_dsa") 836 devs._setProperty("zMaxOIDPerRequest", 40, type="int") 837 838 # Extra stuff for users 839 devs._setProperty("zLinks", "") 840 841 # Device context Event Mapping 842 #FIXME this is half baked needs to be specific to an event class 843 #devs._setProperty("zEventSeverity", -1, type="int") 844 845 # Windows WMI collector properties 846 devs._setProperty("zWinUser", "") 847 devs._setProperty("zWinPassword", "") 848 devs._setProperty("zWinEventlogMinSeverity", 2, type="int") 849 devs._setProperty("zWinEventlog", False, type="boolean") 850 851 # Icon path 852 devs._setProperty("zIcon", "/zport/dmd/img/icons/noicon.png")
853 854
855 - def zenPropertyOptions(self, propname):
856 """ 857 Provide a set of default options for a zProperty 858 859 @param propname: zProperty name 860 @type propname: string 861 @return: list of zProperty options 862 @rtype: list 863 """ 864 if propname == 'zCollectorPlugins': 865 from Products.DataCollector.Plugins import loadPlugins 866 names = [ldr.pluginName() for ldr in loadPlugins(self.dmd)] 867 names.sort() 868 return names 869 if propname == 'zCommandProtocol': 870 return ['ssh', 'telnet'] 871 if propname == 'zSnmpVer': 872 return ['v1', 'v2c', 'v3'] 873 if propname == 'zSnmpAuthType': 874 return ['', 'MD5', 'SHA'] 875 if propname == 'zSnmpPrivType': 876 return ['', 'DES', 'AES'] 877 return DeviceOrganizer.zenPropertyOptions(self, propname)
878 879
880 - def pushConfig(self, REQUEST=None):
881 """ 882 This will result in a push of all the devices to live collectors 883 884 @param REQUEST: Zope REQUEST object 885 @type REQUEST: Zope REQUEST object 886 """ 887 self._p_changed = True 888 if REQUEST: 889 messaging.IMessageSender(self).sendToBrowser( 890 'Pushed Changes', 891 'Changes to %s were pushed to collectors.' % self.id 892 ) 893 return self.callZenScreen(REQUEST)
894 895 896 security.declareProtected('Change Device', 'setLastChange')
897 - def setLastChange(self, value=None):
898 """ 899 Set the changed datetime for this device. 900 901 @param value: changed datetime. Default is now. 902 @type value: number 903 """ 904 if value is None: 905 value = time.time() 906 self._lastChange = float(value)
907
908 - def register_devtype(self, description, protocol):
909 """ 910 Define this class in terms of a description of the devices it should 911 contain and the protocol by which they would normally be monitored. 912 """ 913 t = (description, protocol) 914 if not hasattr(self, 'devtypes'): 915 self._setProperty('devtypes', [], 'lines') 916 if t not in self.devtypes: 917 self.devtypes.append(t) 918 self._p_changed = True
919
920 - def unregister_devtype(self, description, protocol):
921 t = (description, protocol) 922 if hasattr(self, 'devtypes'): 923 if t in self.devtypes: 924 self.devtypes.remove(t) 925 self._p_changed = True
926 927 928 InitializeClass(DeviceClass) 929