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

Source Code for Module Products.ZenModel.BasicDataSource

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, 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__="""BasicDataSource 
 12   
 13  Defines attributes for how a datasource will be graphed 
 14  and builds the nessesary DEF and CDEF statements for it. 
 15  """ 
 16   
 17  from Products.ZenModel import RRDDataSource 
 18  from AccessControl import ClassSecurityInfo, Permissions 
 19  from Globals import InitializeClass 
 20  from Products.ZenEvents.ZenEventClasses import Cmd_Fail 
 21  from Products.ZenUtils.Utils import executeStreamCommand 
 22  from Products.ZenWidgets import messaging 
 23  from copy import copy 
 24  import cgi, time 
 25   
 26  snmptemplate = ("snmpwalk -c%(zSnmpCommunity)s " 
 27                  "-%(zSnmpVer)s %(manageIp)s %(oid)s") 
 28   
29 -def checkOid(oid):
30 import string 31 for c in string.whitespace: 32 oid = oid.replace(c, '') 33 oid = oid.strip('.') 34 numbers = oid.split('.') 35 map(int, numbers) 36 if len(numbers) < 3: 37 raise ValueError("OID too short") 38 return oid
39 40
41 -class BasicDataSource(RRDDataSource.SimpleRRDDataSource):
42 43 __pychecker__='no-override' 44 45 sourcetypes = ('SNMP', 'COMMAND') 46 47 sourcetype = 'SNMP' 48 eventClass = Cmd_Fail 49 oid = '' 50 parser = "Auto" 51 52 usessh = False 53 54 _properties = RRDDataSource.RRDDataSource._properties + ( 55 {'id':'oid', 'type':'string', 'mode':'w'}, 56 {'id':'usessh', 'type':'boolean', 'mode':'w'}, 57 {'id':'parser', 'type':'string', 'mode':'w'}, 58 ) 59 60 _relations = RRDDataSource.RRDDataSource._relations + ( 61 ) 62 63 # Screen action bindings (and tab definitions) 64 factory_type_information = ( 65 { 66 'immediate_view' : 'editBasicDataSource', 67 'actions' : 68 ( 69 { 'id' : 'edit' 70 , 'name' : 'Data Source' 71 , 'action' : 'editBasicDataSource' 72 , 'permissions' : ( Permissions.view, ) 73 }, 74 ) 75 }, 76 ) 77 78 security = ClassSecurityInfo() 79
80 - def addDataPoints(self):
81 """ 82 Overrides method defined in SimpleRRDDataSource. Only sync the 83 datapoint with the datasource if the datasource type is SNMP. 84 """ 85 if self.sourcetype == 'SNMP': 86 RRDDataSource.SimpleRRDDataSource.addDataPoints(self)
87
88 - def getDescription(self):
89 if self.sourcetype == "SNMP": 90 return self.oid 91 if self.sourcetype == "COMMAND": 92 if self.usessh: 93 return self.commandTemplate + " over SSH" 94 else: 95 return self.commandTemplate 96 return RRDDataSource.RRDDataSource.getDescription(self)
97 98
99 - def useZenCommand(self):
100 if self.sourcetype == 'COMMAND': 101 return True 102 return False
103 104
105 - def zmanage_editProperties(self, REQUEST=None):
106 'add some validation' 107 if REQUEST: 108 oid = REQUEST.get('oid', '') 109 if oid: 110 try: 111 REQUEST.form['oid'] = checkOid(oid) 112 except ValueError: 113 messaging.IMessageSender(self).sendToBrowser( 114 'Invalid OID', 115 "%s is an invalid OID." % oid, 116 priority=messaging.WARNING 117 ) 118 return self.callZenScreen(REQUEST) 119 120 return RRDDataSource.SimpleRRDDataSource.zmanage_editProperties( 121 self, REQUEST)
122
123 - def testDataSourceAgainstDevice(self, testDevice, REQUEST, write, errorLog):
124 """ 125 Does the majority of the logic for testing a datasource against the device 126 @param string testDevice The id of the device we are testing 127 @param Dict REQUEST the browers request 128 @param Function write The output method we are using to stream the result of the command 129 @parma Function errorLog The output method we are using to report errors 130 """ 131 out = REQUEST.RESPONSE 132 # Determine which device to execute against 133 device = None 134 if testDevice: 135 # Try to get specified device 136 device = self.findDevice(testDevice) 137 if not device: 138 errorLog( 139 'No device found', 140 'Cannot find device matching %s.' % testDevice, 141 priority=messaging.WARNING 142 ) 143 return self.callZenScreen(REQUEST) 144 elif hasattr(self, 'device'): 145 # ds defined on a device, use that device 146 device = self.device() 147 elif hasattr(self, 'getSubDevicesGen'): 148 # ds defined on a device class, use any device from the class 149 try: 150 device = self.getSubDevicesGen().next() 151 except StopIteration: 152 # No devices in this class, bail out 153 pass 154 if not device: 155 errorLog( 156 'No Testable Device', 157 'Cannot determine a device against which to test.', 158 priority=messaging.WARNING 159 ) 160 return self.callZenScreen(REQUEST) 161 162 # Get the command to run 163 command = None 164 if self.sourcetype=='COMMAND': 165 command = self.getCommand(device, REQUEST.get('commandTemplate')) 166 displayCommand = command 167 if displayCommand and len(displayCommand.split()) > 1: 168 displayCommand = "%s [args omitted]" % displayCommand.split()[0] 169 elif self.sourcetype=='SNMP': 170 snmpinfo = copy(device.getSnmpConnInfo().__dict__) 171 # use the oid from the request or our existing one 172 snmpinfo['oid'] = REQUEST.get('oid', self.getDescription()) 173 command = snmptemplate % snmpinfo 174 displayCommand = command 175 else: 176 errorLog( 177 'Test Failed', 178 'Unable to test %s datasources' % self.sourcetype, 179 priority=messaging.WARNING 180 ) 181 return self.callZenScreen(REQUEST) 182 if not command: 183 errorLog( 184 'Test Failed', 185 'Unable to create test command.', 186 priority=messaging.WARNING 187 ) 188 return self.callZenScreen(REQUEST) 189 header = '' 190 footer = '' 191 # Render 192 if REQUEST.get('renderTemplate', True): 193 header, footer = self.commandTestOutput().split('OUTPUT_TOKEN') 194 195 out.write(str(header)) 196 197 write("Executing command\n%s\n against %s" % (displayCommand, device.id)) 198 write('') 199 start = time.time() 200 try: 201 executeStreamCommand(command, write) 202 except: 203 import sys 204 write('exception while executing command') 205 write('type: %s value: %s' % tuple(sys.exc_info()[:2])) 206 write('') 207 write('') 208 write('DONE in %s seconds' % long(time.time() - start)) 209 out.write(str(footer))
210 211 security.declareProtected('Change Device', 'manage_testDataSource')
212 - def manage_testDataSource(self, testDevice, REQUEST):
213 ''' Test the datasource by executing the command and outputting the 214 non-quiet results. 215 ''' 216 # set up the output method for our test 217 out = REQUEST.RESPONSE 218 def write(lines): 219 ''' Output (maybe partial) result text. 220 ''' 221 # Looks like firefox renders progressive output more smoothly 222 # if each line is stuck into a table row. 223 startLine = '<tr><td class="tablevalues">' 224 endLine = '</td></tr>\n' 225 if out: 226 if not isinstance(lines, list): 227 lines = [lines] 228 for l in lines: 229 if not isinstance(l, str): 230 l = str(l) 231 l = l.strip() 232 l = cgi.escape(l) 233 l = l.replace('\n', endLine + startLine) 234 out.write(startLine + l + endLine)
235 236 # use our input and output to call the testDataSource Method 237 errorLog = messaging.IMessageSender(self).sendToBrowser 238 return self.testDataSourceAgainstDevice(testDevice, 239 REQUEST, 240 write, 241 errorLog)
242
243 - def parsers(self):
244 from Products.DataCollector.Plugins import loadParserPlugins 245 return sorted(p.modPath for p in loadParserPlugins(self.getDmd()))
246 247 248 249 InitializeClass(BasicDataSource) 250