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  __doc__ = """Device 
  15  Base device (remote computer) class 
  16  """ 
  17   
  18  import os 
  19  import shutil 
  20  import time 
  21  import types 
  22  import socket 
  23  import logging 
  24  log = logging.getLogger("zen.Device") 
  25   
  26  from _mysql_exceptions import OperationalError 
  27   
  28  from urllib import quote as urlquote 
  29   
  30  from Products.ZenUtils.Utils import isXmlRpc 
  31  from Products.ZenUtils.Utils import unused 
  32  from Products.ZenUtils import Time 
  33  import RRDView 
  34  from Products.ZenUtils.IpUtil import checkip, IpAddressError, maskToBits 
  35   
  36  # base classes for device 
  37  from ManagedEntity import ManagedEntity 
  38   
  39  from AccessControl import ClassSecurityInfo 
  40  from Globals import DTMLFile 
  41  from Globals import InitializeClass 
  42  from DateTime import DateTime 
  43   
  44  from ZODB.POSException import POSError 
  45   
  46   
  47  #from Products.SnmpCollector.SnmpCollector import findSnmpCommunity 
  48  from Products.DataCollector.ApplyDataMap import ApplyDataMap 
  49   
  50  from Products.ZenRelations.RelSchema import * 
  51  from Commandable import Commandable 
  52  from Lockable import Lockable 
  53  from MaintenanceWindowable import MaintenanceWindowable 
  54  from AdministrativeRoleable import AdministrativeRoleable 
  55  from ZenMenuable import ZenMenuable 
  56   
  57  from OperatingSystem import OperatingSystem 
  58  from DeviceHW import DeviceHW 
  59   
  60  from ZenStatus import ZenStatus 
  61  from Products.ZenModel.Exceptions import * 
  62  from ZenossSecurity import * 
  63  from Products.ZenUtils.FakeRequest import FakeRequest 
  64  from Products.ZenUtils.Utils import edgesToXML 
  65  from Products.ZenUtils import NetworkTree 
  66   
  67  from zope.interface import implements 
  68  from EventView import IEventView 
  69  from Products.ZenWidgets.interfaces import IMessageSender 
  70  from Products.ZenWidgets import messaging 
  71  from Products.Jobber.status import SUCCESS, FAILURE 
  72  from Products.ZenUtils.Utils import binPath 
  73  from Products.ZenEvents.browser.EventPillsAndSummaries import getEventPillME 
  74  from OFS.CopySupport import CopyError # Yuck, a string exception 
  75   
  76   
77 -def getNetworkRoot(context, performanceMonitor):
78 """ 79 Return the default network root. 80 """ 81 return context.getDmdRoot('Networks')
82 83
84 -def checkDeviceExists(context, deviceName, ip, performanceMonitor):
85 mon = context.Monitors.getPerformanceMonitor(performanceMonitor) 86 netroot = mon.getNetworkRoot() 87 if ip: 88 ipobj = netroot.findIp(ip) 89 if ipobj: 90 dev = ipobj.device() 91 if dev: 92 raise DeviceExistsError("Ip %s exists on %s" % (ip, dev.id),dev) 93 94 if deviceName: 95 dev = context.getDmdRoot('Devices').findDevice(deviceName) 96 if dev: 97 raise DeviceExistsError("Device %s already exists" % 98 deviceName, dev) 99 if ip: 100 dev = mon.findDevice(ip) 101 if dev: 102 raise DeviceExistsError("Manage IP %s already exists" % ip, dev) 103 return deviceName, ip
104 105
106 -def manage_createDevice(context, deviceName, devicePath="/Discovered", 107 tag="", serialNumber="", 108 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="", 109 rackSlot="", productionState=1000, comments="", 110 hwManufacturer="", hwProductName="", 111 osManufacturer="", osProductName="", 112 locationPath="", groupPaths=[], systemPaths=[], 113 performanceMonitor="localhost", 114 discoverProto="snmp", priority=3, manageIp="", 115 zProperties=None):
116 """ 117 Device factory creates a device and sets up its relations and collects its 118 configuration. SNMP Community discovery also happens here. If an IP is 119 passed for deviceName it will be used for collection and the device name 120 will be set to the SNMP SysName (or ptr if SNMP Fails and ptr is valid) 121 122 @rtype: Device 123 """ 124 checkDeviceExists(context, deviceName, manageIp, performanceMonitor) 125 deviceName = context.prepId(deviceName) 126 log.info("device name '%s' for ip '%s'", deviceName, manageIp) 127 deviceClass = context.getDmdRoot("Devices").createOrganizer(devicePath) 128 deviceName = context.prepId(deviceName) 129 device = deviceClass.createInstance(deviceName) 130 device.setManageIp(manageIp) 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 performanceMonitor, priority, zProperties) 139 return device
140 141
142 -def findCommunity(context, ip, devicePath, 143 community="", port=None, version=None):
144 """ 145 Find the SNMP community and version for an ip address using zSnmpCommunities. 146 147 @rtype: tuple of (community, port, version, device name) 148 """ 149 from pynetsnmp.SnmpSession import SnmpSession 150 151 devroot = context.getDmdRoot('Devices').createOrganizer(devicePath) 152 communities = [] 153 if community: communities.append(community) 154 communities.extend(getattr(devroot, "zSnmpCommunities", [])) 155 if not port: port = getattr(devroot, "zSnmpPort", 161) 156 versions = ('v2c', 'v1') 157 if not version: version = getattr(devroot, 'zSnmpVer', None) 158 if version: versions = (version,) 159 timeout = getattr(devroot, "zSnmpTimeout", 2) 160 retries = getattr(devroot, "zSnmpTries", 2) 161 session = SnmpSession(ip, timeout=timeout, port=port, retries=retries) 162 oid = '.1.3.6.1.2.1.1.5.0' 163 goodcommunity = "" 164 goodversion = "" 165 devname = "" 166 for version in versions: 167 session.setVersion(version) 168 for community in communities: 169 session.community = community 170 try: 171 devname = session.get(oid).values()[0] 172 goodcommunity = session.community 173 goodversion = version 174 break 175 except (SystemExit, KeyboardInterrupt, POSError): raise 176 except: pass #keep trying until we run out 177 if goodcommunity: 178 break 179 else: 180 raise NoSnmp("No SNMP found for IP = %s" % ip) 181 return (goodcommunity, port, goodversion, devname)
182
183 -def manage_addDevice(context, id, REQUEST = None):
184 """ 185 Creates a device 186 """ 187 serv = Device(id) 188 context._setObject(serv.id, serv) 189 if REQUEST is not None: 190 messaging.IMessageSender(self).sendToBrowser( 191 'Device Added', 192 'Device %s has been created.' % id 193 ) 194 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
195 196 addDevice = DTMLFile('dtml/addDevice',globals()) 197 198
199 -class Device(ManagedEntity, Commandable, Lockable, MaintenanceWindowable, 200 AdministrativeRoleable, ZenMenuable):
201 """ 202 Device is a base class that represents the idea of a single computer system 203 that is made up of software running on hardware. It currently must be IP 204 enabled but maybe this will change. 205 """ 206 207 implements(IEventView) 208 209 event_key = portal_type = meta_type = 'Device' 210 211 default_catalog = "deviceSearch" #device ZCatalog 212 213 relationshipManagerPathRestriction = '/Devices' 214 215 manageIp = "" 216 productionState = 1000 217 preMWProductionState = productionState 218 snmpAgent = "" 219 snmpDescr = "" 220 snmpOid = "" 221 snmpContact = "" 222 snmpSysName = "" 223 snmpLocation = "" 224 rackSlot = "" 225 comments = "" 226 sysedgeLicenseMode = "" 227 priority = 3 228 229 # Flag indicating whether device is in process of creation 230 _temp_device = False 231 232 _properties = ManagedEntity._properties + ( 233 {'id':'manageIp', 'type':'string', 'mode':'w'}, 234 {'id':'productionState', 'type':'keyedselection', 'mode':'w', 235 'select_variable':'getProdStateConversions','setter':'setProdState'}, 236 {'id':'preMWProductionState', 'type':'keyedselection', 'mode':'w', 237 'select_variable':'getProdStateConversions','setter':'setProdState'}, 238 {'id':'snmpAgent', 'type':'string', 'mode':'w'}, 239 {'id':'snmpDescr', 'type':'string', 'mode':''}, 240 {'id':'snmpOid', 'type':'string', 'mode':''}, 241 {'id':'snmpContact', 'type':'string', 'mode':''}, 242 {'id':'snmpSysName', 'type':'string', 'mode':''}, 243 {'id':'snmpLocation', 'type':'string', 'mode':''}, 244 {'id':'snmpLastCollection', 'type':'date', 'mode':''}, 245 {'id':'snmpAgent', 'type':'string', 'mode':''}, 246 {'id':'rackSlot', 'type':'string', 'mode':'w'}, 247 {'id':'comments', 'type':'text', 'mode':'w'}, 248 {'id':'sysedgeLicenseMode', 'type':'string', 'mode':''}, 249 {'id':'priority', 'type':'int', 'mode':'w'}, 250 ) 251 252 _relations = ManagedEntity._relations + ( 253 ("deviceClass", ToOne(ToManyCont, "Products.ZenModel.DeviceClass", 254 "devices")), 255 ("perfServer", ToOne(ToMany, "Products.ZenModel.PerformanceConf", 256 "devices")), 257 ("location", ToOne(ToMany, "Products.ZenModel.Location", "devices")), 258 ("systems", ToMany(ToMany, "Products.ZenModel.System", "devices")), 259 ("groups", ToMany(ToMany, "Products.ZenModel.DeviceGroup", "devices")), 260 ("maintenanceWindows",ToManyCont(ToOne, 261 "Products.ZenModel.MaintenanceWindow", "productionState")), 262 ("adminRoles", ToManyCont(ToOne,"Products.ZenModel.AdministrativeRole", 263 "managedObject")), 264 ('userCommands', ToManyCont(ToOne, 'Products.ZenModel.UserCommand', 265 'commandable')), 266 # unused: 267 ('monitors', ToMany(ToMany, 'Products.ZenModel.StatusMonitorConf', 268 'devices')), 269 ) 270 271 # Screen action bindings (and tab definitions) 272 factory_type_information = ( 273 { 274 'id' : 'Device', 275 'meta_type' : 'Device', 276 'description' : """Base class for all devices""", 277 'icon' : 'Device_icon.gif', 278 'product' : 'ZenModel', 279 'factory' : 'manage_addDevice', 280 'immediate_view' : 'deviceStatus', 281 'actions' : 282 ( 283 { 'id' : 'status' 284 , 'name' : 'Status' 285 , 'action' : 'deviceStatus' 286 , 'permissions' : (ZEN_VIEW, ) 287 }, 288 { 'id' : 'osdetail' 289 , 'name' : 'OS' 290 , 'action' : 'deviceOsDetail' 291 , 'permissions' : (ZEN_VIEW, ) 292 }, 293 { 'id' : 'hwdetail' 294 , 'name' : 'Hardware' 295 , 'action' : 'deviceHardwareDetail' 296 , 'permissions' : (ZEN_VIEW, ) 297 }, 298 { 'id' : 'swdetail' 299 , 'name' : 'Software' 300 , 'action' : 'deviceSoftwareDetail' 301 , 'permissions' : (ZEN_VIEW, ) 302 }, 303 { 'id' : 'events' 304 , 'name' : 'Events' 305 , 'action' : 'viewEvents' 306 , 'permissions' : (ZEN_VIEW, ) 307 }, 308 # { 'id' : 'historyEvents' 309 # , 'name' : 'History' 310 # , 'action' : 'viewHistoryEvents' 311 # , 'permissions' : (ZEN_VIEW, ) 312 # }, 313 { 'id' : 'perfServer' 314 , 'name' : 'Perf' 315 , 'action' : 'viewDevicePerformance' 316 , 'permissions' : (ZEN_VIEW, ) 317 }, 318 # { 'id' : 'perfConf' 319 # , 'name' : 'PerfConf' 320 # , 'action' : 'objTemplates' 321 # , 'permissions' : ("Change Device", ) 322 # }, 323 { 'id' : 'edit' 324 , 'name' : 'Edit' 325 , 'action' : 'editDevice' 326 , 'permissions' : ("Change Device",) 327 }, 328 # { 'id' : 'management' 329 # , 'name' : 'Administration' 330 # , 'action' : 'deviceManagement' 331 # , 'permissions' : ("Change Device",) 332 # }, 333 # { 'id' : 'custom' 334 # , 'name' : 'Custom' 335 # , 'action' : 'deviceCustomEdit' 336 # , 'permissions' : (ZEN_VIEW, ) 337 # }, 338 # { 'id' : 'config' 339 # , 'name' : 'zProperties' 340 # , 'action' : 'zPropertyEdit' 341 # , 'permissions' : (ZEN_VIEW,) 342 # }, 343 # { 'id' : 'viewHistory' 344 # , 'name' : 'Modifications' 345 # , 'action' : 'viewHistory' 346 # , 'permissions' : (ZEN_VIEW, ) 347 # }, 348 # { 'id' : 'zProperties' 349 # , 'name' : 'zProperties' 350 # , 'action' : 'zPropertyEdit' 351 # , 'permissions' : ( ZEN_VIEW, ) 352 # }, 353 ) 354 }, 355 ) 356 357 security = ClassSecurityInfo() 358
359 - def __init__(self, id, buildRelations=True):
360 ManagedEntity.__init__(self, id, buildRelations=buildRelations) 361 os = OperatingSystem() 362 self._setObject(os.id, os) 363 hw = DeviceHW() 364 self._setObject(hw.id, hw) 365 #self.commandStatus = "Not Tested" 366 self._lastPollSnmpUpTime = ZenStatus(0) 367 self._snmpLastCollection = 0 368 self._lastChange = 0
369
370 - def isTempDevice(self):
371 flag = getattr(self, '_temp_device', None) 372 if flag is None: 373 flag = self._temp_device = False 374 return flag
375 376 377 security.declareProtected(ZEN_MANAGE_DMD, 'changeDeviceClass')
378 - def changeDeviceClass(self, deviceClassPath, REQUEST=None):
379 """ 380 Wrapper for DeviceClass.moveDevices. The primary reason to use this 381 method instead of that one is that this one redirects the user to the 382 device in the web interface instead of the new device class. 383 384 @param deviceClassPath: device class in DMD path 385 @type deviceClassPath: string 386 @param REQUEST: Zope REQUEST object 387 @type REQUEST: Zope REQUEST object 388 """ 389 self.deviceClass().moveDevices(deviceClassPath, (self.id,)) 390 if REQUEST: 391 messaging.IMessageSender(self).sendToBrowser( 392 title='Device Moved', 393 body="%s was moved to %s." % (self.id, deviceClassPath)) 394 REQUEST['message'] = "%s moved to %s" % (self.id, deviceClassPath) 395 if isinstance(REQUEST, FakeRequest) and \ 396 REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'): 397 return REQUEST['message'] 398 device = self.getDmdRoot('Devices').findDevice(self.id) 399 REQUEST['RESPONSE'].redirect(device.absolute_url()) 400 return
401 402
403 - def getRRDTemplate(self):
404 """ 405 DEPRECATED 406 """ 407 import warnings 408 warnings.warn('Device.getRRDTemplate is deprecated', 409 DeprecationWarning) 410 return ManagedEntity.getRRDTemplate(self)
411
412 - def getRRDTemplates(self):
413 """ 414 Returns all the templates bound to this Device 415 416 @rtype: list 417 418 >>> from Products.ZenModel.Device import manage_addDevice 419 >>> manage_addDevice(devices, 'test') 420 >>> devices.test.getRRDTemplates() 421 [<RRDTemplate at /zport/dmd/Devices/rrdTemplates/Device>] 422 """ 423 if not hasattr(self, 'zDeviceTemplates'): 424 return ManagedEntity.getRRDTemplates(self) 425 result = [] 426 for name in self.zDeviceTemplates: 427 template = self.getRRDTemplateByName(name) 428 if template: 429 result.append(template) 430 return result
431 432
433 - def getRRDNames(self):
434 return ['sysUpTime']
435 436
437 - def getDataSourceOptions(self):
438 """ 439 Returns the available DataSource options. DataSource options 440 are used to populate the dropdown when adding a new DataSource 441 and is a string. See L{RRDTemplate.RRDTemplate.getDataSourceOptions} 442 for more information. 443 444 @rtype: list 445 @return: [(displayName, dsOption),] 446 """ 447 # This is an unfortunate hack. Called from the device templates 448 # page where we show multiple templates now. This only really 449 # works because getDataSourceOptions() returns the same values 450 # for every template. Ideally we would be able to pass some sort 451 # of context to the Add DataSource dialog that calls this method. 452 templates = self.getRRDTemplates() 453 if templates: 454 return templates[0].getDataSourceOptions() 455 return []
456 457 # security.declareProtected('Manage DMD', 'manage_resequenceRRDGraphs') 458 # def manage_resequenceRRDGraphs(self, templateId, seqmap=(), origseq=(), REQUEST=None): 459 # """Reorder the sequecne of the RRDGraphs. 460 # """ 461 # template = self.getRRDTemplateByName(templateId) 462 # return template.manage_resequenceRRDGraphs(seqmap, origseq, REQUEST) 463 464
465 - def sysUpTime(self):
466 """ 467 Returns the cached sysUpTime for this device 468 469 @rtype: int 470 """ 471 try: 472 return self.cacheRRDValue('sysUpTime', -1) 473 except Exception: 474 log.exception("failed getting sysUpTime") 475 return -1
476 477
478 - def availability(self, *args, **kw):
479 """ 480 Returns the uptime of this device 481 482 @rtype: string 483 @todo: Performance enhancement: Should move import outside of method 484 """ 485 from Products.ZenEvents import Availability 486 results = Availability.query(self.dmd, device=self.id, *args, **kw) 487 if results: 488 return results[0] 489 else: 490 return None
491 492 493 # FIXME: cleanup --force option #2660
494 - def __getattr__(self, name):
495 """ 496 Override from object to handle lastPollSnmpUpTime and 497 snmpLastCollection 498 499 @todo: Not sure this is needed, see getLastPollSnmpUpTime and 500 getSnmpLastCollection 501 """ 502 if name == 'lastPollSnmpUpTime': 503 return self._lastPollSnmpUpTime.getStatus() 504 elif name == 'snmpLastCollection': 505 return DateTime(self._snmpLastCollection) 506 else: 507 raise AttributeError( name )
508 509
510 - def _setPropValue(self, id, value):
511 """ 512 Override from PropertyManager to handle checks and ip creation 513 514 @todo: Not sure this is needed, see setSnmpLastCollection 515 """ 516 self._wrapperCheck(value) 517 if id == 'snmpLastCollection': 518 self._snmpLastCollection = float(value) 519 else: 520 ManagedEntity._setPropValue(self, id, value)
521 522
523 - def applyDataMap(self, datamap, relname="", compname="", modname=""):
524 """ 525 Apply a datamap passed as a list of dicts through XML-RPC. 526 """ 527 adm = ApplyDataMap() 528 adm.applyDataMap(self, datamap, relname=relname, 529 compname=compname, modname=modname)
530 531
532 - def path(self):
533 """ 534 Return a sequence of path tuples suitable for indexing by 535 a MultiPathIndex. 536 """ 537 orgs = ( 538 self.systems() + 539 self.groups() + 540 [self.location()] + 541 [self.deviceClass()] 542 ) 543 orgs = filter(None, orgs) 544 paths = [] 545 for org in orgs: 546 rel = org.primaryAq().devices 547 try: 548 orgself = rel._getOb(self.getPrimaryId()) 549 except AttributeError: 550 # Device class wants an id, not a path 551 orgself = rel._getOb(self.getId()) 552 paths.append(orgself.getPhysicalPath()) 553 return paths
554 555
556 - def traceRoute(self, target, ippath=None):
557 """ 558 Trace the route to target using our routing table. 559 Wrapper method of OperatingSystem.traceRoute 560 561 @param target: Device name 562 @type target: string 563 @param ippath: IP addesses 564 @type ippath: list 565 @return: IP Addresses 566 @rtype: list 567 """ 568 if ippath is None: ippath=[] 569 if type(target) in types.StringTypes: 570 target = self.findDevice(target) 571 if not target: raise ValueError("Target %s not found in DMD" % target) 572 return self.os.traceRoute(target, ippath)
573 574
575 - def getMonitoredComponents(self, collector=None, type=None):
576 """ 577 Return list of monitored DeviceComponents on this device. 578 Wrapper method for getDeviceComponents 579 """ 580 return self.getDeviceComponents(monitored=True, 581 collector=collector, type=type)
582 583 security.declareProtected(ZEN_VIEW, 'getDeviceComponents')
584 - def getDeviceComponents(self, monitored=None, collector=None, type=None):
585 """ 586 Return list of all DeviceComponents on this device. 587 588 @type monitored: boolean 589 @type collector: string 590 @type type: string 591 @permission: ZEN_VIEW 592 @rtype: list 593 """ 594 # The getParentDeviceName index was added in 2.2. During migrates 595 # this code could execute before the 2.2 migrate steps are run, so we 596 # need to properly cope with this case. 597 # See ticket #2787 598 if not self.componentSearch._catalog.indexes.has_key('getParentDeviceName'): 599 return self.getDeviceComponentsNoIndexGen() 600 601 query = { 602 'getParentDeviceName':self.id, 603 } 604 if collector is not None: 605 query['getCollectors'] = collector 606 if monitored is not None: 607 query['monitored'] = monitored 608 if type is not None: 609 query['meta_type'] = type 610 brains = self.componentSearch(query) 611 return [c.getObject() for c in brains]
612 613
615 """ 616 Return a list of all device components by walking relations. This is 617 much slower then the normal getDeviceComponents method which uses the 618 component index. It is used when rebuilding the device indexes. 619 """ 620 from DeviceComponent import DeviceComponent 621 for baseObject in (self, self.os, self.hw): 622 for rel in baseObject.getRelationships(): 623 if rel.meta_type != "ToManyContRelationship": continue 624 for obj in rel(): 625 if not isinstance(obj, DeviceComponent): break 626 yield obj
627 628
629 - def getSnmpConnInfo(self):
630 """ 631 Returns an object containing SNMP Connection Info 632 633 @rtype: SnmpConnInfo object 634 """ 635 from Products.ZenHub.services.PerformanceConfig import SnmpConnInfo 636 return SnmpConnInfo(self)
637 638
639 - def getHWManufacturerName(self):
640 """ 641 DEPRECATED - Return the hardware manufacturer name of this device. 642 643 @rtype: string 644 @todo: Remove this method and remove the call from testDevice.py 645 """ 646 return self.hw.getManufacturerName()
647 648
649 - def getHWProductName(self):
650 """ 651 Return the hardware product name of this device. 652 653 @rtype: string 654 """ 655 return self.hw.getProductName()
656 657
658 - def getHWProductKey(self):
659 """ 660 DEPRECATED - Return the productKey of the device hardware. 661 662 @rtype: string 663 @todo: Remove this method and remove the call from testDevice.py 664 """ 665 return self.hw.getProductKey()
666 667
668 - def getOSManufacturerName(self):
669 """ 670 DEPRECATED - Return the OS manufacturer name of this device. 671 672 @rtype: string 673 @todo: Remove this method and remove the call from testDevice.py 674 """ 675 return self.os.getManufacturerName()
676 677
678 - def getOSProductName(self):
679 """ 680 DEPRECATED - Return the OS product name of this device. 681 682 @rtype: string 683 @todo: Remove this method and remove the call from testDevice.py 684 """ 685 return self.os.getProductName()
686 687
688 - def getOSProductKey(self):
689 """ 690 DEPRECATED - Return the productKey of the device OS. 691 692 @rtype: string 693 @todo: Remove this method and remove the call from testDevice.py 694 """ 695 return self.os.getProductKey()
696 697
698 - def setOSProductKey(self, prodKey, manufacturer="Unknown"):
699 """ 700 Set the productKey of the device OS. 701 """ 702 self.os.setProductKey(prodKey, manufacturer)
703 704
705 - def getHWTag(self):
706 """ 707 DEPRECATED - Return the tag of the device HW. 708 709 @rtype: string 710 @todo: remove this method and remove the call from testDevice.py 711 """ 712 return self.hw.tag
713 714
715 - def setHWTag(self, assettag):
716 """ 717 Set the asset tag of the device hardware. 718 """ 719 self.hw.tag = assettag
720 721
722 - def setHWProductKey(self, prodKey, manufacturer="Unknown"):
723 """ 724 Set the productKey of the device hardware. 725 """ 726 self.hw.setProductKey(prodKey, manufacturer)
727 728
729 - def setHWSerialNumber(self, number):
730 """ 731 Set the hardware serial number. 732 """ 733 self.hw.serialNumber = number
734 735
736 - def getHWSerialNumber(self):
737 """ 738 DEPRECATED - Return the hardware serial number. 739 740 @rtype: string 741 @todo: Remove this method and remove the call from testDevice.py 742 """ 743 return self.hw.serialNumber
744 745
746 - def followNextHopIps(self):
747 """ 748 Return the ips that our indirect routs point to which aren't currently 749 connected to devices. 750 751 @todo: Can be moved to zendisc.py 752 """ 753 ips = [] 754 for r in self.os.routes(): 755 ipobj = r.nexthop() 756 #if ipobj and not ipobj.device(): 757 if ipobj: ips.append(ipobj.id) 758 return ips
759 760 761 security.declareProtected(ZEN_VIEW, 'getLocationName')
762 - def getLocationName(self):
763 """ 764 Return the full location name ie /Location/SubLocation/Rack 765 766 @rtype: string 767 @permission: ZEN_VIEW 768 """ 769 loc = self.location() 770 if loc: return loc.getOrganizerName() 771 return ""
772 773 security.declareProtected(ZEN_VIEW, 'getLocationLink') 789 790 791 security.declareProtected(ZEN_VIEW, 'getSystemNames')
792 - def getSystemNames(self):
793 """ 794 Return the system names for this device 795 796 @rtype: list 797 @permission: ZEN_VIEW 798 """ 799 return map(lambda x: x.getOrganizerName(), self.systems())
800 801 802 security.declareProtected(ZEN_VIEW, 'getSystemNamesString')
803 - def getSystemNamesString(self, sep=', '):
804 """ 805 Return the system names for this device as a string 806 807 @rtype: string 808 @permission: ZEN_VIEW 809 """ 810 return sep.join(self.getSystemNames())
811 812 813 security.declareProtected(ZEN_VIEW, 'getDeviceGroupNames')
814 - def getDeviceGroupNames(self):
815 """ 816 Return the device group names for this device 817 818 @rtype: list 819 @permission: ZEN_VIEW 820 """ 821 return map(lambda x: x.getOrganizerName(), self.groups())
822 823 824 security.declareProtected(ZEN_VIEW, 'getPerformanceServer')
825 - def getPerformanceServer(self):
826 """ 827 Return the device performance server 828 829 @rtype: PerformanceMonitor 830 @permission: ZEN_VIEW 831 """ 832 return self.perfServer()
833 834 835 security.declareProtected(ZEN_VIEW, 'getPerformanceServerName')
836 - def getPerformanceServerName(self):
837 """ 838 Return the device performance server name 839 840 @rtype: string 841 @permission: ZEN_VIEW 842 """ 843 cr = self.perfServer() 844 if cr: return cr.getId() 845 return ''
846 847
848 - def getNetworkRoot(self):
849 """Return the network root object 850 """ 851 return self.getDmdRoot('Networks')
852 853 security.declareProtected(ZEN_VIEW, 'getLastChange')
854 - def getLastChange(self):
855 """ 856 Return DateTime of last change detected on this device. 857 858 @rtype: DateTime 859 @permission: ZEN_VIEW 860 """ 861 return DateTime(float(self._lastChange))
862 863 864 security.declareProtected(ZEN_VIEW, 'getLastChangeString')
865 - def getLastChangeString(self):
866 """ 867 Return date string of last change detected on this device. 868 869 @rtype: string 870 @permission: ZEN_VIEW 871 """ 872 return Time.LocalDateTimeSecsResolution(float(self._lastChange))
873 874 875 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollection')
876 - def getSnmpLastCollection(self):
877 """ 878 Return DateTime of last SNMP collection on this device. 879 880 @rtype: DateTime 881 @permission: ZEN_VIEW 882 """ 883 return DateTime(float(self._snmpLastCollection))
884 885 886 security.declareProtected(ZEN_VIEW, 'getSnmpLastCollectionString')
888 """ 889 Return date string of last SNMP collection on this device. 890 891 @rtype: string 892 @permission: ZEN_VIEW 893 """ 894 return Time.LocalDateTimeSecsResolution(float(self._snmpLastCollection))
895 896 897 security.declareProtected(ZEN_ADMIN_DEVICE, 'setManageIp')
898 - def setManageIp(self, ip="", REQUEST=None):
899 """ 900 Set the manage IP, if IP is not passed perform DNS lookup. 901 902 @rtype: string 903 @permission: ZEN_ADMIN_DEVICE 904 """ 905 origip = ip 906 try: 907 if ip.find("/") > -1: 908 ipWithoutNetmask, netmask = ip.split("/",1) 909 checkip(ipWithoutNetmask) 910 # Also check for valid netmask 911 if maskToBits(netmask) is None: ip = "" 912 else: 913 checkip(ip) 914 except IpAddressError: ip = "" 915 except ValueError: ip = "" 916 if not ip: 917 try: ip = socket.gethostbyname(self.id) 918 except socket.error: ip = "" 919 self.manageIp = ip 920 self.index_object() 921 if REQUEST: 922 msgr = IMessageSender(self) 923 if ip: 924 msgr.sendToBrowser('Manage IP Set', 925 "%s's IP address has been set to %s." % (self.id, ip)) 926 else: 927 msgr.sendToBrowser('Invalid IP', 928 ("%s is an invalid IP address, and no appropriate IP could" 929 " be found via DNS") % origip) 930 return self.callZenScreen(REQUEST) 931 else: 932 return self.manageIp
933 934 935 security.declareProtected(ZEN_VIEW, 'getManageIp')
936 - def getManageIp(self):
937 """ 938 Return the management ip for this device. 939 940 @rtype: string 941 @permission: ZEN_VIEW 942 """ 943 return self.manageIp
944 945
946 - def getManageIpObj(self):
947 """ 948 DEPRECATED - Return the management ipobject for this device. 949 950 @rtype: IpAddress 951 @todo: This method may not be called anywhere, remove it. 952 """ 953 if self.manageIp: 954 return self.Networks.findIp(self.manageIp)
955 956 957 security.declareProtected(ZEN_VIEW, 'getManageInterface')
958 - def getManageInterface(self):
959 """ 960 Return the management interface of a device based on its manageIp. 961 962 @rtype: IpInterface 963 @permission: ZEN_VIEW 964 """ 965 ipobj = self.Networks.findIp(self.manageIp) 966 if ipobj: return ipobj.interface()
967 968 969 security.declareProtected(ZEN_VIEW, 'uptimeStr')
970 - def uptimeStr(self):
971 """ 972 Return the SNMP uptime 973 974 @rtype: string 975 @permission: ZEN_VIEW 976 """ 977 ut = self.sysUpTime() 978 if ut < 0: 979 return "Unknown" 980 elif ut == 0: 981 return "0d:0h:0m:0s" 982 ut = float(ut)/100. 983 days = ut/86400 984 hour = (ut%86400)/3600 985 mins = (ut%3600)/60 986 secs = ut%60 987 return "%02dd:%02dh:%02dm:%02ds" % ( 988 days, hour, mins, secs)
989 990
991 - def getPeerDeviceClassNames(self):
992 """ 993 Build a list of all device paths that have the python class pyclass 994 995 @rtype: list 996 """ 997 dclass = self.getDmdRoot("Devices") 998 return dclass.getPeerDeviceClassNames(self.__class__)
999 1000 1001 #################################################################### 1002 # Edit functions used to manage device relations and other attributes 1003 #################################################################### 1004 1005 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_snmpCommunity')
1006 - def manage_snmpCommunity(self):
1007 """ 1008 Reset the snmp community using the zSnmpCommunities variable. 1009 1010 @permission: ZEN_CHANGE_DEVICE 1011 """ 1012 try: 1013 zSnmpCommunity, zSnmpPort, zSnmpVer, snmpname = \ 1014 findCommunity(self, self.manageIp, self.getDeviceClassPath(), 1015 port=self.zSnmpPort, version=self.zSnmpVer) 1016 except NoSnmp: 1017 pass 1018 else: 1019 if self.zSnmpCommunity != zSnmpCommunity: 1020 self.setZenProperty("zSnmpCommunity", zSnmpCommunity) 1021 if self.zSnmpPort != zSnmpPort: 1022 self.setZenProperty("zSnmpPort", zSnmpPort) 1023 if self.zSnmpVer != zSnmpVer: 1024 self.setZenProperty("zSnmpVer", zSnmpVer)
1025 1026 1027 security.declareProtected(ZEN_CHANGE_DEVICE, 'manage_editDevice')
1028 - def manage_editDevice(self, 1029 tag="", serialNumber="", 1030 zSnmpCommunity="", zSnmpPort=161, zSnmpVer="", 1031 rackSlot="", productionState=1000, comments="", 1032 hwManufacturer="", hwProductName="", 1033 osManufacturer="", osProductName="", 1034 locationPath="", groupPaths=[], systemPaths=[], 1035 performanceMonitor="localhost", priority=3, 1036 zProperties=None, REQUEST=None):
1037 """ 1038 Edit the device relation and attributes. 1039 1040 @param locationPath: path to a Location 1041 @type locationPath: string 1042 @param groupPaths: paths to DeviceGroups 1043 @type groupPaths: list 1044 @param systemPaths: paths to Systems 1045 @type systemPaths: list 1046 @param performanceMonitor: name of PerformanceMonitor 1047 @type performanceMonitor: string 1048 @permission: ZEN_CHANGE_DEVICE 1049 """ 1050 self.hw.tag = tag 1051 self.hw.serialNumber = serialNumber 1052 1053 # Set zProperties passed in intelligently 1054 if zProperties is None: zProperties = {} 1055 zProperties.update({'zSnmpCommunity':zSnmpCommunity, 1056 'zSnmpPort':zSnmpPort, 1057 'zSnmpVer':zSnmpVer}) 1058 for prop, value in zProperties.items(): 1059 if value and getattr(self, prop) != value: 1060 self.setZenProperty(prop, value) 1061 1062 self.rackSlot = rackSlot 1063 self.setProdState(productionState) 1064 self.setPriority(priority) 1065 self.comments = comments 1066 1067 if hwManufacturer and hwProductName: 1068 log.info("setting hardware manufacturer to %s productName to %s" 1069 % (hwManufacturer, hwProductName)) 1070 self.hw.setProduct(hwProductName, hwManufacturer) 1071 else: 1072 self.hw.productClass.removeRelation() 1073 1074 if osManufacturer and osProductName: 1075 log.info("setting os manufacturer to %s productName to %s" 1076 % (osManufacturer, osProductName)) 1077 self.os.setProduct(osProductName, osManufacturer) 1078 self.os.productClass().isOS = True 1079 else: 1080 self.os.productClass.removeRelation() 1081 1082 if locationPath: 1083 log.info("setting location to %s" % locationPath) 1084 self.setLocation(locationPath) 1085 1086 if groupPaths: 1087 log.info("setting group %s" % groupPaths) 1088 self.setGroups(groupPaths) 1089 1090 if systemPaths: 1091 log.info("setting system %s" % systemPaths) 1092 self.setSystems(systemPaths) 1093 1094 if performanceMonitor != self.getPerformanceServerName(): 1095 log.info("setting performance monitor to %s" % performanceMonitor) 1096 self.setPerformanceMonitor(performanceMonitor) 1097 1098 self.setLastChange() 1099 self.index_object() 1100 if REQUEST: 1101 from Products.ZenUtils.Time import SaveMessage 1102 IMessageSender(self).sendToBrowser('Saved', SaveMessage()) 1103 return self.callZenScreen(REQUEST)
1104 1105
1106 - def monitorDevice(self):
1107 """ 1108 Returns true if the device production state >= zProdStateThreshold. 1109 1110 @rtype: boolean 1111 """ 1112 return self.productionState >= self.zProdStateThreshold
1113 1114
1115 - def snmpMonitorDevice(self):
1116 """ 1117 Returns true if the device is subject to SNMP monitoring 1118 1119 @rtype: boolean 1120 """ 1121 return (self.monitorDevice() 1122 and self.getManageIp() 1123 and not self.zSnmpMonitorIgnore)
1124 1125
1126 - def getProductionStateString(self):
1127 """ 1128 Return the prodstate as a string. 1129 1130 @rtype: string 1131 """ 1132 return self.convertProdState(self.productionState)
1133 1134
1135 - def getPriority(self):
1136 """ 1137 Return the numeric device priority. 1138 1139 @rtype: int 1140 """ 1141 return self.priority
1142 1143
1144 - def getPriorityString(self):
1145 """ 1146 Return the device priority as a string. 1147 1148 @rtype: string 1149 """ 1150 return self.convertPriority(self.priority)
1151
1152 - def getPingStatusString(self):
1153 """ 1154 Return the pingStatus as a string 1155 1156 @rtype: string 1157 """ 1158 return self.convertStatus(self.getPingStatus())
1159
1160 - def getSnmpStatusString(self):
1161 """ 1162 Return the snmpStatus as a string 1163 1164 @rtype: string 1165 """ 1166 return self.convertStatus(self.getSnmpStatus())
1167 1168 security.declareProtected(ZEN_CHANGE_DEVICE, 'setProdState')
1169 - def setProdState(self, state, maintWindowChange=False, REQUEST=None):
1170 """ 1171 Set the device's production state. 1172 1173 @parameter state: new production state 1174 @type state: int 1175 @parameter maintWindowChange: are we resetting state from inside a MW? 1176 @type maintWindowChange: boolean 1177 @permission: ZEN_CHANGE_DEVICE 1178 """ 1179 self.productionState = int(state) 1180 self.primaryAq().index_object() 1181 if not maintWindowChange: 1182 # Saves our production state for use at the end of the 1183 # maintenance window. 1184 self.preMWProductionState = self.productionState 1185 1186 try: 1187 zem = self.dmd.ZenEventManager 1188 conn = zem.connect() 1189 try: 1190 curs = conn.cursor() 1191 curs.execute( 1192 "update status set prodState=%d where device='%s'" % ( 1193 self.productionState, self.id)) 1194 finally: zem.close(conn) 1195 except OperationalError: 1196 msg = "Failed to update events for %s with new prodState %s" % ( 1197 self.id, state) 1198 log.exception(msg) 1199 if REQUEST: 1200 IMessageSender(self).sendToBrowser( 1201 "Update Failed", 1202 msg, 1203 priority=messaging.WARNING 1204 ) 1205 return self.callZenScreen(REQUEST) 1206 1207 if REQUEST: 1208 IMessageSender(self).sendToBrowser( 1209 "Production State Set", 1210 "%s's production state was set to %s." % (self.id, 1211 self.getProductionStateString()) 1212 ) 1213 return self.callZenScreen(REQUEST)
1214 1215 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPriority')
1216 - def setPriority(self, priority, REQUEST=None):
1217 """ 1218 Set the device's priority 1219 1220 @type priority: int 1221 @permission: ZEN_CHANGE_DEVICE 1222 """ 1223 self.priority = int(priority) 1224 try: 1225 zem = self.dmd.ZenEventManager 1226 conn = zem.connect() 1227 try: 1228 curs = conn.cursor() 1229 curs.execute("update status set DevicePriority=%d where device='%s'" % ( 1230 self.priority, self.id)) 1231 finally: zem.close(conn) 1232 except OperationalError: 1233 log.exception("failed to update events with new priority") 1234 if REQUEST: 1235 messaging.IMessageSender(self).sendToBrowser( 1236 'Update Failed', 1237 "Failed to update events with new priority", 1238 priority=messaging.WARNING 1239 ) 1240 return self.callZenScreen(REQUEST) 1241 1242 if REQUEST: 1243 messaging.IMessageSender(self).sendToBrowser( 1244 'Priority Udpdated', 1245 "Device priority has been set to %s." % ( 1246 self.getPriorityString()) 1247 ) 1248 return self.callZenScreen(REQUEST)
1249 1250 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLastChange')
1251 - def setLastChange(self, value=None):
1252 """ 1253 Set the changed datetime for this device. 1254 1255 @param value: secs since the epoch, default is now 1256 @type value: float 1257 @permission: ZEN_CHANGE_DEVICE 1258 """ 1259 if value is None: 1260 value = time.time() 1261 self._lastChange = float(value)
1262 1263 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSnmpLastCollection')
1264 - def setSnmpLastCollection(self, value=None):
1265 """ 1266 Set the last time snmp collection occurred. 1267 1268 @param value: secs since the epoch, default is now 1269 @type value: float 1270 @permission: ZEN_CHANGE_DEVICE 1271 """ 1272 if value is None: 1273 value = time.time() 1274 self._snmpLastCollection = float(value)
1275 1276 1277 security.declareProtected(ZEN_CHANGE_DEVICE, 'addManufacturer')
1278 - def addManufacturer(self, newHWManufacturerName=None, 1279 newSWManufacturerName=None, REQUEST=None):
1280 """ 1281 DEPRECATED - 1282 Add either a hardware or software manufacturer to the database. 1283 1284 @permission: ZEN_CHANGE_DEVICE 1285 @todo: Doesn't really do work on a device object. 1286 Already exists on ZDeviceLoader 1287 """ 1288 mname = newHWManufacturerName 1289 field = 'hwManufacturer' 1290 if not mname: 1291 mname = newSWManufacturerName 1292 field = 'osManufacturer' 1293 self.getDmdRoot("Manufacturers").createManufacturer(mname) 1294 if REQUEST: 1295 REQUEST[field] = mname 1296 messaging.IMessageSender(self).sendToBrowser( 1297 'Manufacturer Added', 1298 'The %s manufacturer has been created.' % mname 1299 ) 1300 return self.callZenScreen(REQUEST)
1301 1302 1303 security.declareProtected(ZEN_CHANGE_DEVICE, 'setHWProduct')
1304 - def setHWProduct(self, newHWProductName=None, hwManufacturer=None, 1305 REQUEST=None):
1306 """ 1307 DEPRECATED - 1308 Adds a new hardware product 1309 1310 @permission: ZEN_CHANGE_DEVICE 1311 @todo: Doesn't really do work on a device object. 1312 Already exists on ZDeviceLoader 1313 """ 1314 added = False 1315 if newHWProductName and hwManufacturer: 1316 self.getDmdRoot("Manufacturers").createHardwareProduct( 1317 newHWProductName, hwManufacturer) 1318 added = True 1319 if REQUEST: 1320 if added: 1321 messaging.IMessageSender(self).sendToBrowser( 1322 'Product Set', 1323 'Hardware product has been set to %s.' % newHWProductName 1324 ) 1325 REQUEST['hwProductName'] = newHWProductName 1326 else: 1327 messaging.IMessageSender(self).sendToBrowser( 1328 'Set Product Failed', 1329 'Hardware product could not be set to %s.'%newHWProductName, 1330 priority=messaging.WARNING 1331 ) 1332 return self.callZenScreen(REQUEST)
1333 1334 1335 security.declareProtected(ZEN_CHANGE_DEVICE, 'setOSProduct')
1336 - def setOSProduct(self, newOSProductName=None, osManufacturer=None, REQUEST=None):
1337 """ 1338 DEPRECATED 1339 Adds a new os product 1340 1341 @permission: ZEN_CHANGE_DEVICE 1342 @todo: Doesn't really do work on a device object. 1343 Already exists on ZDeviceLoader 1344 """ 1345 if newOSProductName: 1346 self.getDmdRoot("Manufacturers").createSoftwareProduct( 1347 newOSProductName, osManufacturer, isOS=True) 1348 if REQUEST: 1349 if newOSProductName: 1350 messaging.IMessageSender(self).sendToBrowser( 1351 'Product Set', 1352 'OS product has been set to %s.' % newOSProductName 1353 ) 1354 REQUEST['osProductName'] = newOSProductName 1355 else: 1356 messaging.IMessageSender(self).sendToBrowser( 1357 'Set Product Failed', 1358 'OS product could not be set to %s.' % newOSProductName, 1359 priority=messaging.WARNING 1360 ) 1361 return self.callZenScreen(REQUEST)
1362 1363 1364 security.declareProtected(ZEN_CHANGE_DEVICE, 'setLocation')
1365 - def setLocation(self, locationPath, REQUEST=None):
1366 """ 1367 Set the location of a device. If the location is new it will be created. 1368 1369 @permission: ZEN_CHANGE_DEVICE 1370 """ 1371 if not locationPath: 1372 self.location.removeRelation() 1373 else: 1374 locobj = self.getDmdRoot("Locations").createOrganizer(locationPath) 1375 self.addRelation("location", locobj) 1376 self.setAdminLocalRoles() 1377 self.index_object()
1378 1379
1380 - def addLocation(self, newLocationPath, REQUEST=None):
1381 """ 1382 DEPRECATED 1383 Add a new location and relate it to this device 1384 1385 @todo: Doesn't really do work on a device object. 1386 Already exists on ZDeviceLoader 1387 """ 1388 self.getDmdRoot("Locations").createOrganizer(newLocationPath) 1389 if REQUEST: 1390 REQUEST['locationPath'] = newLocationPath 1391 messaging.IMessageSender(self).sendToBrowser( 1392 'Location Added', 1393 'Location %s has been created.' % newLocationPath 1394 ) 1395 return self.callZenScreen(REQUEST)
1396 1397 1398 security.declareProtected(ZEN_CHANGE_DEVICE, 'setPerformanceMonitor')
1399 - def setPerformanceMonitor(self, performanceMonitor, 1400 newPerformanceMonitor=None, REQUEST=None):
1401 """ 1402 Set the performance monitor for this device. 1403 If newPerformanceMonitor is passed in create it 1404 1405 @permission: ZEN_CHANGE_DEVICE 1406 """ 1407 if newPerformanceMonitor: 1408 #self.dmd.RenderServer.moveRRDFiles(self.id, 1409 # newPerformanceMonitor, performanceMonitor, REQUEST) 1410 performanceMonitor = newPerformanceMonitor 1411 1412 obj = self.getDmdRoot("Monitors").getPerformanceMonitor( 1413 performanceMonitor) 1414 self.addRelation("perfServer", obj) 1415 self.setLastChange() 1416 1417 if REQUEST: 1418 messaging.IMessageSender(self).sendToBrowser( 1419 'Monitor Changed', 1420 'Performance monitor has been set to %s.' % performanceMonitor 1421 ) 1422 return self.callZenScreen(REQUEST)
1423 1424 1425 security.declareProtected(ZEN_CHANGE_DEVICE, 'setGroups')
1426 - def setGroups(self, groupPaths):
1427 """ 1428 Set the list of groups for this device based on a list of paths 1429 1430 @permission: ZEN_CHANGE_DEVICE 1431 """ 1432 objGetter = self.getDmdRoot("Groups").createOrganizer 1433 self._setRelations("groups", objGetter, groupPaths) 1434 self.index_object()
1435 1436 1437 security.declareProtected(ZEN_CHANGE_DEVICE, 'addDeviceGroup')
1438 - def addDeviceGroup(self, newDeviceGroupPath, REQUEST=None):
1439 """ 1440 DEPRECATED? 1441 Add a device group to the database and this device 1442 1443 @permission: ZEN_CHANGE_DEVICE 1444 @todo: Already exists on ZDeviceLoader 1445 """ 1446 group = self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath) 1447 self.addRelation("groups", group) 1448 if REQUEST: 1449 messaging.IMessageSender(self).sendToBrowser( 1450 'Group Added', 1451 'Group %s has been created.' % newDeviceGroupPath 1452 ) 1453 return self.callZenScreen(REQUEST)
1454 1455 1456 security.declareProtected(ZEN_CHANGE_DEVICE, 'setSystems')
1457 - def setSystems(self, systemPaths):
1458 """ 1459 Set a list of systems to this device using their system paths 1460 1461 @permission: ZEN_CHANGE_DEVICE 1462 """ 1463 objGetter = self.getDmdRoot("Systems").createOrganizer 1464 self._setRelations("systems", objGetter, systemPaths) 1465 self.index_object()
1466 1467 1468 security.declareProtected(ZEN_CHANGE_DEVICE, 'addSystem')
1469 - def addSystem(self, newSystemPath, REQUEST=None):
1470 """ 1471 DEPRECATED? 1472 Add a systems to this device using its system path 1473 1474 @permission: ZEN_CHANGE_DEVICE 1475 @todo: Already exists on ZDeviceLoader 1476 """ 1477 sys = self.getDmdRoot("Systems").createOrganizer(newSystemPath) 1478 self.addRelation("systems", sys) 1479 if REQUEST: 1480 messaging.IMessageSender(self).sendToBrowser( 1481 'System Added', 1482 'System %s has been created.' % newSystemPath 1483 ) 1484 return self.callZenScreen(REQUEST)
1485 1486 1487 security.declareProtected(ZEN_CHANGE_DEVICE, 'setTerminalServer')
1488 - def setTerminalServer(self, termservername):
1489 """ 1490 Set the terminal server of this device 1491 1492 @param termservername: device name of terminal server 1493 @permission: ZEN_CHANGE_DEVICE 1494 """ 1495 termserver = self.findDevice(termservername) 1496 if termserver: 1497 self.addRelation('termserver', termserver)
1498 1499
1500 - def _setRelations(self, relName, objGetter, relPaths):
1501 """ 1502 Set related objects to this device 1503 1504 @param relName: name of the relation to set 1505 @param objGetter: method to get the relation 1506 @param relPaths: list of relationship paths 1507 """ 1508 if type(relPaths) != type([]) and type(relPaths) != type(()): 1509 relPaths = [relPaths,] 1510 relPaths = filter(lambda x: x.strip(), relPaths) 1511 rel = getattr(self, relName, None) 1512 if not rel: 1513 raise AttributeError( "Relation %s not found" % relName) 1514 curRelIds = {} 1515 for value in rel.objectValuesAll(): 1516 curRelIds[value.getOrganizerName()] = value 1517 for path in relPaths: 1518 if not curRelIds.has_key(path): 1519 robj = objGetter(path) 1520 self.addRelation(relName, robj) 1521 else: 1522 del curRelIds[path] 1523 for obj in curRelIds.values(): 1524 self.removeRelation(relName, obj) 1525 self.setAdminLocalRoles()
1526 1527 1540 1541 #################################################################### 1542 # Private getter functions that implement DeviceResultInt 1543 #################################################################### 1544 1545 security.declareProtected(ZEN_VIEW, 'device')
1546 - def device(self):
1547 """ 1548 Support DeviceResultInt mixin class. Returns itself 1549 1550 @permission: ZEN_VIEW 1551 """ 1552 return self
1553 1554 1555 #################################################################### 1556 # Status Management Functions used by status monitors 1557 #################################################################### 1558 1559
1560 - def pastSnmpMaxFailures(self):
1561 """ 1562 Returns true if the device has more SNMP failures 1563 than maxFailures on its status mon. 1564 1565 @rtype: boolean 1566 """ 1567 statusmon = self.monitors() 1568 if len(statusmon) > 0: 1569 statusmon = statusmon[0] 1570 return statusmon.maxFailures < self.getSnmpStatusNumber() 1571 return False
1572 1573 1574 # FIXME: cleanup --force option #2660 1575 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS, 1576 'getLastPollSnmpUpTime')
1577 - def getLastPollSnmpUpTime(self):
1578 """ 1579 Get the value of the snmpUpTime status object 1580 1581 @permission: ZEN_MANAGE_DEVICE_STATUS 1582 """ 1583 return self._lastPollSnmpUpTime.getStatus()
1584 1585 1586 # FIXME: cleanup --force option #2660 1587 security.declareProtected(ZEN_MANAGE_DEVICE_STATUS, 1588 'setLastPollSnmpUpTime')
1589 - def setLastPollSnmpUpTime(self, value):
1590 """ 1591 Set the value of the snmpUpTime status object 1592 1593 @permission: ZEN_MANAGE_DEVICE_STATUS 1594 """ 1595 self._lastPollSnmpUpTime.setStatus(value)
1596 1597
1598 - def snmpAgeCheck(self, hours):
1599 """ 1600 Returns True if SNMP data was collected more than 24 hours ago 1601 """ 1602 lastcoll = self.getSnmpLastCollection() 1603 hours = hours/24.0 1604 if DateTime() > lastcoll + hours: return 1
1605 1606
1607 - def applyProductContext(self):
1608 """ 1609 Apply zProperties inherited from Product Contexts. 1610 """ 1611 self._applyProdContext(self.hw.getProductContext()) 1612 self._applyProdContext(self.os.getProductContext()) 1613 for soft in self.os.software(): 1614 self._applyProdContext(soft.getProductContext())
1615 1616
1617 - def _applyProdContext(self, context):
1618 """ 1619 Apply zProperties taken for the product context passed in. 1620 1621 @param context: list of tuples returned from 1622 getProductContext on a MEProduct. 1623 """ 1624 for name, value in context: 1625 if name == "zDeviceClass" and value: 1626 log.info("move device to %s", value) 1627 self.moveDevices(value, self.id) 1628 elif name == "zDeviceGroup" and value: 1629 log.info("add device to group %s", value) 1630 self.addDeviceGroup(value) 1631 elif name == "zSystem" and value: 1632 log.info("add device to system %s", value) 1633 self.addSystem(value)
1634 1635 1636 1637 #################################################################### 1638 # Management Functions 1639 #################################################################### 1640 1641 security.declareProtected(ZEN_MANAGE_DEVICE, 'collectDevice')
1642 - def collectDevice(self, setlog=True, REQUEST=None, generateEvents=False):
1643 """ 1644 Collect the configuration of this device AKA Model Device 1645 1646 @param setlog: If true, set up the output log of this process 1647 @permission: ZEN_MANAGE_DEVICE 1648 @todo: generateEvents param is not being used. 1649 """ 1650 unused(generateEvents) 1651 xmlrpc = isXmlRpc(REQUEST) 1652 perfConf = self.getPerformanceServer() 1653 perfConf.collectDevice(self, setlog, REQUEST) 1654 1655 if xmlrpc: return 0
1656 1657 1658 security.declareProtected(ZEN_ADMIN_DEVICE, 'deleteDevice')
1659 - def deleteDevice(self, deleteStatus=False, deleteHistory=False, 1660 deletePerf=False, REQUEST=None):
1661 """ 1662 Delete device from the database 1663 1664 NB: deleteHistory is disabled for the 2.2 release. In some 1665 circumstances it was causing many subprocesses to be spawned 1666 and creating a gridlock situation. 1667 1668 @permission: ZEN_ADMIN_DEVICE 1669 """ 1670 parent = self.getPrimaryParent() 1671 if deleteStatus: 1672 self.getEventManager().manage_deleteHeartbeat(self.getId()) 1673 self.getEventManager().manage_deleteAllEvents(self.getId()) 1674 # if deleteHistory: 1675 # self.getEventManager().manage_deleteHistoricalEvents(self.getId()) 1676 if deletePerf: 1677 perfserv = self.getPerformanceServer() 1678 if perfserv: 1679 perfserv.deleteRRDFiles(self.id) 1680 parent._delObject(self.getId()) 1681 if REQUEST: 1682 if parent.getId()=='devices': 1683 parent = parent.getPrimaryParent() 1684 REQUEST['RESPONSE'].redirect(parent.absolute_url() + 1685 "/deviceOrganizerStatus" 1686 '?message=Device deleted')
1687 1688 1689 security.declareProtected(ZEN_MANAGE_DEVICE, 'manage_deleteHeartbeat')
1690 - def manage_deleteHeartbeat(self, REQUEST=None):
1691 """ 1692 Delete this device's heartbeats. 1693 1694 @permission: ZEN_MANAGE_DEVICE 1695 """ 1696 self.getEventManager().manage_deleteHeartbeat(self.getId()) 1697 if REQUEST: 1698 messaging.IMessageSender(self).sendToBrowser( 1699 'Heartbeats cleared', 1700 "Cleared heartbeat events for %s." % self.id 1701 ) 1702 return self.callZenScreen(REQUEST)
1703 1704 1705 security.declareProtected(ZEN_ADMIN_DEVICE, 'renameDevice')
1706 - def renameDevice(self, newId=None, REQUEST=None):
1707 """ 1708 Rename device from the DMD 1709 1710 @permission: ZEN_ADMIN_DEVICE 1711 @param newId: new name 1712 @type newId: string 1713 @param REQUEST: Zope REQUEST object 1714 @type REQUEST: Zope REQUEST object 1715 """ 1716 parent = self.getPrimaryParent() 1717 oldId = self.getId() 1718 if newId is None: 1719 if REQUEST: 1720 REQUEST['RESPONSE'].redirect("%s/%s" % (parent.absolute_url(), oldId)) 1721 return 1722 1723 if not isinstance(newId, unicode): 1724 newId = self.prepId(newId) 1725 1726 newId = newId.strip() 1727 1728 if newId == '' or newId == oldId: 1729 if REQUEST: 1730 REQUEST['RESPONSE'].redirect("%s/%s" % (parent.absolute_url(), oldId)) 1731 return 1732 1733 # side effect: self.getId() will return newId after this call 1734 try: 1735 parent.manage_renameObject(oldId, newId) 1736 1737 self.renameDeviceInEvents(oldId, newId) 1738 self.renameDeviceInPerformance(oldId, newId) 1739 self.setLastChange() 1740 1741 if REQUEST: 1742 messaging.IMessageSender(self).sendToBrowser( 1743 'Device Renamed', 1744 "Device %s was renamed to %s." % (oldId, newId) 1745 ) 1746 REQUEST['RESPONSE'].redirect("%s/%s" % (parent.absolute_url(), newId)) 1747 1748 except CopyError, e: 1749 if REQUEST: 1750 messaging.IMessageSender(self).sendToBrowser( 1751 'Device Rename Failed', str(e), messaging.CRITICAL) 1752 return self.callZenScreen(REQUEST)
1753
1754 - def renameDeviceInEvents(self, old, new):
1755 """update the device column in the status and history tables for rows 1756 associated with this device""" 1757 zem=self.dmd.ZenEventManager 1758 query="update %%s set device='%s' where device='%s';"%(new, old) 1759 sqlscript=''.join([query%t for t in ('status', 'history')]) 1760 args=['mysql', 1761 '-h%s'%zem.host, 1762 '-P%s'%zem.port, 1763 '-u%s'%zem.username, 1764 '-p%s'%zem.password, 1765 '-e%s'%sqlscript, 1766 zem.database, 1767 ] 1768 if not os.fork(): os.execvp('mysql', args)
1769
1770 - def renameDeviceInPerformance(self, old, new):
1771 """ 1772 Rename the directory that holds performance data for this device. 1773 1774 @param old: old performance directory name 1775 @type old: string 1776 @param new: new performance directory name 1777 @type new: string 1778 """ 1779 root = os.path.dirname(self.fullRRDPath()) 1780 oldpath = os.path.join(root, old) 1781 newpath = os.path.join(root, new) 1782 perfsvr = self.getPerformanceServer() 1783 if hasattr(perfsvr, 'isLocalHost') and not perfsvr.isLocalHost(): 1784 command = 'mv "%s" "%s"' % (oldpath, newpath) 1785 perfsvr.executeCommand(command, 'zenoss') 1786 elif os.path.exists(oldpath): 1787 if os.path.exists(newpath): 1788 shutil.rmtree(newpath) 1789 shutil.move(oldpath, newpath)
1790
1791 - def manage_afterAdd(self, item, container):
1792 """ 1793 Device only propagates afterAdd if it is the added object. 1794 """ 1795 super(Device,self).manage_afterAdd(item, container) 1796 self.index_object()
1797 1798
1799 - def manage_afterClone(self, item):
1800 """ 1801 DEPRECATED 1802 """ 1803 super(Device,self).manage_afterClone(item) 1804 self.index_object()
1805 1806
1807 - def manage_beforeDelete(self, item, container):
1808 """ 1809 Device only propagates beforeDelete if we are being deleted or copied. 1810 Moving and renaming don't propagate. 1811 """ 1812 super(Device,self).manage_beforeDelete(item, container) 1813 self.unindex_ips() # Clean up IpAddress links explicitly 1814 self.unindex_object()
1815 1816
1817 - def unindex_ips(self):
1818 """ 1819 IpAddresses aren't contained underneath Device, so manage_beforeDelete 1820 won't propagate. Thus we must remove those links explicitly. 1821 """ 1822 cat = self.dmd.ZenLinkManager._getCatalog(layer=3) 1823 brains = cat(deviceId=self.id) 1824 for brain in brains: 1825 brain.getObject().index_links()
1826 1827
1828 - def cacheComponents(self):
1829 """ 1830 Read current RRD values for all of a device's components 1831 """ 1832 paths = self.getRRDPaths()[:] 1833 #FIXME need better way to scope and need to get DataSources 1834 # from RRDTemplates 1835 #for c in self.os.interfaces(): paths.extend(c.getRRDPaths()) 1836 for c in self.os.filesystems(): paths.extend(c.getRRDPaths()) 1837 #for c in self.hw.harddisks(): paths.extend(c.getRRDPaths()) 1838 objpaq = self.primaryAq() 1839 perfServer = objpaq.getPerformanceServer() 1840 if perfServer: 1841 try: 1842 result = perfServer.currentValues(paths) 1843 if result: 1844 RRDView.updateCache(zip(paths, result)) 1845 except Exception: 1846 log.exception("Unable to cache values for %s", self.id);
1847 1848
1849 - def getUserCommandTargets(self):
1850 """ 1851 Called by Commandable.doCommand() to ascertain objects on which 1852 a UserCommand should be executed. 1853 """ 1854 return [self]
1855
1856 - def getUserCommandEnvironment(self):
1857 """ 1858 Returns the tales environment used to evaluate the command 1859 """ 1860 environ = Commandable.getUserCommandEnvironment(self) 1861 context = self.primaryAq() 1862 environ.update({'dev': context, 'device': context,}) 1863 return environ
1864
1865 - def getUrlForUserCommands(self):
1866 """ 1867 Returns a URL to redirect to after a command has executed 1868 used by Commandable 1869 """ 1870 return self.getPrimaryUrlPath() + '/deviceManagement'
1871
1872 - def getHTMLEventSummary(self, severity=4):
1873 """ 1874 Returns HTML Event Summary of a device 1875 """ 1876 html = [] 1877 html.append("<table width='100%' cellspacing='1' cellpadding='3'>") 1878 html.append("<tr>") 1879 def evsummarycell(ev): 1880 if ev[1]-ev[2]>=0: klass = '%s empty thin' % ev[0] 1881 else: klass = '%s thin' % ev[0] 1882 h = '<th align="center" width="16%%" class="%s">%s/%s</th>' % ( 1883 klass, ev[1], ev[2]) 1884 return h
1885 info = self.getEventSummary(severity) 1886 html += map(evsummarycell, info) 1887 html.append('</tr></table>') 1888 return '\n'.join(html)
1889
1890 - def getDataForJSON(self, minSeverity=0):
1891 """ 1892 Returns data ready for serialization 1893 """ 1894 url, classurl = map(urlquote, 1895 (self.getDeviceUrl(), self.getDeviceClassPath())) 1896 id = '<a class="tablevalues" href="%s">%s</a>' % ( 1897 url, self.getId()) 1898 ip = self.getDeviceIp() 1899 if self.checkRemotePerm(ZEN_VIEW, self.deviceClass()): 1900 path = '<a href="/zport/dmd/Devices%s">%s</a>' % (classurl,classurl) 1901 else: 1902 path = classurl 1903 prod = self.getProdState() 1904 zem = self.dmd.ZenEventManager 1905 evsum = getEventPillME(zem, self, 1, minSeverity)[0] 1906 return [id, ip, path, prod, evsum, self.getId()]
1907
1908 - def exportXmlHook(self, ofile, ignorerels):
1909 """ 1910 Add export of our child objects. 1911 """ 1912 map(lambda o: o.exportXml(ofile, ignorerels), (self.hw, self.os))
1913
1914 - def zenPropertyOptions(self, propname):
1915 """ 1916 Returns a list of possible options for a given zProperty 1917 """ 1918 if propname == 'zCollectorPlugins': 1919 from Products.DataCollector.Plugins import loadPlugins 1920 names = [ldr.pluginName for ldr in loadPlugins(self.dmd)] 1921 names.sort() 1922 return names 1923 if propname == 'zCommandProtocol': 1924 return ['ssh', 'telnet'] 1925 if propname == 'zSnmpVer': 1926 return ['v1', 'v2c', 'v3'] 1927 if propname == 'zSnmpAuthType': 1928 return ['', 'MD5', 'SHA'] 1929 if propname == 'zSnmpPrivType': 1930 return ['', 'DES', 'AES'] 1931 return ManagedEntity.zenPropertyOptions(self, propname)
1932 1933 security.declareProtected(ZEN_MANAGE_DEVICE, 'pushConfig')
1934 - def pushConfig(self, REQUEST=None):
1935 """ 1936 This will result in a push of all the devices to live collectors 1937 1938 @permission: ZEN_MANAGE_DEVICE 1939 """ 1940 self._p_changed = True 1941 if REQUEST: 1942 messaging.IMessageSender(self).sendToBrowser( 1943 'Changes Pushed', 1944 'Changes to %s pushed to collectors.' % self.id 1945 ) 1946 return self.callZenScreen(REQUEST)
1947 1948 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'bindTemplates')
1949 - def bindTemplates(self, ids=(), REQUEST=None):
1950 """ 1951 This will bind available templates to the zDeviceTemplates 1952 1953 @permission: ZEN_EDIT_LOCAL_TEMPLATES 1954 """ 1955 return self.setZenProperty('zDeviceTemplates', ids, REQUEST)
1956 1957 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'removeZDeviceTemplates')
1958 - def removeZDeviceTemplates(self, REQUEST=None):
1959 """ 1960 Deletes the local zProperty, zDeviceTemplates 1961 1962 @permission: ZEN_EDIT_LOCAL_TEMPLATES 1963 """ 1964 for id in self.zDeviceTemplates: 1965 self.removeLocalRRDTemplate(id) 1966 return self.deleteZenProperty('zDeviceTemplates', REQUEST)
1967 1968 security.declareProtected(ZEN_EDIT_LOCAL_TEMPLATES, 'addLocalTemplate')
1969 - def addLocalTemplate(self, id, REQUEST=None):
1970 """ 1971 Create a local template on a device 1972 1973 @permission: ZEN_EDIT_LOCAL_TEMPLATES 1974 """ 1975 from Products.ZenModel.RRDTemplate import manage_addRRDTemplate 1976 manage_addRRDTemplate(self, id) 1977 if id not in self.zDeviceTemplates: 1978 self.bindTemplates(self.zDeviceTemplates+[id]) 1979 if REQUEST: 1980 messaging.IMessageSender(self).sendToBrowser( 1981 'Local Template Added', 1982 'Added template %s to %s.' % (id, self.id) 1983 ) 1984 return self.callZenScreen(REQUEST)
1985
1986 - def getAvailableTemplates(self):
1987 """ 1988 Returns all available templates for this device 1989 """ 1990 # All templates defined on this device are available 1991 templates = self.objectValues('RRDTemplate') 1992 # Any templates available to the class that aren't overridden locally 1993 # are also available 1994 templates += [t for t in self.deviceClass().getRRDTemplates() 1995 if t.id not in [r.id for r in templates]] 1996 def cmpTemplates(a, b): 1997 return cmp(a.id.lower(), b.id.lower())
1998 templates.sort(cmpTemplates) 1999 return [ t for t in templates 2000 if isinstance(self, t.getTargetPythonClass()) ] 2001 2002 2003 security.declareProtected(ZEN_VIEW, 'getLinks') 2018 2019 security.declareProtected(ZEN_VIEW, 'getXMLEdges')
2020 - def getXMLEdges(self, depth=3, filter="/", start=()):
2021 """ 2022 Gets XML 2023 """ 2024 if not start: start=self.id 2025 edges = NetworkTree.get_edges(self, depth, 2026 withIcons=True, filter=filter) 2027 return edgesToXML(edges, start)
2028 2029 security.declareProtected(ZEN_VIEW, 'getPrettyLink') 2049 2050
2051 - def updateProcesses(self, relmaps):
2052 "Uses ProcessClasses to create processes to monitor" 2053 2054 from Products.DataCollector.ApplyDataMap import ApplyDataMap 2055 2056 processes = self.getDmdRoot("Processes") 2057 pcs = list(processes.getSubOSProcessClassesGen()) 2058 log.debug("zenoss processes: %s" % pcs) 2059 pcs.sort(lambda a, b: cmp(a.sequence,b.sequence)) 2060 2061 #some debug output 2062 procs = Set() 2063 if log.isEnabledFor(10): 2064 log.debug("=== snmp process information received ===") 2065 for p in scanResults: 2066 log.debug("process: %s" % p) 2067 log.debug("=== processes stored/defined in Zenoss ===") 2068 for p in pcs: 2069 log.debug("%s\t%s" % (p.id, p.regex)) 2070 2071 procs = Set() 2072 2073 #get the processes defined in Zenoss 2074 processes = self.getDmdRoot("Processes") 2075 pcs = list(processes.getSubOSProcessClassesGen()) 2076 log.debug("zenoss processes: %s" % pcs) 2077 pcs.sort(lambda a, b: cmp(a.sequence,b.sequence)) 2078 2079 #some debug output 2080 if log.isEnabledFor(10): 2081 log.debug("=== snmp process information received ===") 2082 for p in scanResults: 2083 log.debug("process: %s" % p) 2084 2085 log.debug("=== processes stored/defined in Zenoss ===") 2086 for p in pcs: 2087 log.debug("%s\t%s" % (p.id, p.regex)) 2088 2089 maps = [] 2090 for om in relmap.maps: 2091 om = ObjectMap(proc) 2092 fullname = (om.procName + " " + om.parameters).rstrip() 2093 log.debug("current process: %s" % fullname) 2094 2095 for pc in pcs: 2096 if pc.match(fullname): 2097 om.setOSProcessClass = pc.getPrimaryDmdId() 2098 id = om.procName 2099 parameters = om.parameters.strip() 2100 if parameters and not pc.ignoreParameters: 2101 parameters = md5.md5(parameters).hexdigest() 2102 id += ' ' + parameters 2103 om.id = self.prepId(id) 2104 if id not in procs: 2105 procs.add(id) 2106 log.debug("adding %s" % fullname) 2107 maps.append(om) 2108 break 2109 relmap.maps = maps 2110 2111 adm = ApplyDataMap() 2112 return adm._applyDataMap(self, relmap)
2113 2114 InitializeClass(Device) 2115