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