1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""BasicDataSource
15
16 Defines attributes for how a datasource will be graphed
17 and builds the nessesary DEF and CDEF statements for it.
18 """
19
20 from Products.ZenModel import RRDDataSource
21 from AccessControl import ClassSecurityInfo, Permissions
22 from Globals import InitializeClass
23 from Products.ZenEvents.ZenEventClasses import Cmd_Fail
24 from Products.ZenUtils.Utils import executeStreamCommand
25 from Products.ZenWidgets import messaging
26 from copy import copy
27 import cgi, time
28
29 snmptemplate = ("snmpwalk -c%(zSnmpCommunity)s "
30 "-%(zSnmpVer)s %(manageIp)s %(oid)s")
31
33 import string
34 for c in string.whitespace:
35 oid = oid.replace(c, '')
36 oid = oid.strip('.')
37 numbers = oid.split('.')
38 map(int, numbers)
39 if len(numbers) < 3:
40 raise ValueError("OID too short")
41 return oid
42
43
45
46 __pychecker__='no-override'
47
48 sourcetypes = ('SNMP', 'COMMAND')
49
50 sourcetype = 'SNMP'
51 eventClass = Cmd_Fail
52 oid = ''
53 parser = "Auto"
54
55 usessh = False
56
57 _properties = RRDDataSource.RRDDataSource._properties + (
58 {'id':'oid', 'type':'string', 'mode':'w'},
59 {'id':'usessh', 'type':'boolean', 'mode':'w'},
60 {'id':'parser', 'type':'string', 'mode':'w'},
61 )
62
63 _relations = RRDDataSource.RRDDataSource._relations + (
64 )
65
66
67 factory_type_information = (
68 {
69 'immediate_view' : 'editBasicDataSource',
70 'actions' :
71 (
72 { 'id' : 'edit'
73 , 'name' : 'Data Source'
74 , 'action' : 'editBasicDataSource'
75 , 'permissions' : ( Permissions.view, )
76 },
77 )
78 },
79 )
80
81 security = ClassSecurityInfo()
82
90
100
101
103 if self.sourcetype == 'COMMAND':
104 return True
105 return False
106
107
125
127 """
128 Does the majority of the logic for testing a datasource against the device
129 @param string testDevice The id of the device we are testing
130 @param Dict REQUEST the browers request
131 @param Function write The output method we are using to stream the result of the command
132 @parma Function errorLog The output method we are using to report errors
133 """
134 out = REQUEST.RESPONSE
135
136 device = None
137 if testDevice:
138
139 device = self.findDevice(testDevice)
140 if not device:
141 errorLog(
142 'No device found',
143 'Cannot find device matching %s.' % testDevice,
144 priority=messaging.WARNING
145 )
146 return self.callZenScreen(REQUEST)
147 elif hasattr(self, 'device'):
148
149 device = self.device()
150 elif hasattr(self, 'getSubDevicesGen'):
151
152 try:
153 device = self.getSubDevicesGen().next()
154 except StopIteration:
155
156 pass
157 if not device:
158 errorLog(
159 'No Testable Device',
160 'Cannot determine a device against which to test.',
161 priority=messaging.WARNING
162 )
163 return self.callZenScreen(REQUEST)
164
165
166 command = None
167 if self.sourcetype=='COMMAND':
168 command = self.getCommand(device, REQUEST.get('commandTemplate'))
169 displayCommand = command
170 if displayCommand and len(displayCommand.split()) > 1:
171 displayCommand = "%s [args omitted]" % displayCommand.split()[0]
172 elif self.sourcetype=='SNMP':
173 snmpinfo = copy(device.getSnmpConnInfo().__dict__)
174
175 snmpinfo['oid'] = REQUEST.get('oid', self.getDescription())
176 command = snmptemplate % snmpinfo
177 displayCommand = command
178 else:
179 errorLog(
180 'Test Failed',
181 'Unable to test %s datasources' % self.sourcetype,
182 priority=messaging.WARNING
183 )
184 return self.callZenScreen(REQUEST)
185 if not command:
186 errorLog(
187 'Test Failed',
188 'Unable to create test command.',
189 priority=messaging.WARNING
190 )
191 return self.callZenScreen(REQUEST)
192 header = ''
193 footer = ''
194
195 if REQUEST.get('renderTemplate', True):
196 header, footer = self.commandTestOutput().split('OUTPUT_TOKEN')
197
198 out.write(str(header))
199
200 write("Executing command\n%s\n against %s" % (displayCommand, device.id))
201 write('')
202 start = time.time()
203 try:
204 executeStreamCommand(command, write)
205 except:
206 import sys
207 write('exception while executing command')
208 write('type: %s value: %s' % tuple(sys.exc_info()[:2]))
209 write('')
210 write('')
211 write('DONE in %s seconds' % long(time.time() - start))
212 out.write(str(footer))
213
214 security.declareProtected('Change Device', 'manage_testDataSource')
216 ''' Test the datasource by executing the command and outputting the
217 non-quiet results.
218 '''
219
220 out = REQUEST.RESPONSE
221 def write(lines):
222 ''' Output (maybe partial) result text.
223 '''
224
225
226 startLine = '<tr><td class="tablevalues">'
227 endLine = '</td></tr>\n'
228 if out:
229 if not isinstance(lines, list):
230 lines = [lines]
231 for l in lines:
232 if not isinstance(l, str):
233 l = str(l)
234 l = l.strip()
235 l = cgi.escape(l)
236 l = l.replace('\n', endLine + startLine)
237 out.write(startLine + l + endLine)
238
239
240 errorLog = messaging.IMessageSender(self).sendToBrowser
241 return self.testDataSourceAgainstDevice(testDevice,
242 REQUEST,
243 write,
244 errorLog)
245
249
250
251
252 InitializeClass(BasicDataSource)
253