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

Source Code for Module Products.ZenModel.DeviceClass

  1  ############################################################################## 
  2  # 
  3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  4  # 
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  # 
  8  ############################################################################## 
  9   
 10   
 11  __doc__="""DeviceClass 
 12  The primary organizer of device objects, managing zProperties and 
 13  their acquisition. 
 14  """ 
 15   
 16  import time 
 17  from cStringIO import StringIO 
 18  import transaction 
 19  import logging 
 20  log = logging.getLogger('zen.DeviceClass') 
 21   
 22  import DateTime 
 23  from zope.event import notify 
 24  from zope.container.contained import ObjectMovedEvent 
 25  from Globals import DTMLFile 
 26  from Globals import InitializeClass 
 27  from Acquisition import aq_base, aq_chain 
 28  from AccessControl import ClassSecurityInfo 
 29  from AccessControl import Permissions as permissions 
 30  from ZODB.transact import transact 
 31   
 32  from Products.AdvancedQuery import MatchGlob, Or, Eq, RankByQueries_Max, And 
 33  from Products.CMFCore.utils import getToolByName 
 34  from Products.ZenMessaging.ChangeEvents.events import DeviceClassMovedEvent 
 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, makeCaseInsensitiveFieldIndex, makeCaseSensitiveKeywordIndex 
 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.ZenUtils.guid.interfaces import IGlobalIdentifier 
 43  from Products.ZenWidgets import messaging 
 44  from Products.ZenUtils.FakeRequest import FakeRequest 
 45  from Products.Zuul.catalog.events import IndexingEvent 
 46  from Products.Zuul.interfaces import ICatalogTool 
 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(key=lambda a: a.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 @transact
190 - def _moveDevice(self, devname, target, targetClass):
191 dev = self.findDeviceByIdExact(devname) 192 if not dev: 193 return 194 guid = IGlobalIdentifier(dev).create() 195 source = dev.deviceClass().primaryAq() 196 197 notify(DeviceClassMovedEvent(dev, dev.deviceClass().primaryAq(), target)) 198 199 exported = False 200 oldPath = source.absolute_url_path() + '/' 201 if dev.__class__ != targetClass: 202 from Products.ZenRelations.ImportRM import NoLoginImportRM 203 204 def switchClass(o, module, klass): 205 """ 206 Create an XML string representing the module in a 207 new class. 208 209 @param o: file-type object 210 @type o: file-type object 211 @param module: location in DMD 212 @type module: string 213 @param klass: class name 214 @type klass: string 215 @return: XML representation of the class 216 @rtype: string 217 """ 218 from xml.dom.minidom import parse 219 220 # Note: strips almost everything out of the move 221 # as the new class may not have the same relations etc. 222 # For example, moving SNMP host to a VMware class. 223 o.seek(0) 224 dom = parse(o) 225 root = dom.childNodes[0] 226 root.setAttribute('module', module) 227 root.setAttribute('class', klass) 228 for obj in root.childNodes: 229 if obj.nodeType != obj.ELEMENT_NODE: 230 continue # Keep XML-tree baggage 231 232 name = obj.getAttribute('id') 233 if obj.tagName == 'property': 234 # Only remove modeler plugins, templates 235 # and z*Ignore zprops 236 if name in ('zCollectorPlugins', 'zDeviceTemplates') or \ 237 name.endswith('Ignore'): 238 root.removeChild(obj) 239 240 elif obj.tagName == 'toone' and \ 241 name in ('perfServer', 'location'): 242 pass # Preserve collector name and location 243 244 elif obj.tagName == 'tomany' and \ 245 name in ('systems', 'groups'): 246 pass # Preserve the Groups and Systems groupings 247 248 elif obj.tagName == 'tomanycont' and \ 249 name in ('maintenanceWindows', 250 'adminRoles', 251 'userCommands'): 252 pass # Preserve maintenance windows, admins, commands 253 254 else: 255 log.debug("Removing %s element id='%s'", 256 obj.tagName, name) 257 root.removeChild(obj) 258 259 importFile = StringIO() 260 dom.writexml(importFile) 261 importFile.seek(0) 262 return importFile
263 264 def devExport(d, module, klass): 265 """ 266 Create an XML string representing the device d 267 at the DMD location module of type klass. 268 269 @param module: location in DMD 270 @type module: string 271 @param klass: class name 272 @type klass: string 273 @return: XML representation of the class 274 @rtype: string 275 """ 276 o = StringIO() 277 d.exportXml(o, exportPasswords=True) 278 return switchClass(o, module, klass)
279 280 def devImport(xmlfile): 281 """ 282 Load a new device from a file. 283 284 @param xmlfile: file type object 285 @type xmlfile: file type object 286 """ 287 im = NoLoginImportRM(target.devices) 288 im.loadObjectFromXML(xmlfile) 289 im.processLinks() 290 291 module = target.zPythonClass 292 if module: 293 klass = target.zPythonClass.split('.')[-1] 294 else: 295 module = 'Products.ZenModel.Device' 296 klass = 'Device' 297 log.debug('Exporting device %s from %s', devname, source) 298 xmlfile = devExport(dev, module, klass) 299 log.debug('Removing device %s from %s', devname, source) 300 source.devices._delObject(devname) 301 log.debug('Importing device %s to %s', devname, target) 302 devImport(xmlfile) 303 exported = True 304 else: 305 dev._operation = 1 306 source.devices._delObject(devname) 307 target.devices._setObject(devname, dev) 308 dev = target.devices._getOb(devname) 309 IGlobalIdentifier(dev).guid = guid 310 dev.setLastChange() 311 dev.setAdminLocalRoles() 312 dev.index_object() 313 notify(IndexingEvent(dev, idxs=('path', 'searchKeywords'), 314 update_metadata=True)) 315 316 return exported 317
318 - def moveDevices(self, moveTarget, deviceNames=None, REQUEST=None):
319 """ 320 Override default moveDevices because this is a contained relation. 321 If the Python class bound to a DeviceClass is different we convert to 322 the new Python class adding / removing relationships as needed. 323 324 @param moveTarget: organizer in DMD path 325 @type moveTarget: string 326 @param deviceNames: devices to move 327 @type deviceNames: list of stringa 328 @param REQUEST: Zope REQUEST object 329 @type REQUEST: Zope REQUEST object 330 """ 331 if not moveTarget or not deviceNames: return self() 332 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 333 if isinstance(deviceNames, basestring): deviceNames = (deviceNames,) 334 targetClass = target.getPythonDeviceClass() 335 numExports = 0 336 for devname in deviceNames: 337 devicewasExported = self._moveDevice(devname, target, targetClass) 338 if devicewasExported: 339 numExports += 1 340 return numExports
341 342 343 security.declareProtected(ZEN_DELETE_DEVICE, 'removeDevices')
344 - def removeDevices(self, deviceNames=None, deleteStatus=False, 345 deleteHistory=False, deletePerf=False,REQUEST=None):
346 """ 347 See IManageDevice overrides DeviceManagerBase.removeDevices 348 """ 349 if not deviceNames: return self() 350 if isinstance(deviceNames, basestring): deviceNames = (deviceNames,) 351 for devname in deviceNames: 352 dev = self.findDevice(devname) 353 dev.deleteDevice(deleteStatus=deleteStatus, 354 deleteHistory=deleteHistory, deletePerf=deletePerf) 355 if REQUEST: 356 messaging.IMessageSender(self).sendToBrowser( 357 'Devices Deleted', 358 "Devices were deleted: %s." % ', '.join(deviceNames) 359 ) 360 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 361 return 'Devices were deleted: %s.' % ', '.join(deviceNames) 362 else: 363 return self.callZenScreen(REQUEST)
364 365 366 security.declareProtected('View', 'getEventDeviceInfo')
367 - def getEventDeviceInfo(self):
368 """ 369 getEventDeviceInfo() -> return the info for NcoEventPopulator 370 """ 371 deviceInfo = {} 372 for device in self.getSubDevices(): 373 systemNames = [] 374 for sys in device.systems.objectValuesAll(): 375 systemNames.append(sys.getOrganizerName()) 376 systemNames = "|".join(systemNames) 377 location = device.getLocationName() 378 if not location: location = "Unknown" 379 deviceInfo[device.id] = (systemNames, location, 380 device.productionState, 381 device.getDeviceClassPath()) 382 return deviceInfo
383 384 385 security.declareProtected('View', 'getDeviceWinInfo')
386 - def getDeviceWinInfo(self, lastPoll=0, eventlog=False):
387 """ 388 Return list of (devname,user,passwd,url) for each device. 389 user and passwd are used to connect via wmi. 390 """ 391 ffunc = None 392 starttime = time.time() 393 if lastPoll > 0: 394 lastPoll = DateTime.DateTime(lastPoll) 395 ffunc = lambda x: x.getSnmpLastCollection() > lastPoll 396 if eventlog: 397 ffunc = lambda x: x.getProperty('zWinEventlog', False) 398 devinfo = [] 399 for dev in self.getSubDevices(devfilter=ffunc): 400 if not dev.monitorDevice(): continue 401 if dev.getProperty('zWmiMonitorIgnore', False): continue 402 user = dev.getProperty('zWinUser','') 403 passwd = dev.getProperty( 'zWinPassword', '') 404 sev = dev.getProperty( 'zWinEventlogMinSeverity', '') 405 devinfo.append((dev.id, str(user), str(passwd), sev, dev.absolute_url())) 406 return starttime, devinfo
407 408
409 - def getWinServices(self):
410 """ 411 Return a list of (devname, user, passwd, {'EvtSys':0,'Exchange':0}) 412 """ 413 svcinfo = [] 414 allsvcs = {} 415 for s in self.getSubComponents("WinService"): 416 svcs=allsvcs.setdefault(s.hostname(),{}) 417 name = s.name() 418 if isinstance(name, unicode): 419 name = name.encode(s.zCollectorDecoding) 420 svcs[name] = (s.getStatus(), s.getAqProperty('zFailSeverity')) 421 for dev in self.getSubDevices(): 422 if not dev.monitorDevice(): continue 423 if dev.getProperty( 'zWmiMonitorIgnore', False): continue 424 svcs = allsvcs.get(dev.getId(), {}) 425 if not svcs and not dev.getProperty('zWinEventlog', False): continue 426 user = dev.getProperty('zWinUser','') 427 passwd = dev.getProperty( 'zWinPassword', '') 428 svcinfo.append((dev.id, str(user), str(passwd), svcs)) 429 return svcinfo
430 431 432 security.declareProtected('View', 'searchDeviceSummary')
433 - def searchDeviceSummary(self, query):
434 """ 435 Search device summary index and return device objects 436 """ 437 if not query: return [] 438 zcatalog = self._getCatalog() 439 if not zcatalog: return [] 440 results = zcatalog({'summary':query}) 441 return self._convertResultsToObj(results)
442 443 444 security.declareProtected('View', 'searchInterfaces')
445 - def searchInterfaces(self, query):
446 """ 447 Search interfaces index and return interface objects 448 """ 449 if not query: return [] 450 zcatalog = getattr(self, 'interfaceSearch', None) 451 if not zcatalog: return [] 452 results = zcatalog(query) 453 return self._convertResultsToObj(results)
454 455
456 - def _convertResultsToObj(self, results):
457 devices = [] 458 for brain in results: 459 try: 460 devobj = self.getObjByPath(brain.getPrimaryId) 461 devices.append(devobj) 462 except KeyError: 463 log.warn("bad path '%s' in index" % brain.getPrimaryId) 464 465 return devices
466
467 - def _findDevice(self, devicename, useTitle=True):
468 """ 469 Returns all devices whose ip/id/title match devicename. 470 ip/id matches are at the front of the list. 471 472 @rtype: list of brains 473 """ 474 idIpQuery = Or( MatchGlob('id', devicename), 475 Eq('getDeviceIp', devicename) ) 476 if useTitle: 477 titleOrIdQuery = MatchGlob('titleOrId', devicename) 478 query = Or( idIpQuery, titleOrIdQuery ) 479 rankSort = RankByQueries_Max( ( idIpQuery, 16 ), 480 ( titleOrIdQuery, 8 ) ) 481 devices = self._getCatalog().evalAdvancedQuery(query, (rankSort,)) 482 else: 483 devices = self._getCatalog().evalAdvancedQuery(idIpQuery) 484 return devices
485
486 - def findDevicePath(self, devicename):
487 """ 488 Look up a device and return its path 489 """ 490 ret = self._findDevice(devicename) 491 if not ret: return "" 492 return ret[0].getPrimaryId
493
494 - def findDevice(self, devicename):
495 """ 496 Returns the first device whose ip/id matches devicename. If 497 there is no ip/id match, return the first device whose title 498 matches devicename. 499 """ 500 ret = self._findDevice(devicename) 501 if ret: return ret[0].getObject()
502
503 - def findDeviceByIdOrIp(self, devicename):
504 """ 505 Returns the first device that has an ip/id that matches devicename 506 """ 507 ret = self._findDevice( devicename, False ) 508 if ret: return ret[0].getObject()
509
510 - def findDeviceByIdExact(self, devicename):
511 """ 512 Look up device in catalog and return it. devicename 513 must match device id exactly 514 """ 515 for brains in self._getCatalog()(id=devicename): 516 dev = brains.getObject() 517 if dev.id == devicename: 518 return dev
519
520 - def findDevicePingStatus(self, devicename):
521 """ 522 look up device in catalog and return its pingStatus 523 """ 524 dev = self.findDevice(devicename) 525 if dev: return dev.getPingStatusNumber()
526 527
528 - def getSubComponents(self, meta_type="", monitored=True):
529 """ 530 Return generator of components, by meta_type if specified 531 """ 532 catalog = ICatalogTool(self) 533 COMPONENT = 'Products.ZenModel.DeviceComponent.DeviceComponent' 534 monitorq, typeq = None, None 535 if monitored: 536 monitorq = Eq('monitored', '1') 537 if meta_type: 538 typeq = Eq('meta_type', meta_type) 539 queries = filter(None, (monitorq, typeq)) 540 if queries: 541 query = And(*queries) if len(queries) > 1 else queries[0] 542 else: 543 query = None 544 for brain in catalog.search(COMPONENT, query=query): 545 try: 546 yield brain.getObject() 547 except KeyError: 548 log.warn("bad path '%s' in global catalog", brain.getPath())
549 550 551 security.declareProtected("ZenCommon", "getMonitoredComponents")
552 - def getMonitoredComponents(self):
553 """ 554 Return monitored components for devices within this DeviceDeviceClass 555 """ 556 return self.getSubComponents()
557 558 559 security.declareProtected('View', 'getRRDTemplates')
560 - def getRRDTemplates(self, context=None):
561 """ 562 Return the actual RRDTemplate instances. 563 """ 564 templates = {} 565 if not context: context = self 566 mychain = aq_chain(context) 567 mychain.reverse() 568 for obj in mychain: 569 try: 570 templates.update(dict((t.id, t) for t in obj.rrdTemplates())) 571 except AttributeError: 572 pass 573 return templates.values()
574 575
576 - def getAvailableTemplates(self):
577 """ 578 Returns all available templates 579 """ 580 pdc = self.getPythonDeviceClass() 581 templates = filter(lambda t: issubclass(pdc, t.getTargetPythonClass()), 582 self.getRRDTemplates()) 583 return sorted(templates, key=lambda a: a.id.lower())
584 585
586 - def bindTemplates(self, ids=(), REQUEST=None):
587 """ 588 This will bind available templates to the zDeviceTemplates 589 """ 590 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
591
592 - def removeZDeviceTemplates(self, REQUEST=None):
593 """ 594 Deletes the local zProperty, zDeviceTemplates 595 """ 596 if self.getPrimaryPath()[-2:] == ('dmd', 'Devices'): 597 self.setZenProperty('zDeviceTemplates', ['Device']) 598 else: 599 self.deleteZenProperty('zDeviceTemplates') 600 messaging.IMessageSender(self).sendToBrowser( 601 'Bindings Reset', 602 'Template bindings for this class were reset.' 603 ) 604 return self.callZenScreen(REQUEST)
605 606
607 - def getAllRRDTemplates(self, rrdts=None):
608 """ 609 Return all RRDTemplates at this level and below in the object tree. 610 If rrdts is provided then it must be a list of RRDTemplates which 611 will be extended with the templates from here and returned. 612 613 The original getAllRRDTemplates() method has been renamed 614 getAllRRDTemplatesPainfully(). It walks the object tree looking 615 for templates which is a very slow way of going about things. 616 The newer RRDTemplate.YieldAllRRDTemplate() method uses the 617 searchRRDTemplates catalog to speed things up dramatically. 618 YieldAllRRDTemplates is smart enough to revert to 619 getAllRRDTemplatesPainfully if the catalog is not present. 620 621 The searchRRDTemplates catalog was added in 2.2 622 """ 623 if rrdts is None: 624 rrdts = [] 625 rrdts.extend(RRDTemplate.YieldAllRRDTemplates(self)) 626 return rrdts
627 628
629 - def getAllRRDTemplatesPainfully(self, rrdts=None):
630 """ 631 RRDTemplate.YieldAllRRDTemplates() is probably what you want. 632 It takes advantage of the searchRRDTemplates catalog to get 633 much better performance. This method iterates over objects looking 634 for templates which is a slow, painful process. 635 """ 636 if rrdts is None: rrdts = [] 637 rrdts.extend(self.rrdTemplates()) 638 for dev in self.devices(): 639 rrdts += dev.objectValues('RRDTemplate') 640 for comps in dev.getDeviceComponents(): 641 rrdts += comps.objectValues('RRDTemplate') 642 for child in self.children(): 643 child.getAllRRDTemplatesPainfully(rrdts) 644 return rrdts
645 646 647 security.declareProtected('Add DMD Objects', 'manage_addRRDTemplate')
648 - def manage_addRRDTemplate(self, id, REQUEST=None):
649 """ 650 Add an RRDTemplate to this DeviceClass. 651 """ 652 if not id: return self.callZenScreen(REQUEST) 653 id = self.prepId(id) 654 org = RRDTemplate.RRDTemplate(id) 655 self.rrdTemplates._setObject(org.id, org) 656 if REQUEST: 657 messaging.IMessageSender(self).sendToBrowser( 658 'Template Added', 659 'The "%s" template has been created.' % id 660 ) 661 return self.callZenScreen(REQUEST)
662 663 664 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 665 'manage_copyRRDTemplates')
666 - def manage_copyRRDTemplates(self, ids=(), REQUEST=None):
667 """ 668 Put a reference to the objects named in ids in the clip board 669 """ 670 if not ids: return self.callZenScreen(REQUEST) 671 ids = [ id for id in ids if self.rrdTemplates._getOb(id, None) is not None] 672 if not ids: return self.callZenScreen(REQUEST) 673 cp = self.rrdTemplates.manage_copyObjects(ids) 674 if REQUEST: 675 resp=REQUEST['RESPONSE'] 676 resp.setCookie('__cp', cp, path='/zport/dmd') 677 REQUEST['__cp'] = cp 678 messaging.IMessageSender(self).sendToBrowser( 679 'Templates Copied', 680 'Templates have been copied: %s' % ', '.join(ids) 681 ) 682 return self.callZenScreen(REQUEST) 683 return cp
684 685 686 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 687 'manage_pasteRRDTemplates')
688 - def manage_pasteRRDTemplates(self, moveTarget=None, cb_copy_data=None, REQUEST=None):
689 """ 690 Paste RRDTemplates that have been copied before. 691 """ 692 cp = None 693 if cb_copy_data: cp = cb_copy_data 694 elif REQUEST: 695 cp = REQUEST.get("__cp",None) 696 697 if cp: 698 if moveTarget: 699 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 700 else: 701 target = self 702 target.rrdTemplates.manage_pasteObjects(cp) 703 else: 704 target = None 705 706 if REQUEST: 707 REQUEST['RESPONSE'].setCookie('__cp', 'deleted', path='/zport/dmd', 708 expires='Wed, 31-Dec-97 23:59:59 GMT') 709 REQUEST['__cp'] = None 710 if target: 711 message = "Template(s) copied to %s" % moveTarget 712 else: 713 message = None 714 messaging.IMessageSender(self).sendToBrowser( 715 'Template(s) Copied', 716 message 717 ) 718 if not isinstance(REQUEST, FakeRequest): 719 url = target.getPrimaryUrlPath() + '/perfConfig' 720 if message: 721 url += '?message=%s' % message 722 REQUEST['RESPONSE'].redirect(url) 723 else: 724 return self.callZenScreen(REQUEST)
725 726 727 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 728 'manage_copyAndPasteRRDTemplates')
729 - def manage_copyAndPasteRRDTemplates(self, ids=(), copyTarget=None, REQUEST=None):
730 """ 731 Copy the selected templates into the specified device class. 732 """ 733 if not ids: 734 messaging.IMessageSender(self).sendToBrowser( 735 'Invalid', 736 'No templates were selected.', 737 priority=messaging.WARNING 738 ) 739 return self.callZenScreen(REQUEST) 740 if copyTarget is None: 741 messaging.IMessageSender(self).sendToBrowser( 742 'Invalid', 743 'No target was selected.', 744 priority=messaging.WARNING 745 ) 746 return self.callZenScreen(REQUEST) 747 cp = self.manage_copyRRDTemplates(ids) 748 return self.manage_pasteRRDTemplates(copyTarget, cp, REQUEST)
749 750 751 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 752 'manage_deleteRRDTemplates')
753 - def manage_deleteRRDTemplates(self, ids=(), paths=(), REQUEST=None):
754 """ 755 Delete RRDTemplates from this DeviceClass 756 (skips ones in other Classes) 757 """ 758 if not ids and not paths: 759 return self.callZenScreen(REQUEST) 760 for id in ids: 761 if (getattr(aq_base(self), 'rrdTemplates', False) 762 and getattr(aq_base(self.rrdTemplates),id,False)): 763 self.rrdTemplates._delObject(id) 764 for path in paths: 765 temp = self.dmd.getObjByPath(path) 766 if temp.deviceClass(): 767 temp.deviceClass().rrdTemplates._delObject(temp.id) 768 else: 769 temp.device()._delObject(temp.id) 770 if REQUEST: 771 messaging.IMessageSender(self).sendToBrowser( 772 'Templates Deleted', 773 'Templates were deleted: %s' % ", ".join(ids) 774 ) 775 return self.callZenScreen(REQUEST)
776 777
778 - def createCatalog(self):
779 """ 780 Make the catalog for device searching 781 """ 782 from Products.ZCatalog.ZCatalog import manage_addZCatalog 783 784 # Make catalog for Devices 785 manage_addZCatalog(self, self.default_catalog, 786 self.default_catalog) 787 zcat = self._getOb(self.default_catalog) 788 cat = zcat._catalog 789 for idxname in ['id', 790 'getDeviceIp','getDeviceClassPath','getProdState','titleOrId']: 791 cat.addIndex(idxname, makeCaseInsensitiveFieldIndex(idxname)) 792 cat.addIndex('getPhysicalPath', makePathIndex('getPhysicalPath')) 793 cat.addIndex('path', makeMultiPathIndex('path')) 794 zcat.addColumn('getPrimaryId') 795 zcat.addColumn('id') 796 zcat.addColumn('path')
797
798 - def reIndex(self):
799 """ 800 Go through all devices in this tree and reindex them. 801 """ 802 zcat = getToolByName(self, self.default_catalog) 803 zcat.manage_catalogClear() 804 for dev in self.getSubDevicesGen_recursive(): 805 if dev.hasObject('componentSearch'): 806 dev._delObject('componentSearch') 807 dev._create_componentSearch() 808 dev.index_object() 809 notify(IndexingEvent(dev)) 810 for comp in dev.getDeviceComponentsNoIndexGen(): 811 notify(IndexingEvent(comp))
812 813
814 - def buildDeviceTreeProperties(self):
815 """ 816 Create a new device tree with a default configuration 817 """ 818 devs = self.getDmdRoot("Devices") 819 for id, value, type in Z_PROPERTIES: 820 if not devs.hasProperty(id): 821 devs._setProperty(id, value, type)
822
823 - def zenPropertyOptions(self, propname):
824 """ 825 Provide a set of default options for a zProperty 826 827 @param propname: zProperty name 828 @type propname: string 829 @return: list of zProperty options 830 @rtype: list 831 """ 832 if propname == 'zCollectorPlugins': 833 from Products.DataCollector.Plugins import loadPlugins 834 return sorted(ldr.pluginName for ldr in loadPlugins(self.dmd)) 835 if propname == 'zCommandProtocol': 836 return ['ssh', 'telnet'] 837 if propname == 'zSnmpVer': 838 return ['v1', 'v2c', 'v3'] 839 if propname == 'zSnmpAuthType': 840 return ['', 'MD5', 'SHA'] 841 if propname == 'zSnmpPrivType': 842 return ['', 'DES', 'AES'] 843 return DeviceOrganizer.zenPropertyOptions(self, propname)
844 845
846 - def pushConfig(self, REQUEST=None):
847 """ 848 This will result in a push of all the devices to live collectors 849 850 @param REQUEST: Zope REQUEST object 851 @type REQUEST: Zope REQUEST object 852 """ 853 self._p_changed = True 854 if REQUEST: 855 messaging.IMessageSender(self).sendToBrowser( 856 'Pushed Changes', 857 'Changes to %s were pushed to collectors.' % self.id 858 ) 859 return self.callZenScreen(REQUEST)
860 861 862 security.declareProtected('Change Device', 'setLastChange')
863 - def setLastChange(self, value=None):
864 """ 865 Set the changed datetime for this device. 866 867 @param value: changed datetime. Default is now. 868 @type value: number 869 """ 870 if value is None: 871 value = time.time() 872 self._lastChange = float(value)
873
874 - def register_devtype(self, description, protocol):
875 """ 876 Define this class in terms of a description of the devices it should 877 contain and the protocol by which they would normally be monitored. 878 """ 879 t = (description, protocol) 880 if not self.isLocal('devtypes'): 881 self._setProperty('devtypes', [], 'lines') 882 if t not in self.devtypes: 883 self.devtypes.append(t) 884 self._p_changed = True
885
886 - def unregister_devtype(self, description, protocol):
887 t = (description, protocol) 888 if hasattr(self, 'devtypes'): 889 if t in self.devtypes: 890 self.devtypes.remove(t) 891 self._p_changed = True
892 893 894 InitializeClass(DeviceClass) 895