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

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