Package Products :: Package ZenStatus :: Package ping :: Module CmdPingTask
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenStatus.ping.CmdPingTask

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2011, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  __doc__ = """CmdPingTask 
 12   
 13  Determines the availability of a IP addresses using command line ping. 
 14   
 15  """ 
 16   
 17  import logging 
 18  log = logging.getLogger("zen.zenping.cmdping") 
 19   
 20  from twisted.python.failure import Failure 
 21  from twisted.internet import defer, utils 
 22  import time 
 23   
 24  import Globals 
 25  from zope import interface 
 26  from zope import component 
 27   
 28  from zenoss.protocols.protobufs.zep_pb2 import SEVERITY_CLEAR 
 29   
 30  from Products.ZenCollector import interfaces  
 31  from Products.ZenCollector.tasks import TaskStates, BaseTask 
 32   
 33  from Products.ZenUtils.Utils import unused 
 34  from Products.ZenCollector.services.config import DeviceProxy 
 35  unused(DeviceProxy) 
 36   
 37  from Products.ZenEvents.ZenEventClasses import Status_Ping 
 38  from Products.ZenEvents import Event 
 39  from Products import ZenStatus 
 40   
 41  from PingResult import PingResult 
 42  _PING = None 
 43  _PING6 = None 
 44  _PING_ARG_TEMPLATE = None 
 45  _OK = 0 
46 47 -def _detectPing():
48 import subprocess 49 global _PING, _PING6, _PING_ARG_TEMPLATE 50 try: 51 _PING = subprocess.check_output(['which', 'ping']).strip() 52 except subprocess.CalledProcessError: 53 log.error('no command line ping detected') 54 import sys 55 sys.exit(1) 56 try: 57 _PING6 = subprocess.check_output(['which', 'ping6']).strip() 58 except subprocess.CalledProcessError: 59 log.info('ping6 not found in path') 60 61 _PING_ARG_TEMPLATE = '%(ping)s -n -c 1 -t %(ttl)d -w %(timeout)f %(ip)s' 62 import platform 63 system = platform.system() 64 if system in ('Mac OS X', 'Darwin'): 65 log.info('Mac OS X detected; adjusting ping args.') 66 _PING_ARG_TEMPLATE = '%(ping)s -n -c 1 -m %(ttl)d -t %(timeout)f %(ip)s' 67 elif system != 'Linux': 68 log.info('CmdPing has not been tested on %r; assuming that Linux ping args work.')
69 70 _detectPing()
71 72 -def _getPingCmd(version=6, **kwargs):
73 args = kwargs.copy() 74 if version == 6: 75 args['ping'] = _PING6 76 else: 77 args['ping'] = _PING 78 79 cmd_str = _PING_ARG_TEMPLATE % args 80 cmd_list = cmd_str.split(' ') 81 return (cmd_list[0], cmd_list[1:])
82
83 84 -class CmdPingCollectionPreferences(ZenStatus.PingCollectionPreferences):
85 """ 86 This required to be a ping backend; use default implementation. 87 """ 88 pass
89
90 -class CmdPingTaskFactory(object):
91 """ 92 A Factory to create command line PingTasks. 93 """ 94 interface.implements(ZenStatus.interfaces.IPingTaskFactory) 95
96 - def __init__(self):
97 self.reset()
98
99 - def build(self):
100 task = CmdPingTask( 101 self.name, 102 self.configId, 103 self.interval, 104 self.config, 105 ) 106 return task
107
108 - def reset(self):
109 self.name = None 110 self.configId = None 111 self.interval = None 112 self.config = None
113
114 -class CmdPingTask(ZenStatus.PingTask):
115 interface.implements(ZenStatus.interfaces.IPingTask) 116
117 - def doTask(self):
118 """ 119 Contact to one device and return a deferred which gathers data from 120 the device. 121 122 @return: A task to ping the device and any of its interfaces. 123 @rtype: Twisted deferred object 124 """ 125 self.resetPingResult() 126 return self._pingIp()
127 128 @defer.inlineCallbacks
129 - def _pingIp(self):
130 131 maxTries = self.config.tries 132 attempts = 0 133 exitCode = -1 134 timestamp = None 135 while attempts < maxTries: 136 attempts += 1 137 cmd, args = _getPingCmd(ip=self.config.ip, version=self.config.ipVersion, ttl=64, timeout=1.5) 138 log.debug("%s %s", cmd, " ".join(args)) 139 timestamp = time.time() 140 out, err, exitCode = yield utils.getProcessOutputAndValue(cmd, args) 141 pingResult = PingResult(self.config.ip, exitCode, out, timestamp) 142 self.logPingResult(pingResult) 143 if not self.config.points and exitCode == 0: 144 # if there are no datapoints to store 145 # and there is at least 1 ping up, then go on 146 break 147 148 if self.isUp: 149 log.debug("%s is up!", self.config.ip) 150 self.sendPingUp() 151 else: 152 log.debug("%s is down", self.config.ip) 153 self.sendPingDown() 154 self.storeResults()
155