| Trees | Indices | Help |
|
|---|
|
|
1 ##############################################################################
2 #
3 # Copyright (C) Zenoss, Inc. 2007, 2009, 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__ = """ZenTcpClient
12 Connect to the remote service and (optionally) test the output from
13 the service against what we expect.
14
15 Error types:
16
17 1. timeout (no connection)
18 2. connection refused - port not available on remote end
19 3. bad value - value returned did not match expectRegex
20
21 """
22 import re
23 import logging
24 log = logging.getLogger("zen.ZenTcpClient")
25 from socket import getfqdn
26 hostname = getfqdn()
27
28 from twisted.internet import reactor, protocol, defer
29 from Products.ZenEvents.ZenEventClasses import Status_IpService
30 from Products.ZenUtils.Utils import unused
31
33 """
34 Twisted class to make a TCP/IP connection to a remote IP service
35 and report back the result.
36 """
37 defer = None
38 data = ""
39
41 """
42 Connected successfully to the remote device, now test against any
43 regex that we might have and record the result.
44 """
45 log.debug("Connected to %s" % self.transport.getPeer().host)
46 self.factory.msg = "pass"
47 self.cfg = self.factory.cfg
48
49 if self.cfg.sendString:
50 sendString = self.cfg.sendString.decode("string_escape")
51 log.debug("Sending: %s", sendString)
52 self.transport.write(sendString)
53
54 if self.cfg.expectRegex:
55 log.debug("Waiting for results to check against regex '%s'",
56 self.cfg.expectRegex)
57 self.defer = reactor.callLater(self.cfg.timeout, self.expectTimeout)
58 else:
59 self.loseConnection()
60
62 """
63 Compare the data from the remote device to what we expect in the
64 regex.
65
66 @parameter data: output from remote service
67 @type data: string
68 """
69 log.debug("%s %s received data: %s", self.cfg.device,
70 self.cfg.component, data)
71 self.data += data
72 if self.cfg.expectRegex:
73 if re.search(self.cfg.expectRegex, data):
74 log.debug("Found %s in '%s' -- closing connection",
75 self.cfg.expectRegex, data)
76 self.loseConnection()
77 else:
78 log.debug("No match for %s in '%s' -- looking for more data",
79 self.cfg.expectRegex, data)
80
82 """
83 Called if we timeout waiting for the service to connect or for
84 receiving a response from the service that matches our regex.
85 """
86 msg = "IP Service %s TIMEOUT waiting for '%s'" % (
87 self.cfg.component, self.cfg.expectRegex)
88 log.debug("%s %s", self.cfg.ip, msg)
89 self.factory.msg = msg
90 self.loseConnection()
91
93 """
94 Shut down the connection and cleanup.
95 """
96 ip, port = self.transport.addr
97 log.debug("Closed connection to %s on port %s for %s",
98 ip, port, self.cfg.component)
99 self.data = ""
100 try:
101 self.defer.cancel()
102 except:
103 self.defer = None
104 self.transport.loseConnection()
105
106
108 """
109 Client class to run TCP tests.
110 """
111 protocol = ZenTcpTest
112 msg = "pass"
113 deferred = None
114
118
120 """
121 Record why the connection to the remote device was dropped.
122
123 @parameter connector: Twisted protocol object
124 @type connector: Twisted protocol object
125 @parameter reason: explanation for the connection loss
126 @type reason: Twisted error object
127 """
128 unused(connector)
129 errorMsg = reason.getErrorMessage()
130 if errorMsg != 'Connection was closed cleanly.':
131 log.debug("Lost connection to %s (%s) port %s: %s",
132 self.cfg.device, self.cfg.ip, self.cfg.port,
133 reason.getErrorMessage() )
134 if self.deferred:
135 self.deferred.callback(self)
136 self.deferred = None
137
139 """
140 Record why the connection to the remote device failed.
141
142 @parameter connector: Twisted protocol object
143 @type connector: Twisted protocol object
144 @parameter reason: explanation for the connection loss
145 @type reason: Twisted error object
146 """
147 log.debug("Connection to %s (%s) port %s failed: %s",
148 self.cfg.device, connector.host, self.cfg.port,
149 reason.getErrorMessage() )
150 self.msg = "IP Service %s is down" % self.cfg.component
151 if self.deferred:
152 self.deferred.callback(self)
153 self.deferred = None
154
156 """
157 Called by zenstatus to report status information about a service.
158
159 @return: event of what happened to our service test
160 @rtype: dictionary
161 """
162 if self.msg == "pass" and self.status > 0:
163 self.status = sev = 0
164 self.msg = "IP Service %s back up" % self.cfg.component
165
166 elif self.msg != "pass":
167 self.status += 1
168 sev = self.cfg.failSeverity
169
170 else:
171 # Send an event even though there's no problem and
172 # nothing to clear __internally__ to zenstatus.
173 # The event console might have an event that will
174 # otherwise never be cleared.
175 # Code higher up discards duplicate clears.
176 self.status = sev = 0
177 self.msg = "IP Service %s back up" % self.cfg.component
178
179 return dict(device=self.cfg.device,
180 component=self.cfg.component,
181 ipAddress=self.cfg.ip,
182 summary=self.msg,
183 severity=sev,
184 eventClass=Status_IpService,
185 eventGroup="TCPTest",
186 agent="ZenStatus",
187 manager=hostname)
188
190 """
191 Called by zenstatus to make a connection attempt to the service.
192
193 @return: Twisted deferred
194 @rtype: Twisted deferred
195 """
196 d = self.deferred = defer.Deferred()
197 reactor.connectTCP(ip_address, self.cfg.port, self, self.cfg.timeout)
198 return d
199
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Mon Jul 30 17:11:15 2012 | http://epydoc.sourceforge.net |