Package Products :: Package DataCollector :: Module PortscanClient |
[hide private]
[frames] | no frames]

# Source Code for Module Products.DataCollector.PortscanClient

      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 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  __doc__ = """PortscanClient
     15  Performance collector of port-scanning
     16  """
     17
     18  import logging
     19
     20  from twisted.internet import reactor
     21  from twisted.python import failure
     22
     23  import Globals
     24
     25  from Products.ZenUtils import PortScan
     26
     27  log = logging.getLogger("zen.PortscanClient")
     28
     29  from BaseClient import BaseClient
     30
     31 -class PortscanClient(BaseClient):
     32      """
     33      Implement the DataCollector Client interface for port-scanning
     34      """
     35
     36 -    def __init__(self, hostname, ipaddr, options=None, device=None,
     37                   datacollector=None, plugins=[]):
     38          """
     39          Initializer
     40
     41          @param hostname: name of the remote device
     42          @type hostname: string
     43          @param ipaddr: IP address of the remote device
     44          @type ipaddr: string
     45          @param options: optparse options
     46          @type options: optparse options object
     47          @param device: DMD device object
     48          @type device: device object
     49          @param datacollector: performance data collector object
     50          @type datacollector: datacollector object
     51          @param plugins: performance data collector plugin
     52          @type plugins: list of plugin objects
     53          """
     54          BaseClient.__init__(self, device, datacollector)
     55          self.hostname = hostname
     56          self.options = options
     57          self.plugins = plugins
     58          self.results = []
     59
     60          maxPort = getattr(device,'zIpServiceMapMaxPort', 1024)
     61          self.portRange = (1, maxPort)
     62
     63          #self.portList = getattr(device,'zPortscanPortList', [])
     64          self.portList = []
     65
     66          if self.portList:
     67              kwds = {'portList': self.portList}
     68          else:
     69              kwds = {'portRange': self.portRange}
     70          kwds.update(dict(timeout=self.options.portscantimeout))
     71          self.scanner = PortScan.Scanner(ipaddr, **kwds)
     72
     73
     74 -    def run(self):
     75          """
     76          Start portscan collection.
     77          """
     78          for plugin in self.plugins:
     79              log.debug("Sending queries for plugin %s", plugin.name())
     80              d = self.scanner.prepare()
     81              d.addCallback(self._cbScanComplete, plugin)
     82              d.addErrback(self._ebScanError, plugin)
     83
     84
     85 -    def _cbScanComplete(self, unused, plugin):
     86          """
     87          Start portscan collection.
     88
     89          @param unused: unused (unused)
     90          @type unused: object
     91          @param plugin: performance data collector plugin
     92          @type plugin: plugin object
     93          """
     94          log.debug("Received plugin:%s getOids", plugin.name())
     95          self.clientFinished(plugin)
     96
     97
     98 -    def _ebScanError( self, err, plugin):
     99          """
    100          Handle an error generated by one of our requests.
    101
    102          @param err: result from the collection run
    103          @type err: result or Exception
    104          @param plugin: performance data collector plugin
    105          @type plugin: plugin object
    106          """
    107          self.clientFinished(plugin)
    108          log.debug('Device %s plugin %s %s', self.hostname, plugin.name(), err)
    109          if isinstance(err, failure.Failure):
    110              trace = err.getTraceback()
    111          else:
    112              trace = log.getException(err)
    113          log.error(
    114              """Device %s plugin %s received an unexpected error: %s""",
    115              self.hostname, plugin.name(), trace,
    116          )
    117
    118
    119 -    def getResults(self):
    120          """
    121          ZenUtils.PortScan records open ports in a list that are the
    122          values for a key in a dict where the key is the IP address
    123          scanned.
    124
    125          For example, if we scan host 10.0.4.55 and ports 22 and 80 are
    126          open, getSuccesses() will return the following:
    127
    128              {'10.0.4.55': [22, 80]}
    129
    130          @return: results
    131          @rtype: list of strings
    132          """
    133          return self.results
    134
    135
    136 -    def clientFinished(self, plugin):
    137          """
    138          Tell the datacollector that we are all done.
    139
    140          @param plugin: performance data collector plugin
    141          @type plugin: plugin object
    142          """
    143          log.info("portscan client finished collection for %s" % self.hostname)
    144          # ApplyDataMap.processClient() expect an iterable with two
    145          # elements: the plugin name and the results, so we set this
    146          # here.
    147          self.results.append((plugin, self.scanner.getSuccesses()))
    148          if self.datacollector:
    149              self.datacollector.clientFinished(self)
    150          else:
    151              reactor.stop()
    152
    153
    154 -def buildOptions(parser=None, usage=None):
    155      """
    156      Create the command-line options list
    157      """
    158
    159      if not usage:
    160          usage = "%prog [options] hostname[:port] oids"
    161
    162      if not parser:
    163          from optparse import OptionParser
    164          parser = OptionParser(usage=usage)
    165      # XXX this function may need options later, so we'll keep this here
    166      # as a reminder for now
    167      #parser.add_option('--snmpCommunity',
    168      #            dest='snmpCommunity',
    169      #            default=defaultSnmpCommunity,
    170      #            help='Snmp Community string')
    171
    172
    173  if __name__ == "__main__":
    174      import sys
    175      sys.path.extend([
    176          '/usr/local/zenoss/Products/DataCollector/plugins',
    177      ])
    178      import pprint
    179      from zenoss.portscan import IpServiceMap
    180
    181      logging.basicConfig()
    182      log = logging.getLogger()
    183      log.setLevel(20)
    184      ipmap = IpServiceMap.IpServiceMap()
    185      psc = PortscanClient("localhost", '127.0.0.1', plugins=[ipmap,])
    186      psc.run()
    187      reactor.run()
    188      pprint.pprint(psc.getResults())
    189