1
2
3
4
5
6
7
8
9
10
11
12
13 __doc__ = """ZenTcpClient
14 Connect to the remote service and (optionally) test the output from
15 the service against what we expect.
16
17 Error types:
18
19 1. timeout (no connection)
20 2. connection refused - port not available on remote end
21 3. bad value - value returned did not match expectRegex
22
23 """
24 import re
25 import logging
26 log = logging.getLogger("zen.ZenTcpClient")
27 from socket import getfqdn
28 hostname = getfqdn()
29
30 from twisted.internet import reactor, protocol, defer
31 from Products.ZenEvents.ZenEventClasses import Status_IpService
32 from Products.ZenUtils.Utils import unused
33
34
35
36 from Products.ZenHub.services.StatusConfig import ServiceConfig
37 unused(ServiceConfig)
38
40 """
41 Twisted class to make a TCP/IP connection to a remote IP service
42 and report back the result.
43 """
44 defer = None
45 data = ""
46
67
68
70 """
71 Compare the data from the remote device to what we expect in the
72 regex.
73
74 @parameter data: output from remote service
75 @type data: string
76 """
77 log.debug("%s %s received data: %s" % (self.cfg.device,
78 self.cfg.component, data))
79 self.data += data
80 if self.cfg.expectRegex:
81 if re.search(self.cfg.expectRegex, data):
82 log.debug("Found %s in '%s' -- closing connection" % (
83 self.cfg.expectRegex, data))
84 self.loseConnection()
85 else:
86 log.debug("No match for %s in '%s' -- looking for more data" % (
87 self.cfg.expectRegex, data))
88
89
91 """
92 Called if we timeout waiting for the service to connect or for
93 receiving a response from the service that matches our regex.
94 """
95 msg = "IP Service %s TIMEOUT waiting for '%s'" % (
96 self.cfg.component, self.cfg.expectRegex)
97 log.debug( "%s %s" % (self.cfg.ip, msg) )
98 self.factory.msg = msg
99 self.loseConnection()
100
101
115
116
117
119 """
120 Client class to run TCP tests.
121 """
122 protocol = ZenTcpTest
123 msg = "pass"
124 deferred = None
125
129
131 """
132 Record why the connection to the remote device was dropped.
133
134 @parameter connector: Twisted protocol object
135 @type connector: Twisted protocol object
136 @parameter reason: explanation for the connection loss
137 @type reason: Twisted error object
138 """
139 unused(connector)
140 log.debug("Lost connection to %s (%s) port %s : %s" % (
141 self.cfg.device, self.cfg.ip, self.cfg.port,
142 reason.getErrorMessage() ))
143 if self.deferred:
144 self.deferred.callback(self)
145 self.deferred = None
146
147
149 """
150 Record why the connection to the remote device failed.
151
152 @parameter connector: Twisted protocol object
153 @type connector: Twisted protocol object
154 @parameter reason: explanation for the connection loss
155 @type reason: Twisted error object
156 """
157 unused(connector)
158 log.debug("Connection to %s (%s) port %s failed: %s" % (
159 self.cfg.device, self.cfg.ip, self.cfg.port,
160 reason.getErrorMessage() ))
161 log.debug(reason.type)
162 self.msg = "IP Service %s is down" % self.cfg.component
163 if self.deferred:
164 self.deferred.callback(self)
165 self.deferred = None
166
167
169 """
170 Called by zenstatus to report status information about a service.
171
172 @return: event of what happened to our service test
173 @rtype: dictionary
174 """
175 log.debug("status:%s msg:%s", self.status, self.msg)
176 if self.msg == "pass" and self.status > 0:
177 self.status = sev = 0
178 self.msg = "IP Service %s back up" % self.cfg.component
179 log.info(self.msg)
180
181 elif self.msg != "pass":
182 self.status += 1
183 sev = self.cfg.failSeverity
184 log.warn(self.msg)
185
186 else:
187
188
189 return None
190
191 return dict(device=self.cfg.device,
192 component=self.cfg.component,
193 ipAddress=self.cfg.ip,
194 summary=self.msg,
195 severity=sev,
196 eventClass=Status_IpService,
197 eventGroup="TCPTest",
198 agent="ZenStatus",
199 manager=hostname)
200
202 """
203 Called by zenstatus to make a connection attempt to the service.
204
205 @return: Twisted deferred
206 @rtype: Twisted deferred
207 """
208 d = self.deferred = defer.Deferred()
209 reactor.connectTCP(self.cfg.ip, self.cfg.port, self, self.cfg.timeout)
210 return d
211