| Trees | Indices | Help |
|
|---|
|
|
1 ###########################################################################
2 #
3 # This program is part of Zenoss Core, an open source monitoring platform.
4 # Copyright (C) 2007, 2009 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 __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
35 """
36 Twisted class to make a TCP/IP connection to a remote IP service
37 and report back the result.
38 """
39 defer = None
40 data = ""
41
43 """
44 Connected successfully to the remote device, now test against any
45 regex that we might have and record the result.
46 """
47 log.debug("Connected to %s" % self.transport.getPeer().host)
48 self.factory.msg = "pass"
49 self.cfg = self.factory.cfg
50
51 if self.cfg.sendString:
52 sendString = self.cfg.sendString.decode("string_escape")
53 log.debug("Sending: %s", sendString)
54 self.transport.write(sendString)
55
56 if self.cfg.expectRegex:
57 log.debug("Waiting for results to check against regex '%s'",
58 self.cfg.expectRegex)
59 self.defer = reactor.callLater(self.cfg.timeout, self.expectTimeout)
60 else:
61 self.loseConnection()
62
64 """
65 Compare the data from the remote device to what we expect in the
66 regex.
67
68 @parameter data: output from remote service
69 @type data: string
70 """
71 log.debug("%s %s received data: %s", self.cfg.device,
72 self.cfg.component, data)
73 self.data += data
74 if self.cfg.expectRegex:
75 if re.search(self.cfg.expectRegex, data):
76 log.debug("Found %s in '%s' -- closing connection",
77 self.cfg.expectRegex, data)
78 self.loseConnection()
79 else:
80 log.debug("No match for %s in '%s' -- looking for more data",
81 self.cfg.expectRegex, data)
82
84 """
85 Called if we timeout waiting for the service to connect or for
86 receiving a response from the service that matches our regex.
87 """
88 msg = "IP Service %s TIMEOUT waiting for '%s'" % (
89 self.cfg.component, self.cfg.expectRegex)
90 log.debug("%s %s", self.cfg.ip, msg)
91 self.factory.msg = msg
92 self.loseConnection()
93
95 """
96 Shut down the connection and cleanup.
97 """
98 ip, port = self.transport.addr
99 log.debug("Closed connection to %s on port %s for %s",
100 ip, port, self.cfg.component)
101 self.data = ""
102 try:
103 self.defer.cancel()
104 except:
105 self.defer = None
106 self.transport.loseConnection()
107
108
110 """
111 Client class to run TCP tests.
112 """
113 protocol = ZenTcpTest
114 msg = "pass"
115 deferred = None
116
120
122 """
123 Record why the connection to the remote device was dropped.
124
125 @parameter connector: Twisted protocol object
126 @type connector: Twisted protocol object
127 @parameter reason: explanation for the connection loss
128 @type reason: Twisted error object
129 """
130 unused(connector)
131 errorMsg = reason.getErrorMessage()
132 if errorMsg != 'Connection was closed cleanly.':
133 log.debug("Lost connection to %s (%s) port %s: %s",
134 self.cfg.device, self.cfg.ip, self.cfg.port,
135 reason.getErrorMessage() )
136 if self.deferred:
137 self.deferred.callback(self)
138 self.deferred = None
139
141 """
142 Record why the connection to the remote device failed.
143
144 @parameter connector: Twisted protocol object
145 @type connector: Twisted protocol object
146 @parameter reason: explanation for the connection loss
147 @type reason: Twisted error object
148 """
149 log.debug("Connection to %s (%s) port %s failed: %s",
150 self.cfg.device, connector.host, self.cfg.port,
151 reason.getErrorMessage() )
152 self.msg = "IP Service %s is down" % self.cfg.component
153 if self.deferred:
154 self.deferred.callback(self)
155 self.deferred = None
156
158 """
159 Called by zenstatus to report status information about a service.
160
161 @return: event of what happened to our service test
162 @rtype: dictionary
163 """
164 if self.msg == "pass" and self.status > 0:
165 self.status = sev = 0
166 self.msg = "IP Service %s back up" % self.cfg.component
167
168 elif self.msg != "pass":
169 self.status += 1
170 sev = self.cfg.failSeverity
171
172 else:
173 # Send an event even though there's no problem and
174 # nothing to clear __internally__ to zenstatus.
175 # The event console might have an event that will
176 # otherwise never be cleared.
177 # Code higher up discards duplicate clears.
178 self.status = sev = 0
179 self.msg = "IP Service %s back up" % self.cfg.component
180
181 return dict(device=self.cfg.device,
182 component=self.cfg.component,
183 ipAddress=self.cfg.ip,
184 summary=self.msg,
185 severity=sev,
186 eventClass=Status_IpService,
187 eventGroup="TCPTest",
188 agent="ZenStatus",
189 manager=hostname)
190
201
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Tue Oct 11 12:52:00 2011 | http://epydoc.sourceforge.net |