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

Source Code for Module ZenModel.Device

   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  import os 
  15  import sys 
  16  import re 
  17  import time 
  18  import types 
  19  import socket 
  20  import logging 
  21  log = logging.getLogger("zen.Device") 
  22  from popen2 import Popen4 
  23   
  24  from _mysql_exceptions import OperationalError 
  25   
  26  from Products.ZenUtils.Graphics import NetworkGraph 
  27  from Products.ZenUtils.Utils import setWebLoggingStream, clearWebLoggingStream 
  28  from Products.ZenUtils.Utils import zenPath 
  29  from Products.ZenUtils import Time 
  30  import RRDView 
  31   
  32  # base classes for device 
  33  from ManagedEntity import ManagedEntity 
  34   
  35  from AccessControl import ClassSecurityInfo 
  36  from Globals import DTMLFile 
  37  from Globals import InitializeClass 
  38  from Acquisition import aq_base 
  39  from DateTime import DateTime 
  40  from App.Dialogs import MessageDialog 
  41   
  42  from ZODB.POSException import POSError 
  43  from ZenossSecurity import * 
  44   
  45  #from Products.SnmpCollector.SnmpCollector import findSnmpCommunity 
  46  from Products.DataCollector.ApplyDataMap import ApplyDataMap 
  47   
  48  from Products.ZenRelations.RelSchema import * 
  49  from Products.ZenUtils.IpUtil import isip 
  50  from Products.ZenEvents.ZenEventClasses import Status_Snmp 
  51  from UserCommand import UserCommand 
  52  from Commandable import Commandable 
  53  from Lockable import Lockable 
  54  from MaintenanceWindowable import MaintenanceWindowable 
  55  from AdministrativeRoleable import AdministrativeRoleable 
  56  from ZenMenuable import ZenMenuable 
  57   
  58  from OperatingSystem import OperatingSystem 
  59  from DeviceHW import DeviceHW 
  60   
  61  from ZenStatus import ZenStatus 
  62  from Exceptions import * 
  63  from ZenossSecurity import * 
  64  from Products.ZenUtils.Utils import edgesToXML 
  65  from Products.ZenUtils import NetworkTree 
  66   
67 -def manage_createDevice(context, deviceName, devicePath="/Discovered", 68 tag="", serialNumber="", 69 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="", 70 rackSlot=0, productionState=1000, comments="", 71 hwManufacturer="", hwProductName="", 72 osManufacturer="", osProductName="", 73 locationPath="", groupPaths=[], systemPaths=[], 74 statusMonitors=["localhost"], performanceMonitor="localhost", 75 discoverProto="snmp", priority=3):
76 """ 77 Device factory creates a device and sets up its relations and collects its 78 configuration. SNMP Community discovery also happens here. If an IP is 79 passed for deviceName it will be used for collection and the device name 80 will be set to the SNMP SysName (or ptr if SNMP Fails and ptr is valid) 81 82 @rtype: Device 83 """ 84 if isip(deviceName): 85 ip = deviceName 86 deviceName = "" 87 ipobj = context.getDmdRoot('Networks').findIp(ip) 88 if ipobj: 89 dev = ipobj.device() 90 if dev: 91 raise DeviceExistsError("Ip %s exists on %s" % (ip, deviceName)) 92 else: 93 deviceName = context.prepId(deviceName) 94 try: ip = socket.gethostbyname(deviceName) 95 except socket.error: ip = "" 96 if context.getDmdRoot("Devices").findDevice(deviceName): 97 raise DeviceExistsError("Device %s already exists" % deviceName) 98 if not ip: 99 raise NoIPAddress("No IP found for name %s" % deviceName) 100 if discoverProto == "snmp": 101 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \ 102 findCommunity(context, ip, devicePath, 103 zSnmpCommunity, zSnmpPort, zSnmpVer) 104 log.debug("device community = %s", zSnmpCommunity) 105 log.debug("device version = %s", zSnmpVer) 106 log.debug("device name = %s", snmpname) 107 if not deviceName: 108 try: 109 if snmpname and socket.gethostbyname(snmpname): 110 deviceName = snmpname 111 except socket.error: pass 112 try: 113 if (not deviceName and ipobj and ipobj.ptrName 114 and socket.gethostbyname(ipobj.ptrName)): 115 deviceName = ipobj.ptrName 116 except socket.error: pass 117 if not deviceName and snmpname: 118 deviceName = snmpname 119 if not deviceName: 120 log.warn("unable to name device using ip '%s'", ip) 121 deviceName = ip 122 elif discoverProto == "command": 123 raise ZenModelError("discover protocol 'ssh' not implemented yet") 124 if not deviceName: 125 deviceName = ip 126 log.info("device name '%s' for ip '%s'", deviceName, ip) 127 deviceClass = context.getDmdRoot("Devices").createOrganizer(devicePath) 128 deviceName = context.prepId(deviceName) 129 device = deviceClass.createInstance(deviceName) 130 device.setManageIp(ip) 131 device.manage_editDevice( 132 tag, serialNumber, 133 zSnmpCommunity, zSnmpPort, zSnmpVer, 134 rackSlot, productionState, comments, 135 hwManufacturer, hwProductName, 136 osManufacturer, osProductName, 137 locationPath, groupPaths, systemPaths, 138 statusMonitors, performanceMonitor, priority) 139 # Not sure why this was important but it causes issues if 140 # we are adding an alias to an existing box. It will take 141 # away that boxes IP. It also seems to make a network with 142 # the wrong netmask. 143 # if discoverProto == "none": 144 # from Products.ZenModel.IpInterface import IpInterface 145 # tmpInterface = IpInterface('eth0') 146 # device.os.interfaces._setObject('eth0', tmpInterface) 147 # interface = device.getDeviceComponents()[0] 148 # interface.addIpAddress(device.getManageIp()) 149 return device
150 151
152 -def findCommunity(context, ip, devicePath, 153 community="", port=None, version=None):
154 """ 155 Find the SNMP community and version for an p address using zSnmpCommunities. 156 157 @rtype: tuple of (community, port, version, device name) 158 """ 159 try: 160 from pynetsnmp.SnmpSession import SnmpSession 161 except: 162 from Products.DataCollector.SnmpSession import SnmpSession 163 164 devroot = context.getDmdRoot('Devices').createOrganizer(devicePath) 165 communities = [] 166 if community: communities.append(community) 167 communities.extend(getattr(devroot, "zSnmpCommunities", [])) 168 if not port: port = getattr(devroot, "zSnmpPort", 161) 169 versions = ('v2c', 'v1') 170 if version: versions = (version) 171 timeout = getattr(devroot, "zSnmpTimeout", 2) 172 retries = getattr(devroot, "zSnmpTries", 2) 173 session = SnmpSession(ip, timeout=timeout, port=port, retries=retries) 174 sysTableOid = '.1.3.6.1.2.1.1' 175 oid = '.1.3.6.1.2.1.1.5.0' 176 goodcommunity = "" 177 goodversion = "" 178 devname = "" 179 for version in versions: 180 session.setVersion(version) 181 for community in communities: 182 session.community = community 183 try: 184 devname = session.get(oid).values()[0] 185 goodcommunity = session.community 186 goodversion = version 187 break 188 except (SystemExit, KeyboardInterrupt, POSError): raise 189 except: pass #keep trying until we run out 190 if goodcommunity: 191 break 192 else: 193 raise NoSnmp("no snmp found for ip = %s" % ip) 194 return (goodcommunity, port, goodversion, devname)
195
196 -def manage_addDevice(context, id, REQUEST = None):
197 """ 198 Creates a device 199 """ 200 serv = Device(id) 201 context._setObject(serv.id, serv) 202 if REQUEST is not None: 203 REQUEST['message'] = "Device created" 204 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
205 206 207 addDevice = DTMLFile('dtml/addDevice',globals()) 208 209
210 -class Device(ManagedEntity, Commandable, Lockable, MaintenanceWindowable, 211 AdministrativeRoleable, ZenMenuable):
212 """ 213 Device is a base class that represents the idea of a single computer system 214 that is made up of software running on hardware. It currently must be IP 215 enabled but maybe this will change. 216 """ 217 218 event_key = portal_type = meta_type = 'Device' 219 220 default_catalog = "deviceSearch" #device ZCatalog 221 222 relationshipManagerPathRestriction = '/Devices' 223 224 manageIp = "" 225 productionState = 1000 226 snmpAgent = "" 227 snmpDescr = "" 228 snmpOid = "" 229 snmpContact = "" 230 snmpSysName = "" 231 snmpLocation = "" 232 rackSlot = 0 233 comments = "" 234 sysedgeLicenseMode = "" 235 priority = 3 236 237 _properties = ManagedEntity._properties + ( 238 {'id':'manageIp', 'type':'string', 'mode':'w'}, 239 {'id':'productionState', 'type':'keyedselection', 'mode':'w', 240 'select_variable':'getProdStateConversions','setter':'setProdState'}, 241 {'id':'snmpAgent', 'type':'string', 'mode':'w'}, 242 {'id':'snmpDescr', 'type':'string', 'mode':''}, 243 {'id':'snmpOid', 'type':'string', 'mode':''}, 244 {'id':'snmpContact', 'type':'string', 'mode':''}, 245 {'id':'snmpSysName', 'type':'string', 'mode':''}, 246 {'id':'snmpLocation', 'type':'string', 'mode':''}, 247 {'id':'snmpLastCollection', 'type':'date', 'mode':''}, 248 {'id':'snmpAgent', 'type':'string', 'mode':''}, 249 {'id':'rackSlot', 'type':'int', 'mode':'w'}, 250 {'id':'comments', 'type':'text', 'mode':'w'}, 251 {'id':'sysedgeLicenseMode', 'type':'string', 'mode':''}, 252 {'id':'priority', 'type':'int', 'mode':'w'}, 253 ) 254 255 _relations = ManagedEntity._relations + ( 256 ("deviceClass", ToOne(ToManyCont, "Products.ZenModel.DeviceClass", 257 "devices")), 258 #("termserver", ToOne(ToMany, "Products.ZenModel.TerminalServer", 259 # "devices")), 260 ("monitors", ToMany(ToMany, "Products.ZenModel.StatusMonitorConf", 261 "devices")), 262 ("perfServer", ToOne(ToMany, "Products.ZenModel.PerformanceConf", 263 "devices")), 264 ("location", ToOne(ToMany, "Products.ZenModel.Location", "devices")), 265 ("systems", ToMany(ToMany, "Products.ZenModel.System", "devices")), 266 ("groups", ToMany(ToMany, "Products.ZenModel.DeviceGroup", "devices")), 267 ("maintenanceWindows",ToManyCont(ToOne, 268 "Products.ZenModel.MaintenanceWindow", "productionState")), 269 ("adminRoles", ToManyCont(ToOne,"Products.ZenModel.AdministrativeRole", 270 "managedObject")), 271 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand', 272 'commandable')), 273 #("dhcpubrclients", ToMany(ToMany, "Products.ZenModel.UBRRouter", 274 # "dhcpservers")), 275 ) 276 277 # Screen action bindings (and tab definitions) 278 factory_type_information = ( 279 { 280 'id' : 'Device', 281 'meta_type' : 'Device', 282 'description' : """Base class for all devices""", 283 'icon' : 'Device_icon.gif', 284 'product' : 'ZenModel', 285 'factory' : 'manage_addDevice', 286 'immediate_view' : 'deviceStatus', 287 'actions' : 288 ( 289 { 'id' : 'status' 290 , 'name' : 'Status' 291 , 'action' : 'deviceStatus' 292 , 'permissions' : (ZEN_VIEW, ) 293 }, 294 { 'id' : 'osdetail' 295 , 'name' : 'OS' 296 , 'action' : 'os/deviceOsDetail' 297 , 'permissions' : (ZEN_VIEW, ) 298 }, 299 { 'id' : 'hwdetail' 300 , 'name' : 'Hardware' 301 , 'action' : 'deviceHardwareDetail' 302 , 'permissions' : (ZEN_VIEW, ) 303 }, 304 { 'id' : 'swdetail' 305 , 'name' : 'Software' 306 , 'action' : 'deviceSoftwareDetail' 307 , 'permissions' : (ZEN_VIEW, ) 308 }, 309 { 'id' : 'events' 310 , 'name' : 'Events' 311 , 'action' : 'viewEvents' 312 , 'permissions' : (ZEN_VIEW, ) 313 }, 314 { 'id' : 'historyEvents' 315 , 'name' : 'History' 316 , 'action' : 'viewHistoryEvents' 317 , 'permissions' : (ZEN_VIEW, ) 318 }, 319 { 'id' : 'perfServer' 320 , 'name' : 'Perf' 321 , 'action' : 'viewDevicePerformance' 322 , 'permissions' : (ZEN_VIEW, ) 323 }, 324 # { 'id' : 'perfConf' 325 # , 'name' : 'PerfConf' 326 # , 'action' : 'objTemplates' 327 # , 'permissions' : ("Change Device", ) 328 # }, 329 { 'id' : 'edit' 330 , 'name' : 'Edit' 331 , 'action' : 'editDevice' 332 , 'permissions' : ("Change Device",) 333 }, 334 # { 'id' : 'management' 335 # , 'name' : 'Administration' 336 # , 'action' : 'deviceManagement' 337 # , 'permissions' : ("Change Device",) 338 # }, 339 # { 'id' : 'custom' 340 # , 'name' : 'Custom' 341 # , 'action' : 'deviceCustomEdit' 342 # , 'permissions' : (ZEN_VIEW, ) 343 # }, 344 # { 'id' : 'config' 345 # , 'name' : 'zProperties' 346 # , 'action' : 'zPropertyEdit' 347 # , 'permissions' : (ZEN_VIEW,) 348 # }, 349 # { 'id' : 'viewHistory' 350 # , 'name' : 'Modifications' 351 # , 'action' : 'viewHistory' 352 # , 'permissions' : (ZEN_VIEW, ) 353 # }, 354 # { 'id' : 'zProperties' 355 # , 'name' : 'zProperties' 356 # , 'action' : 'zPropertyEdit' 357 # , 'permissions' : ( ZEN_VIEW, ) 358 # }, 359 ) 360 }, 361 ) 362 363 security = ClassSecurityInfo() 364
365 - def __init__(self, id):
366 ManagedEntity.__init__(self, id) 367 os = OperatingSystem() 368 self._setObject(os.id, os) 369 hw = DeviceHW() 370 self._setObject(hw.id, hw) 371 #self.commandStatus = "Not Tested" 372 self._lastPollSnmpUpTime = ZenStatus(0) 373 self._snmpLastCollection = 0 374 self._lastChange = 0
375 376
377 - def getRRDTemplate(self):
378 """ 379 DEPRECATED 380 """ 381 import warnings 382 warnings.warn('Device.getRRDTemplate is deprecated', 383 DeprecationWarning) 384 return ManagedEntity.getRRDTemplate(self)
385
386 - def getRRDTemplates(self):
387 """ 388 Returns all the templates bound to this Device 389 390 @rtype: list 391 392 >>> from Products.ZenModel.Device import manage_addDevice 393 >>> manage_addDevice(devices, 'test') 394 >>> devices.test.getRRDTemplates() 395 [<RRDTemplate at /zport/dmd/Devices/rrdTemplates/Device>] 396 """ 397 if not hasattr(self, 'zDeviceTemplates'): 398 return ManagedEntity.getRRDTemplates(self) 399 result = [] 400 for name in self.zDeviceTemplates: 401 template = self.getRRDTemplateByName(name) 402 if template: 403 result.append(template) 404 return result
405 406
407 - def getRRDNames(self):
408 return ['sysUpTime']
409 410
411 - def getDataSourceOptions(self):
412 """ 413 Returns the available DataSource options. DataSource options 414 are used to populate the dropdown when adding a new DataSource 415 and is a string. See L{RRDTemplate.RRDTemplate.getDataSourceOptions} 416 for more information. 417 418 @rtype: list 419 @return: [(displayName, dsOption),] 420 """ 421 # This is an unfortunate hack. Called from the device templates 422 # page where we show multiple templates now. This only really 423 # works because getDataSourceOptions() returns the same values 424 # for every template. Ideally we would be able to pass some sort 425 # of context to the Add DataSource dialog that calls this method. 426 templates = self.getRRDTemplates() 427 if templates: 428 return templates[0].getDataSourceOptions() 429 return []
430 431 # security.declareProtected('Manage DMD', 'manage_resequenceRRDGraphs') 432 # def manage_resequenceRRDGraphs(self, templateId, seqmap=(), origseq=(), REQUEST=None): 433 # """Reorder the sequecne of the RRDGraphs. 434 # """ 435 # template = self.getRRDTemplateByName(templateId) 436 # return template.manage_resequenceRRDGraphs(seqmap, origseq, REQUEST) 437 438
439 - def sysUpTime(self):
440 """ 441 Returns the cached sysUpTime for this device 442 443 @rtype: int 444 """ 445 try: 446 return self.cacheRRDValue('sysUpTime', -1) 447 except Exception: 448 log.exception("failed getting sysUpTime") 449 return -1
450 451
452 - def availability(self, *args, **kw):
453 """ 454 Returns the uptime of this device 455 456 @rtype: string 457 @todo: Performance enhancement: Should move import outside of method 458 """ 459 from Products.ZenEvents import Availability 460 results = Availability.query(self.dmd, device=self.id, *args, **kw) 461 if results: 462 return results[0] 463 else: 464 return None
465 466
467 - def __getattr__(self, name):
468 """ 469 Override from object to handle lastPollSnmpUpTime and 470 snmpLastCollection 471 472 @todo: Not sure this is needed, see getLastPollSnmpUpTime and 473 getSnmpLastCollection 474 """ 475 if name == 'lastPollSnmpUpTime': 476 return self._lastPollSnmpUpTime.getStatus() 477 elif name == 'snmpLastCollection': 478 return DateTime(self._snmpLastCollection) 479 else: 480 raise AttributeError, name
481 482
483 - def _setPropValue(self, id, value):
484 """ 485 Override from PropertyManager to handle checks and ip creation 486 487 @todo: Not sure this is needed, see setSnmpLastCollection 488 """ 489 self._wrapperCheck(value) 490 if id == 'snmpLastCollection': 491 self._snmpLastCollection = float(value) 492 else: 493 ManagedEntity._setPropValue(self, id, value)
494 495
496 - def applyDataMap(self, datamap, relname="", compname="", modname=""):
497 """ 498 Apply a datamap passed as a list of dicts through XML-RPC. 499 """ 500 adm = ApplyDataMap() 501 adm.applyDataMap(self, datamap, relname=relname, 502 compname=compname, modname=modname)
503 504
505 - def traceRoute(self, target, ippath=None):
506 """ 507 Trace the route to target using our routing table. 508 Wrapper method of OperatingSystem.traceRoute 509 510 @param target: Device name 511 @type target: string 512 @param ippath: IP addesses 513 @type ippath: list 514 @return: IP Addresses 515 @rtype: list 516 """ 517 if ippath is None: ippath=[] 518 if type(target) in types.StringTypes: 519 target = self.findDevice(target) 520 if not target: raise ValueError("target %s not found in dmd",target) 521 return self.os.traceRoute(target, ippath)
522 523
524 - def getMonitoredComponents(self, collector=None, type=None):
525 """ 526 Return list of monitored DeviceComponents on this device. 527 Wrapper method for getDeviceComponents 528 """ 529 return self.getDeviceComponents(monitored=True, 530 collector=collector, type=type)
531 532 security.declareProtected(ZEN_VIEW, 'getDeviceComponents')
533 - def getDeviceComponents(self, monitored=None, collector=None, type=None):
534 """ 535 Return list of all DeviceComponents on this device. 536 537 @type monitored: boolean 538 @type collector: string 539 @type type: string 540 @permission: ZEN_VIEW 541 @rtype: list 542 """ 543 query = { 544 'getParentDeviceName':self.id, 545 } 546 if collector is not None: 547 query['getCollectors'] = collector 548 if monitored is not None: 549 query['monitored'] = monitored 550 if type is not None: 551 query['meta_type'] = type 552 brains = self.componentSearch(query) 553 return [c.getObject() for c in brains]
554 555
557 """ 558 Return a list of all device components by walking relations. This is 559 much slower then the normal getDeviceComponents method which uses the 560 component index. It is used when rebuilding the device indexes. 561 """ 562 from DeviceComponent import DeviceComponent 563 for baseObject in (self, self.os, self.hw): 564 for rel in baseObject.getRelationships(): 565 if rel.meta_type != "ToManyContRelationship": continue 566 for obj in rel(): 567 if not isinstance(obj, DeviceComponent): break 568 yield obj
569 570
571 - def getSnmpConnInfo(self):
572 """ 573 Returns a tuple of SNMP Connection Info 574 575 @rtype: tuple (devname, (ip, port), 576 (community, version, timeout, tries), zMaxOIDPerRequest) 577 578 >>> from Products.ZenModel.Device import manage_addDevice 579 >>> manage_addDevice(devices, 'test') 580 >>> devices.test.getSnmpConnInfo() 581 ('test', ('', 161), ('public', 'v1', 2.5, 2), 40) 582 """ 583 return (self.id, 584 (self.manageIp, self.zSnmpPort), 585 (self.zSnmpCommunity, self.zSnmpVer, 586 self.zSnmpTimeout, self.zSnmpTries), 587 self.zMaxOIDPerRequest)
588 589
590 - def getOSProcessConf(self):
591 """ 592 Returns process monitoring configuration 593 594 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port), 595 (community, version, timeout, tries), zMaxOIDPerRequest), 596 list of configs, list of thresholds) 597 """ 598 if not self.snmpMonitorDevice(): 599 return None 600 procs = self.getMonitoredComponents(collector='zenprocess') 601 if not procs: 602 return None 603 config = [ p.getOSProcessConf() for p in procs ] 604 threshs = [t for p in procs for t in p.getThresholdInstances('SNMP')] 605 return (float(self.getLastChange()), 606 self.getSnmpConnInfo(), 607 config, 608 threshs)
609 610
611 - def getSnmpOidTargets(self):
612 """ 613 Return information for snmp collection on this device 614 615 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port), 616 (community, version, timeout, tries), zMaxOIDPerRequest), 617 list of thresholds, 618 list of oids) 619 620 >>> from Products.ZenModel.Device import manage_addDevice 621 >>> manage_addDevice(devices, 'test') 622 >>> devices.test.getSnmpOidTargets() 623 (0.0, ('test', ('', 161), ('public', 'v1', 2.5, 2), 40), [], 624 [('sysUpTime', '1.3.6.1.2.1.1.3.0', 'Devices/test/sysUpTime_sysUpTime', 625 'GAUGE', '', (None, None))]) 626 """ 627 if not self.snmpMonitorDevice(): return None 628 oids, threshs = (super(Device, self).getSnmpOidTargets()) 629 for o in self.os.getMonitoredComponents(collector="zenperfsnmp"): 630 o, t = o.getSnmpOidTargets() 631 oids.extend(o) 632 threshs.extend(t) 633 return (float(self.getLastChange()), 634 self.getSnmpConnInfo(), 635 threshs, 636 oids)
637 638
639 - def getDataSourceCommands(self):
640 """ 641 Return list of command definitions on this device 642 643 @rtype: tuple (lastChangeTimeInSecs, (devname, (ip, port), 644 (community, version, timeout, tries), zMaxOIDPerRequest), 645 list of thresholds, 646 list of commands) 647 """ 648 if not self.monitorDevice(): 649 return [] 650 cmds, threshs = (super(Device, self).getDataSourceCommands()) 651 for o in self.getMonitoredComponents(collector="zencommand"): 652 c, t = o.getDataSourceCommands() 653 cmds.extend(c) 654 threshs.extend(t) 655 if cmds: 656 return (float(self.getLastChange()), 657 self.id, self.getManageIp(), self.zCommandPort, 658 self.zCommandUsername, self.zCommandPassword, 659 self.zCommandLoginTimeout, self.zCommandCommandTimeout, 660 self.zKeyPath,self.zMaxOIDPerRequest, 661 cmds, threshs)
662 663
664 - def getXmlRpcTargets(self):
665 """ 666 Return information for xmlrpc collection on this device 667 668 @rtype: tuple (devname, xmlRpcStatus, 669 (url, methodName), 670 [(name, path, type, createCmd, thresholds)]) 671 """ 672 targets = (super(Device, self).getXmlRpcTargets()) 673 return (self.id, self.getXmlRpcStatus(), targets)
674 675
676 - def getHWManufacturerName(self):
677 """ 678 DEPRECATED - Return the hardware manufacturer name of this device. 679 680 @rtype: string 681 @todo: Remove this method and remove the call from testDevice.py 682 """ 683 return self.hw.getManufacturerName()
684 685
686 - def getHWProductName(self):
687 """ 688 Return the hardware product name of this device. 689 690 @rtype: string 691 """ 692 return self.hw.getProductName()
693 694
695 - def getHWProductKey(self):
696 """ 697 DEPRECATED - Return the productKey of the device hardware. 698 699 @rtype: string 700 @todo: Remove this method and remove the call from testDevice.py 701 """ 702 return self.hw.getProductKey()
703 704
705 - def getOSManufacturerName(self):
706 """ 707 DEPRECATED - Return the OS manufacturer name of this device. 708 709 @rtype: string 710 @todo: Remove this method and remove the call from testDevice.py 711 """ 712 return self.os.getManufacturerName()
713 714
715 - def getOSProductName(self):
716 """ 717 DEPRECATED - Return the OS product name of this device. 718 719 @rtype: string 720 @todo: Remove this method and remove the call from testDevice.py 721 """ 722 return self.os.getProductName()
723 724
725 - def getOSProductKey(self):
726 """ 727 DEPRECATED - Return the productKey of the device OS. 728 729 @rtype: string 730 @todo: Remove this method and remove the call from testDevice.py 731 """ 732 return self.os.getProductKey()
733 734
735 - def setOSProductKey(self, prodKey):
736 """ 737 Set the productKey of the device OS. 738 """ 739 self.os.setProductKey(prodKey)
740 741
742 - def setHWProductKey(self, prodKey):
743 """ 744 Set the productKey of the device hardware. 745 """ 746 self.hw.setProductKey(prodKey)
747 748
749 - def setHWSerialNumber(self, number):
750 """ 751 Set the hardware serial number. 752 """ 753 self.hw.serialNumber = number
754 755
756 - def getHWSerialNumber(self):
757 """ 758 DEPRECATED - Return the hardware serial number. 759 760 @rtype: string 761 @todo: Remove this method and remove the call from testDevice.py 762 """ 763 return self.hw.serialNumber
764 765
766 - def followNextHopIps(self):
767 """ 768 Return the ips that our indirect routs point to which aren't currently 769 connected to devices. 770 771 @todo: Can be moved to zendisc.py 772 """ 773 ips = [] 774 for r in self.os.routes(): 775 ipobj = r.nexthop() 776 #if ipobj and not ipobj.device(): 777 if ipobj: ips.append(ipobj.id) 778 return ips
779 780 781 security.declareProtected(ZEN_VIEW, 'getLocationName')
782 - def getLocationName(self):
783 """ 784 Return the full location name ie /Location/SubLocation/Rack 785 786 @rtype: string 787 @permission: ZEN_VIEW 788 """ 789 loc = self.location() 790 if loc: return loc.getOrganizerName() 791 return ""
792 793 security.declareProtected(ZEN_VIEW, 'getLocationLink') 809 810 811 security.declareProtected(ZEN_VIEW, 'getSystemNames')
812 - def getSystemNames(self):
813 """ 814 Return the system names for this device 815 816 @rtype: list 817 @permission: ZEN_VIEW 818 """ 819 return map(lambda x: x.getOrganizerName(), self.systems())
820 821 822 security.declareProtected(ZEN_VIEW, 'getSystemNamesString')
823 - def getSystemNamesString(self, sep=', '):
824 """ 825 Return the system names for this device as a string 826 827 @rtype: string 828 @permission: ZEN_VIEW 829 """ 830 return sep.join(self.getSystemNames())
831 832 833 security.declareProtected(ZEN_VIEW, 'getDeviceGroupNames')
834 - def getDeviceGroupNames(self):
835 """ 836 Return the device group names for this device 837 838 @rtype: list 839 @permission: ZEN_VIEW 840 """ 841 return map(lambda x: x.getOrganizerName(), self.groups())
842 843 844 security.declareProtected(ZEN_VIEW, 'getStatusMonitorNames')
845 - def getStatusMonitorNames(self):
846 """ 847 Return status monitor names 848 849 @rtype: string 850 @permission: ZEN_VIEW 851 """ 852 return map(lambda x: x.getId(), self.monitors())
853 854 855 security.declareProtected(ZEN_VIEW, 'getPerformanceServer')
856 - def getPerformanceServer(self):
857 """ 858 Return the device performance server 859 860 @rtype: PerformanceMonitor 861 @permission: ZEN_VIEW 862 """ 863 return self.perfServer()
864 865 866 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
867 - def getPerformanceServerName(self):
868 """ 869 Return the device performance server name 870 871 @rtype: string 872 @permission: ZEN_VIEW 873 """ 874 cr = self.perfServer() 875 if cr: return cr.getId() 876 return ''
877 878 879 security.declareProtected(ZEN_VIEW, 'getLastChange')
880 - def getLastChange(self):
881 """ 882 Return DateTime of last change detected on this device. 883 884 @rtype: DateTime 885 @permission: ZEN_VIEW 886 """ 887 return DateTime(float(self._lastChange))
888 889 890 security.declareProtected(ZEN_VIEW, 'getLastChangeString')
891 - def getLastChangeString(self):
892 """ 893 Return date string of last change detected on this device. 894 895 @rtype: string 896 @permission: ZEN_VIEW 897 """ 898 return Time.LocalDateTime(float(self._lastChange))
899 900 901 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollection')
902 - def getSnmpLastCollection(self):
903 """ 904 Return DateTime of last SNMP collection on this device. 905 906 @rtype: DateTime 907 @permission: ZEN_VIEW 908 """ 909 return DateTime(float(self._snmpLastCollection))
910 911 912 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollectionString')
914 """ 915 Return date string of last SNMP collection on this device. 916 917 @rtype: string 918 @permission: ZEN_VIEW 919 """ 920 return Time.LocalDateTime(float(self._snmpLastCollection))
921 922 923 security.declareProtected(ZEN_ADMIN_DEVICE, 'setManageIp')
924 - def setManageIp(self, ip="", REQUEST=None):
925 """ 926 Set the manage IP, if IP is not passed perform DNS lookup. 927 928 @rtype: string 929 @permission: ZEN_ADMIN_DEVICE 930 """ 931 if not ip: 932 try: ip = socket.gethostbyname(self.id) 933 except socket.error: ip = "" 934 self.manageIp = ip 935 self.index_object() 936 if REQUEST: 937 if ip: REQUEST['message'] = "Manage IP set" 938 else: REQUEST['message'] = "Not a valid IP" 939 return self.callZenScreen(REQUEST) 940 else: 941 return self.manageIp
942 943 944 security.declareProtected(ZEN_VIEW, 'getManageIp')
945 - def getManageIp(self):
946 """ 947 Return the management ip for this device. 948 949 @rtype: string 950 @permission: ZEN_VIEW 951 """ 952 return self.manageIp
953 954
955 - def getManageIpObj(self):
956 """ 957 DEPRECATED - Return the management ipobject for this device. 958 959 @rtype: IpAddress 960 @todo: This method may not be called anywhere, remove it. 961 """ 962 if self.manageIp: 963 return self.Networks.findIp(self.manageIp)
964 965 966 security.declareProtected(ZEN_VIEW, 'getManageInterface')
967 - def getManageInterface(self):
968 """ 969 Return the management interface of a device based on its manageIp. 970 971 @rtype: IpInterface 972 @permission: ZEN_VIEW 973 """ 974 ipobj = self.Networks.findIp(self.manageIp) 975 if ipobj: return ipobj.interface()
976 977 978 security.declareProtected(ZEN_VIEW, 'uptimeStr')
979 - def uptimeStr(self):
980 """" 981 Return the SNMP uptime 982 983 @rtype: string 984 @permission: ZEN_VIEW 985 """ 986 ut = self.sysUpTime() 987 if ut < 0: 988 return "Unknown" 989 elif ut == 0: 990 return "0d:0h:0m:0s" 991 ut = float(ut)/100. 992 days = ut/86400 993 hour = (ut%86400)/3600 994 mins = (ut%3600)/60 995 secs = ut%60 996 return "%02dd:%02dh:%02dm:%02ds" % ( 997 days, hour, mins, secs)
998 999
1000 - def getPeerDeviceClassNames(self):
1001 """ 1002 Build a list of all device paths that have the python class pyclass 1003 1004 @rtype: list 1005 """ 1006 dclass = self.getDmdRoot("Devices") 1007 return dclass.getPeerDeviceClassNames(self.__class__)
1008 1009
1010 - def havePydot(self):
1011 """ 1012 DEPRECATED - Return true if pydot is installed. 1013 1014 @todo: This method may not be called anywhere, remove it. 1015 """ 1016 try: 1017 import pydot 1018 return True 1019 except ImportError: 1020 return False
1021 1022 1023 security.declareProtected(ZEN_VIEW, 'getRouterGraph')
1024 - def getRouterGraph(self):
1025 """ 1026 Return a graph representing the relative routers 1027 1028 @rtype: graph 1029 @permission: ZEN_VIEW 1030 """ 1031 from Products.ZenStatus import pingtree 1032 node = pingtree.buildTree(self) 1033 g = NetworkGraph(node=node, parentName=self.id) 1034 #g.format = 'svg' 1035 self.REQUEST.RESPONSE.setHeader('Content-Type', 'image/%s' % g.format) 1036 return g.render()
1037 1038 1039 security.declareProtected(ZEN_VIEW, 'getNetworkGraph')
1040 - def getNetworkGraph(self):
1041 """ 1042 Return a graph representing the relative routers as well as the 1043 networks 1044 1045 @rtype: graph 1046 @permission: ZEN_VIEW 1047 """ 1048 from Products.ZenStatus import pingtree 1049 node = pingtree.buildTree(self) 1050 g = NetworkGraph(node=node, parentName=self.id) 1051 #g.format = 'svg' 1052 self.REQUEST.RESPONSE.setHeader('Content-Type', 'image/%s' % g.format) 1053 return g.render(withNetworks=True)
1054 1055 #################################################################### 1056 # Edit functions used to manage device relations and other attributes 1057 #################################################################### 1058 1059 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_snmpCommunity')
1060 - def manage_snmpCommunity(self):
1061 """Reset the snmp community using the zSnmpCommunities variable. 1062 """ 1063 try: 1064 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \ 1065 findCommunity(self, self.manageIp, self.getDeviceClassPath(), 1066 port=self.zSnmpPort, version=self.zSnmpVer) 1067 except NoSnmp: 1068 pass 1069 else: 1070 if self.zSnmpCommunity != zSnmpCommunity: 1071 self.setZenProperty("zSnmpCommunity", zSnmpCommunity) 1072 if self.zSnmpPort != zSnmpPort: 1073 self.setZenProperty("zSnmpPort", zSnmpPort) 1074 if self.zSnmpVer != zSnmpVer: 1075 self.setZenProperty("zSnmpVer", zSnmpVer)
1076 1077 1078 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_editDevice')
1079 - def manage_editDevice(self, 1080 tag="", serialNumber="", 1081 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="", 1082 rackSlot=0, productionState=1000, comments="", 1083 hwManufacturer="", hwProductName="", 1084 osManufacturer="", osProductName="", 1085 locationPath="", groupPaths=[], systemPaths=[], 1086 statusMonitors=["localhost"], performanceMonitor="localhost", 1087 priority=3, REQUEST=None):
1088 """edit device relations and attributes""" 1089 self.hw.tag = tag 1090 self.hw.serialNumber = serialNumber 1091 for prop in ('zSnmpCommunity', 'zSnmpVer', 'zSnmpPort'): 1092 passedIn = locals()[prop] 1093 if passedIn and getattr(self, prop) != passedIn: 1094 self.setZenProperty(prop, passedIn) 1095 1096 self.rackSlot = rackSlot 1097 self.setProdState(productionState) 1098 self.setPriority(priority) 1099 self.comments = comments 1100 1101 if hwManufacturer and hwProductName: 1102 log.info("setting hardware manufacturer to %s productName to %s" 1103 % (hwManufacturer, hwProductName)) 1104 self.hw.setProduct(hwProductName, hwManufacturer) 1105 else: 1106 self.hw.productClass.removeRelation() 1107 1108 if osManufacturer and osProductName: 1109 log.info("setting os manufacturer to %s productName to %s" 1110 % (osManufacturer, osProductName)) 1111 self.os.setProduct(osProductName, osManufacturer) 1112 self.os.productClass().isOS = True 1113 else: 1114 self.os.productClass.removeRelation() 1115 1116 if locationPath: 1117 log.info("setting location to %s" % locationPath) 1118 self.setLocation(locationPath) 1119 1120 if groupPaths: 1121 log.info("setting group %s" % groupPaths) 1122 self.setGroups(groupPaths) 1123 1124 if systemPaths: 1125 log.info("setting system %s" % systemPaths) 1126 self.setSystems(systemPaths) 1127 1128 log.info("setting status monitor to %s" % statusMonitors) 1129 self.setStatusMonitors(statusMonitors) 1130 1131 log.info("setting performance monitor to %s" % performanceMonitor) 1132 self.setPerformanceMonitor(performanceMonitor) 1133 1134 self.setLastChange() 1135 self.index_object() 1136 if REQUEST: 1137 from Products.ZenUtils.Time import SaveMessage 1138 REQUEST['message'] = SaveMessage() 1139 return self.callZenScreen(REQUEST)
1140 1141
1142 - def monitorDevice(self):
1143 """Is device production state >= zProdStateThreshold. 1144 """ 1145 return self.productionState >= self.zProdStateThreshold
1146 1147
1148 - def snmpMonitorDevice(self):
1149 "Is this device subject to SNMP monitoring?" 1150 return (self.monitorDevice() 1151 and not self.zSnmpMonitorIgnore 1152 and self.zSnmpCommunity)
1153 1154
1155 - def getProductionStateString(self):
1156 """Return the prodstate as a string. 1157 """ 1158 return self.convertProdState(self.productionState)
1159
1160 - def getPriorityString(self):
1161 """Return the device priority as a string. 1162 """ 1163 return self.convertPriority(self.priority)
1164
1165 - def getPingStatusString(self):
1166 """Return the pingStatus as a string 1167 """ 1168 return self.convertStatus(self.getPingStatus())
1169
1170 - def getSnmpStatusString(self):
1171 """Return the snmpStatus as a string 1172 """ 1173 return self.convertStatus(self.getSnmpStatus())
1174 1175 security.declareProtected(ZEN_CHANGE_DEVICE, 'setProdState')
1176 - def setProdState(self, state, REQUEST=None):
1177 """Set a device's production state as an integer. 1178 """ 1179 self.productionState = int(state) 1180 self.index_object() 1181 try: 1182 zem = self.dmd.ZenEventManager 1183 conn = zem.connect() 1184 try: 1185 curs = conn.cursor() 1186 curs.execute( 1187 "update status set prodState=%d where device='%s'" % ( 1188 self.productionState, self.id)) 1189 finally: zem.close(conn) 1190 except OperationalError: 1191 log.exception("failed to update events with new prodState") 1192 if REQUEST: 1193 REQUEST['message'] = "Failed to update events with new production state" 1194 return self.callZenScreen(REQUEST) 1195 1196 if REQUEST: 1197 REQUEST['message'] = "Production state set" 1198 return self.callZenScreen(REQUEST)
1199 1200 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1201 - def setPriority(self, priority, REQUEST=None):
1202 """ Set a device's priority as an integer. 1203 """ 1204 self.priority = int(priority) 1205 try: 1206 zem = self.dmd.ZenEventManager 1207 conn = zem.connect() 1208 try: 1209 curs = conn.cursor() 1210 curs.execute("update status set DevicePriority=%d where device='%s'" % ( 1211 self.priority, self.id)) 1212 finally: zem.close(conn) 1213 except OperationalError: 1214 log.exception("failed to update events with new priority") 1215 if REQUEST: 1216 REQUEST['message'] = "Failed to update events with new priority" 1217 return self.callZenScreen(REQUEST) 1218 1219 if REQUEST: 1220 REQUEST['message'] = "Priority set" 1221 return self.callZenScreen(REQUEST)
1222 1223 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLastChange')
1224 - def setLastChange(self, value=None):
1225 """Set the changed datetime for this device. value default is now. 1226 """ 1227 if value is None: 1228 value = time.time() 1229 self._lastChange = float(value)
1230 1231 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSnmpLastCollection')
1232 - def setSnmpLastCollection(self, value=None):
1233 """Set the last time snmp collection occurred. value default is now. 1234 """ 1235 if value is None: 1236 value = time.time() 1237 self._snmpLastCollection = float(value)
1238 1239 1240 security.declareProtected(ZEN_CHANGE_DEVICE, 'addManufacturer')
1241 - def addManufacturer(self, newHWManufacturerName=None, 1242 newSWManufacturerName=None, REQUEST=None):
1243 """Add a manufacturer to the database""" 1244 mname = newHWManufacturerName 1245 field = 'hwManufacturer' 1246 if not mname: 1247 mname = newSWManufacturerName 1248 field = 'osManufacturer' 1249 self.getDmdRoot("Manufacturers").createManufacturer(mname) 1250 if REQUEST: 1251 REQUEST[field] = mname 1252 REQUEST['message'] = ("Added Manufacturer %s at time:" % mname) 1253 return self.callZenScreen(REQUEST)
1254 1255 1256 security.declareProtected(ZEN_CHANGE_DEVICE, 'setHWProduct')
1257 - def setHWProduct(self, newHWProductName=None, hwManufacturer=None, 1258 REQUEST=None):
1259 """set the productName of this device""" 1260 added = False 1261 if newHWProductName and hwManufacturer: 1262 self.getDmdRoot("Manufacturers").createHardwareProduct( 1263 newHWProductName, hwManufacturer) 1264 added = True 1265 if REQUEST: 1266 if added: 1267 REQUEST['message'] = "Hardware product set" 1268 REQUEST['hwProductName'] = newHWProductName 1269 else: 1270 REQUEST['message'] = "Hardware product was not set" 1271 return self.callZenScreen(REQUEST)
1272 1273 1274 security.declareProtected(ZEN_CHANGE_DEVICE, 'setOSProduct')
1275 - def setOSProduct(self, newOSProductName=None, osManufacturer=None, REQUEST=None):
1276 """set the productName of this device""" 1277 if newOSProductName: 1278 self.getDmdRoot("Manufacturers").createSoftwareProduct( 1279 newOSProductName, osManufacturer, isOS=True) 1280 if REQUEST: 1281 if newOSProductName: 1282 REQUEST['message'] = "OS Product set" 1283 REQUEST['osProductName'] = newOSProductName 1284 else: 1285 REQUEST['message'] = "OS Product was not set" 1286 return self.callZenScreen(REQUEST)
1287 1288 1289 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1290 - def setLocation(self, locationPath, REQUEST=None):
1291 """set the location of a device within a generic location path""" 1292 if not locationPath: 1293 self.location.removeRelation() 1294 else: 1295 locobj = self.getDmdRoot("Locations").createOrganizer(locationPath) 1296 self.addRelation("location", locobj) 1297 self.setAdminLocalRoles()
1298 1299
1300 - def addLocation(self, newLocationPath, REQUEST=None):
1301 """Add a new location and relate it to this device""" 1302 locobj = self.getDmdRoot("Locations").createOrganizer(newLocationPath) 1303 if REQUEST: 1304 REQUEST['locationPath'] = newLocationPath 1305 REQUEST['message'] = "Added Location %s at time:" % newLocationPath 1306 return self.callZenScreen(REQUEST)
1307 1308 1309 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1310 - def setPerformanceMonitor(self, performanceMonitor, 1311 newPerformanceMonitor=None, REQUEST=None):
1312 """set the performance monitor for this device if newPerformanceMonitor 1313 is passed in create it""" 1314 if newPerformanceMonitor: 1315 #self.dmd.RenderServer.moveRRDFiles(self.id, 1316 # newPerformanceMonitor, performanceMonitor, REQUEST) 1317 performanceMonitor = newPerformanceMonitor 1318 1319 obj = self.getDmdRoot("Monitors").getPerformanceMonitor( 1320 performanceMonitor) 1321 self.addRelation("perfServer", obj) 1322 self.setLastChange() 1323 1324 if REQUEST: 1325 REQUEST['message'] = "Set Performance %s at time:" % performanceMonitor 1326 return self.callZenScreen(REQUEST)
1327 1328 1329 security.declareProtected(ZEN_CHANGE_DEVICE, 'setStatusMonitors')
1330 - def setStatusMonitors(self, statusMonitors):
1331 """Set Status Monitor by list statusMonitors 1332 """ 1333 objGetter = self.getDmdRoot("Monitors").getStatusMonitor 1334 self._setRelations("monitors", objGetter, statusMonitors) 1335 self.setLastChange()
1336 1337 1338 security.declareProtected(ZEN_CHANGE_DEVICE, 'addStatusMonitor')
1339 - def addStatusMonitor(self, newStatusMonitor=None, REQUEST=None):
1340 """add new status monitor to the database and this device""" 1341 if newStatusMonitor: 1342 mon = self.getDmdRoot("Monitors").getStatusMonitor(newStatusMonitor) 1343 self.addRelation("monitors", mon) 1344 self.setLastChange() 1345 if REQUEST: 1346 if newStatusMonitor: 1347 REQUEST['message'] = "Added Monitor %s at time:" % \ 1348 newStatusMonitor 1349 return self.callZenScreen(REQUEST)
1350 1351 1352 security.declareProtected(ZEN_CHANGE_DEVICE, 'setGroups')
1353 - def setGroups(self, groupPaths):
1354 """set the list of groups for this device based on a list of paths""" 1355 objGetter = self.getDmdRoot("Groups").createOrganizer 1356 self._setRelations("groups", objGetter, groupPaths)
1357 1358 1359 security.declareProtected(ZEN_CHANGE_DEVICE, 'addDeviceGroup')
1360 - def addDeviceGroup(self, newDeviceGroupPath, REQUEST=None):
1361 """add a device group to the database and this device""" 1362 group = self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath) 1363 self.addRelation("groups", group) 1364 if REQUEST: 1365 REQUEST['message'] = "Added Group %s at time:" % newDeviceGroupPath 1366 return self.callZenScreen(REQUEST)
1367 1368 1369 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSystems')
1370 - def setSystems(self, systemPaths):
1371 """set a list of systems to this device using their system paths""" 1372 objGetter = self.getDmdRoot("Systems").createOrganizer 1373 self._setRelations("systems", objGetter, systemPaths)
1374 1375 1376 security.declareProtected(ZEN_CHANGE_DEVICE, 'addSystem')
1377 - def addSystem(self, newSystemPath, REQUEST=None):
1378 """add a systems to this device using its system path""" 1379 sys = self.getDmdRoot("Systems").createOrganizer(newSystemPath) 1380 self.addRelation("systems", sys) 1381 if REQUEST: 1382 REQUEST['message'] = "System added" 1383 return self.callZenScreen(REQUEST)
1384 1385 1386 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1387 - def setTerminalServer(self, termservername):
1388 termserver = self.findDevice(termservername) 1389 if termserver: 1390 self.addRelation('termserver', termserver)
1391 1392
1393 - def _setRelations(self, relName, objGetter, relPaths):
1394 """set related objects to this device""" 1395 if type(relPaths) != type([]) and type(relPaths) != type(()): 1396 relPaths = [relPaths,] 1397 relPaths = filter(lambda x: x.strip(), relPaths) 1398 rel = getattr(self, relName, None) 1399 if not rel: 1400 raise AttributeError, "Relation %s not found" % relName 1401 curRelIds = {} 1402 for value in rel.objectValuesAll(): 1403 curRelIds[value.getOrganizerName()] = value 1404 for path in relPaths: 1405 if not curRelIds.has_key(path): 1406 robj = objGetter(path) 1407 self.addRelation(relName, robj) 1408 else: 1409 del curRelIds[path] 1410 for obj in curRelIds.values(): 1411 self.removeRelation(relName, obj) 1412 self.setAdminLocalRoles()
1413 1414 1423 1424 #################################################################### 1425 # Private getter functions that implement DeviceResultInt 1426 #################################################################### 1427 1428 security.declareProtected(ZEN_VIEW, 'device')
1429 - def device(self):
1430 """support DeviceResultInt mixin class""" 1431 return self
1432 1433 1434 #################################################################### 1435 # Status Management Functions used by status monitors 1436 #################################################################### 1437 1438
1439 - def pastSnmpMaxFailures(self):
1440 """Device has more SNMP failures than maxFailures on its status mon.""" 1441 statusmon = self.monitors() 1442 if len(statusmon) > 0: 1443 statusmon = statusmon[0] 1444 return statusmon.maxFailures < self.getSnmpStatusNumber() 1445 return False
1446 1447 1448 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS, 1449 'getLastPollSnmpUpTime')
1450 - def getLastPollSnmpUpTime(self):
1451 """set the value of the snmpUpTime status object""" 1452 return self._lastPollSnmpUpTime.getStatus()
1453 1454 1455 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS, 1456 'setLastPollSnmpUpTime')
1457 - def setLastPollSnmpUpTime(self, value):
1458 """set the value of the snmpUpTime status object""" 1459 self._lastPollSnmpUpTime.setStatus(value)
1460 1461
1462 - def snmpAgeCheck(self, hours):
1463 lastcoll = self.getSnmpLastCollection() 1464 hours = hours/24.0 1465 if DateTime() > lastcoll + hours: return 1
1466 1467
1468 - def applyProductContext(self):
1469 """Apply zProperties inherited from Product Contexts. 1470 """ 1471 self._applyProdContext(self.hw.getProductContext()) 1472 self._applyProdContext(self.os.getProductContext()) 1473 for soft in self.os.software(): 1474 self._applyProdContext(soft.getProductContext())
1475 1476
1477 - def _applyProdContext(self, context):
1478 """Apply zProperties taken for the product context passed in. 1479 context is a list of tuples returned from getProductContext 1480 on a MEProduct. 1481 """ 1482 for name, value in context: 1483 if name == "zDeviceClass" and value: 1484 log.info("move device to %s", value) 1485 self.moveDevices(value, self.id) 1486 elif name == "zDeviceGroup" and value: 1487 log.info("add device to group %s", value) 1488 self.addDeviceGroup(value) 1489 elif name == "zSystem" and value: 1490 log.info("add device to system %s", value) 1491 self.addSystem(value)
1492 1493 1494 1495 #################################################################### 1496 # Management Functions 1497 #################################################################### 1498 1499 security.declareProtected(ZEN_MANAGE_DEVICE, 'collectDevice')
1500 - def collectDevice(self, setlog=True, REQUEST=None, generateEvents=False):
1501 """collect the configuration of this device. 1502 """ 1503 response = None 1504 if REQUEST and setlog: 1505 response = REQUEST.RESPONSE 1506 dlh = self.deviceLoggingHeader() 1507 idx = dlh.rindex("</table>") 1508 dlh = dlh[:idx] 1509 idx = dlh.rindex("</table>") 1510 dlh = dlh[:idx] 1511 response.write(str(dlh[:idx])) 1512 handler = setWebLoggingStream(response) 1513 1514 try: 1515 zm = zenPath('bin', 'zenmodeler') 1516 zenmodelerCmd = [zm, 'run', '--now','-F','-d', self.id] 1517 if REQUEST: zenmodelerCmd.append("--weblog") 1518 log.info('Executing command: %s' % ' '.join(zenmodelerCmd)) 1519 f = Popen4(zenmodelerCmd) 1520 while 1: 1521 s = f.fromchild.readline() 1522 if not s: 1523 break 1524 elif response: 1525 response.write(s) 1526 response.flush() 1527 else: 1528 sys.stdout.write(s) 1529 except (SystemExit, KeyboardInterrupt): raise 1530 except ZentinelException, e: 1531 log.critical(e) 1532 except: raise 1533 1534 if REQUEST and setlog: 1535 response.write(self.loggingFooter()) 1536 clearWebLoggingStream(handler) 1537 REQUEST['message'] = "Configuration collected"
1538 # if not setlog: 1539 # for c in [c for c in sc.finished if c.timeout < time.time()]: 1540 # from Products.DataCollector.Exceptions import DataCollectorError 1541 # raise DataCollectorError("Device %s timed out" % self.id) 1542 1543 1544 security.declareProtected(ZEN_ADMIN_DEVICE, 'deleteDevice')
1545 - def deleteDevice(self, REQUEST=None):
1546 """Delete device from the DMD""" 1547 parent = self.getPrimaryParent() 1548 self.getEventManager().manage_deleteHeartbeat(self.getId()) 1549 self.getEventManager().manage_deleteAllEvents(self.getId()) 1550 parent._delObject(self.getId()) 1551 if REQUEST: 1552 REQUEST['message'] = "Device deleted" 1553 if parent.getId()=='devices': 1554 parent = parent.getPrimaryParent() 1555 REQUEST['RESPONSE'].redirect(parent.absolute_url() + 1556 "/deviceOrganizerStatus")
1557 1558 security.declareProtected(ZEN_MANAGE_DEVICE, 'manage_deleteHeartbeat')
1559 - def manage_deleteHeartbeat(self, REQUEST=None):
1560 """Delete this device's heartbeats.""" 1561 self.getEventManager().manage_deleteHeartbeat(self.getId()) 1562 if REQUEST: 1563 REQUEST['message'] = "Cleared heartbeat events for %s" % self.id 1564 return self.callZenScreen(REQUEST)
1565 1566 1567 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1568 - def renameDevice(self, newId=None, REQUEST=None):
1569 """Rename device from the DMD""" 1570 if newId: 1571 if not isinstance(newId, unicode): 1572 newId = self.prepId(newId) 1573 parent = self.getPrimaryParent() 1574 parent.manage_renameObject(self.getId(), newId) 1575 self.setLastChange() 1576 if REQUEST: 1577 REQUEST['message'] = "Device %s renamed to %s" % (self.getId(), newId) 1578 REQUEST['RESPONSE'].redirect("%s/%s" % (parent.absolute_url(), newId))
1579 1580
1581 - def manage_afterAdd(self, item, container):
1582 """ 1583 Device only propagates afterAdd if it is the added object. 1584 """ 1585 super(Device,self).manage_afterAdd(item, container) 1586 self.index_object()
1587 1588
1589 - def manage_afterClone(self, item):
1590 """Not really sure when this is called.""" 1591 super(Device,self).manage_afterClone(item) 1592 self.index_object()
1593 1594
1595 - def manage_beforeDelete(self, item, container):
1596 """ 1597 Device only propagates beforeDelete if we are being deleted or copied. 1598 Moving and renaming don't propagate. 1599 """ 1600 super(Device,self).manage_beforeDelete(item, container) 1601 self.unindex_object()
1602 1603
1604 - def cacheComponents(self):
1605 "Read current RRD values for all of a device's components" 1606 paths = self.getRRDPaths()[:] 1607 #FIXME need better way to scope and need to get DataSources 1608 # from RRDTemplates 1609 #for c in self.os.interfaces(): paths.extend(c.getRRDPaths()) 1610 for c in self.os.filesystems(): paths.extend(c.getRRDPaths()) 1611 #for c in self.hw.harddisks(): paths.extend(c.getRRDPaths()) 1612 objpaq = self.primaryAq() 1613 perfServer = objpaq.getPerformanceServer() 1614 if perfServer: 1615 try: 1616 result = perfServer.currentValues(paths) 1617 if result: 1618 RRDView.updateCache(zip(paths, result)) 1619 except Exception: 1620 log.exception("Unable to cache values for %s", self.id);
1621 1622
1623 - def getUserCommandTargets(self):
1624 """ Called by Commandable.doCommand() to ascertain objects on which 1625 a UserCommand should be executed. 1626 """ 1627 return [self]
1628
1629 - def getUserCommandEnvironment(self):
1630 environ = Commandable.getUserCommandEnvironment(self) 1631 context = self.primaryAq() 1632 environ.update({'dev': context, 'device': context,}) 1633 return environ
1634
1635 - def getUrlForUserCommands(self, commandId=None):
1636 return self.getPrimaryUrlPath() + '/deviceManagement'
1637
1638 - def getHTMLEventSummary(self, severity=4):
1639 html = [] 1640 html.append("<table width='100%' cellspacing='1' cellpadding='3'>") 1641 html.append("<tr>") 1642 def evsummarycell(ev): 1643 if ev[1]-ev[2]>=0: klass = '%s empty thin' % ev[0] 1644 else: klass = '%s thin' % ev[0] 1645 h = '<th align="center" width="16%%" class="%s">%s/%s</th>' % ( 1646 klass, ev[1], ev[2]) 1647 return h
1648 info = self.getEventSummary(severity) 1649 html += map(evsummarycell, info) 1650 html.append('</tr></table>') 1651 return '\n'.join(html)
1652
1653 - def getDataForJSON(self):
1654 """ returns data ready for serialization 1655 """ 1656 id = '<a class="tablevalues" href="%s">%s</a>' % ( 1657 self.getDeviceUrl(), self.getId()) 1658 ip = self.getDeviceIp() 1659 path = '<a href="/zport/dmd/Devices%s">%s</a>' % ( 1660 self.getDeviceClassPath(), 1661 self.getDeviceClassPath()) 1662 prod = self.getProdState() 1663 evsum = self.getHTMLEventSummary() 1664 imgbase = '<img border="0" src="locked-%s-icon.png"/>' 1665 locks = '' 1666 if self.isLockedFromUpdates(): locks += imgbase % 'update' 1667 if self.isLockedFromDeletion(): locks += imgbase % 'delete' 1668 if self.sendEventWhenBlocked(): locks += imgbase % 'sendevent' 1669 return [id, ip, path, prod, evsum, locks, self.getId()]
1670
1671 - def exportXmlHook(self, ofile, ignorerels):
1672 """Add export of our child objects. 1673 """ 1674 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
1675
1676 - def zenPropertyOptions(self, propname):
1677 if propname == 'zCollectorPlugins': 1678 from Products.DataCollector.Plugins import loadPlugins 1679 names = loadPlugins(self.dmd).keys() 1680 names.sort() 1681 return names 1682 return ManagedEntity.zenPropertyOptions(self, propname)
1683 1684 security.declareProtected(ZEN_MANAGE_DEVICE, 'pushConfig')
1685 - def pushConfig(self, REQUEST=None):
1686 "This will result in a push of all the devices to live collectors" 1687 self._p_changed = True 1688 if REQUEST: 1689 REQUEST['message'] = 'Changes to %s pushed to collectors' % self.id 1690 return self.callZenScreen(REQUEST)
1691 1692 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'bindTemplates')
1693 - def bindTemplates(self, ids=(), REQUEST=None):
1694 "This will bind available templates to the zDeviceTemplates" 1695 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
1696 1697 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'removeZDeviceTemplates')
1698 - def removeZDeviceTemplates(self, REQUEST=None):
1699 "Deletes the local zProperty, zDeviceTemplates" 1700 for id in self.zDeviceTemplates: 1701 self.removeLocalRRDTemplate(id) 1702 return self.deleteZenProperty('zDeviceTemplates', REQUEST)
1703 1704 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
1705 - def addLocalTemplate(self, id, REQUEST=None):
1706 "Create a local template on a device" 1707 from Products.ZenModel.RRDTemplate import manage_addRRDTemplate 1708 manage_addRRDTemplate(self, id) 1709 if id not in self.zDeviceTemplates: 1710 self.bindTemplates(self.zDeviceTemplates+[id]) 1711 if REQUEST: 1712 REQUEST['message'] = 'Added template %s to %s' % (id, self.id) 1713 return self.callZenScreen(REQUEST)
1714
1715 - def getAvailableTemplates(self):
1716 "Returns all available templates for this device" 1717 # All templates defined on this device are available 1718 templates = self.objectValues('RRDTemplate') 1719 # Any templates available to the class that aren't overridden locally 1720 # are also available 1721 templates += [t for t in self.deviceClass().getRRDTemplates() 1722 if t.id not in [r.id for r in templates]] 1723 def cmpTemplates(a, b): 1724 return cmp(a.id.lower(), b.id.lower())
1725 templates.sort(cmpTemplates) 1726 return templates 1727 1728 security.declareProtected(ZEN_VIEW, 'getLinks') 1739 1740 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
1741 - def getXMLEdges(self, depth=3, filter="/", start=()):
1742 """ Gets XML """ 1743 if not start: start=self.id 1744 edges = NetworkTree.get_edges(self, depth, 1745 withIcons=True, filter=filter) 1746 return edgesToXML(edges, start)
1747 1748 security.declareProtected(ZEN_VIEW, 'getPrettyLink') 1763 1764 security.declareProtected(ZEN_VIEW, 'getEventPill')
1765 - def getEventPill(self, showGreen=True):
1766 """ Gets an event pill representing the highest severity """ 1767 pill = self.ZenEventManager.getEventPillME(self, showGreen=showGreen) 1768 if type(pill)==type([]) and len(pill)==1: return pill[0] 1769 return pill
1770
1771 - def getDeviceComponentEventSummary(self):
1772 """ Gets datatable-ready string of components and summaries """ 1773 return self.dmd.ZenEventManager.getDeviceComponentEventSummary(self)
1774 1775 1776 InitializeClass(Device) 1777