1
2
3
4
5
6
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
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()
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
85 """
86 This required to be a ping backend; use default implementation.
87 """
88 pass
89
91 """
92 A Factory to create command line PingTasks.
93 """
94 interface.implements(ZenStatus.interfaces.IPingTaskFactory)
95
98
100 task = CmdPingTask(
101 self.name,
102 self.configId,
103 self.interval,
104 self.config,
105 )
106 return task
107
109 self.name = None
110 self.configId = None
111 self.interval = None
112 self.config = None
113
115 interface.implements(ZenStatus.interfaces.IPingTask)
116
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
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
145
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