Package Products :: Package ZenModel :: Module BasicDataSource
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.BasicDataSource

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, 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   
 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   
32 -def checkOid(oid):
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
44 -class BasicDataSource(RRDDataSource.SimpleRRDDataSource):
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 # Screen action bindings (and tab definitions) 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
83 - def addDataPoints(self):
84 """ 85 Overrides method defined in SimpleRRDDataSource. Only sync the 86 datapoint with the datasource if the datasource type is SNMP. 87 """ 88 if self.sourcetype == 'SNMP': 89 RRDDataSource.SimpleRRDDataSource.addDataPoints(self)
90
91 - def getDescription(self):
92 if self.sourcetype == "SNMP": 93 return self.oid 94 if self.sourcetype == "COMMAND": 95 if self.usessh: 96 return self.commandTemplate + " over SSH" 97 else: 98 return self.commandTemplate 99 return RRDDataSource.RRDDataSource.getDescription(self)
100 101
102 - def useZenCommand(self):
103 if self.sourcetype == 'COMMAND': 104 return True 105 return False
106 107
108 - def zmanage_editProperties(self, REQUEST=None):
109 'add some validation' 110 if REQUEST: 111 oid = REQUEST.get('oid', '') 112 if oid: 113 try: 114 REQUEST.form['oid'] = checkOid(oid) 115 except ValueError: 116 messaging.IMessageSender(self).sendToBrowser( 117 'Invalid OID', 118 "%s is an invalid OID." % oid, 119 priority=messaging.WARNING 120 ) 121 return self.callZenScreen(REQUEST) 122 123 return RRDDataSource.SimpleRRDDataSource.zmanage_editProperties( 124 self, REQUEST)
125
126 - def testDataSourceAgainstDevice(self, testDevice, REQUEST, write, errorLog):
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 # Determine which device to execute against 136 device = None 137 if testDevice: 138 # Try to get specified device 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 # ds defined on a device, use that device 149 device = self.device() 150 elif hasattr(self, 'getSubDevicesGen'): 151 # ds defined on a device class, use any device from the class 152 try: 153 device = self.getSubDevicesGen().next() 154 except StopIteration: 155 # No devices in this class, bail out 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 # Get the command to run 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 # use the oid from the request or our existing one 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 # Render 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')
215 - def manage_testDataSource(self, testDevice, REQUEST):
216 ''' Test the datasource by executing the command and outputting the 217 non-quiet results. 218 ''' 219 # set up the output method for our test 220 out = REQUEST.RESPONSE 221 def write(lines): 222 ''' Output (maybe partial) result text. 223 ''' 224 # Looks like firefox renders progressive output more smoothly 225 # if each line is stuck into a table row. 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 # use our input and output to call the testDataSource Method 240 errorLog = messaging.IMessageSender(self).sendToBrowser 241 return self.testDataSourceAgainstDevice(testDevice, 242 REQUEST, 243 write, 244 errorLog)
245
246 - def parsers(self):
247 from Products.DataCollector.Plugins import loadParserPlugins 248 return sorted(p.modPath for p in loadParserPlugins(self.getDmd()))
249 250 251 252 InitializeClass(BasicDataSource) 253