Package Products :: Package ZenWin :: Module WMIClient |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenWin.WMIClient

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, 2008 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 or (at your
      8  # option) any later version as published by the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13
     14  from pysamba.twisted.callback import WMIFailure
     15  from pysamba.twisted.reactor import eventContext
     16  from pysamba.wbem.Query import Query
     17
     18  from Products.ZenUtils.Utils import zenPath
     19  from Products.ZenUtils.Driver import drive
     20  from Products.DataCollector.BaseClient import BaseClient
     21
     22  from twisted.internet import defer
     23
     24  import os
     25  import socket
     26  import sys
     27  import logging
     28  log = logging.getLogger("zen.WMIClient")
     29
     30
     31  BaseName = os.path.basename(sys.argv[0])
     32  MyName = None
     33
     34 -def _myname():
     35      global MyName
     36      if not MyName:
     37          MyName = BaseName.split('.')[0]
     38          try:
     39              os.mkdir(zenPath('var', _myname()))
     40          except os.error:
     41              pass
     42      return MyName
     43
     44 -def _filename(device):
     45      return zenPath('var', _myname(), device)
     46
     47 -class BadCredentials(Exception): pass
     48
     49 -class WMIClient(BaseClient):
     50
     51 -    def __init__(self, device, datacollector=None, plugins=[]):
     52          BaseClient.__init__(self, device, datacollector)
     53          self.device = device
     54          self.host = device.id
     55          self._wmi = None
     56          if socket.getfqdn().lower() == device.id.lower():
     57              self.host = "."
     58              device.zWinUser = device.zWinPassword = ""
     59          elif device.manageIp is not None:
     60              self.host = device.manageIp
     61          self.name = device.id
     62          self.user = device.zWinUser
     63          self.passwd = device.zWinPassword
     64          self.datacollector = datacollector
     65          self.plugins = plugins
     66          self.results = []
     67
     68
     69 -    def connect(self):
     70          log.debug("connect to %s, user %r", self.host, self.user)
     71          if not self.user:
     72              log.warning("Windows login name is unset: "
     73                          "please specify zWinUser and "
     74                          "zWinPassword zProperties before adding devices.")
     75              raise BadCredentials("Username is empty")
     76          self._wmi = Query()
     77          creds = '%s%%%s' % (self.user, self.passwd)
     78          return self._wmi.connect(eventContext, self.device.id, self.host, creds)
     79
     80
     81 -    def close(self):
     82          if self._wmi:
     83              self._wmi.close()
     84
     85
     86 -    def query(self, queries):
     87          def inner(driver):
     88              try:
     89                  queryResult = {}
     90                  for tableName, query in queries.items():
     91                      query = query.replace ("\\", "\\\\")
     92                      yield self._wmi.query(query)
     93                      result = driver.next()
     94                      queryResult[tableName] = []
     95                      while 1:
     96                          more = None
     97                          yield result.fetchSome()
     98                          try:
     99                              more = driver.next()
    100                          except WMIFailure, ex:
    101                              msg = 'Received %s from query: %s'
    102
    103                              # Look for specific errors that should be equated
    104                              # to an empty result set.
    105                              if str(ex) in (
    106                                  "NT code 0x80041010",
    107                                  "WBEM_E_INVALID_CLASS",
    108                                  ):
    109                                  log.debug(msg % (ex, query))
    110                              else:
    111                                  log.error(msg % (ex, query))
    112                                  raise
    113                          if not more:
    114                              break
    115                          queryResult[tableName].extend(more)
    116                  yield defer.succeed(queryResult)
    117                  driver.next()
    118              except Exception, ex:
    119                  log.debug("Exception collecting query: %s", str(ex))
    120                  raise
    121          return drive(inner)
    122
    123 -    def run(self):
    124          def inner(driver):
    125              try:
    126                  yield self.connect()
    127                  driver.next()
    128                  for plugin in self.plugins:
    129                      pluginName = plugin.name()
    130                      log.debug("Sending queries for plugin: %s", pluginName)
    131                      log.debug("Queries: %s" % str(plugin.queries().values()))
    132                      try:
    133                          yield self.query(plugin.queries())
    134                          self.results.append((plugin, driver.next()))
    135                      except Exception, ex:
    136                          self.results.append((plugin, ex))
    137                  self.close()
    138              except Exception, ex:
    139                  log.warn("Unable to collect WMI data from %s: %s",
    140                           self.device.id, ex)
    141                  self.close()
    142                  raise
    143          d = drive(inner)
    144          def finish(result):
    145              if self.datacollector:
    146                  self.datacollector.clientFinished(self)
    147          d.addBoth(finish)
    148          return d
    149
    150
    151 -    def getResults(self):
    152          """Return data for this client
    153          """
    154          return self.results
    155