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 as published by 
  8  # 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.IMessagSeender(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 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 else: 175 errorLog( 176 'Test Failed', 177 'Unable to test %s datasources' % self.sourcetype, 178 priority=messaging.WARNING 179 ) 180 return self.callZenScreen(REQUEST) 181 if not command: 182 errorLog( 183 'Test Failed', 184 'Unable to create test command.', 185 priority=messaging.WARNING 186 ) 187 return self.callZenScreen(REQUEST) 188 header = '' 189 footer = '' 190 # Render 191 if REQUEST.get('renderTemplate', True): 192 header, footer = self.commandTestOutput().split('OUTPUT_TOKEN') 193 194 out.write(str(header)) 195 196 write("Executing command\n%s\n against %s" % (command, device.id)) 197 write('') 198 start = time.time() 199 try: 200 executeStreamCommand(command, write) 201 except: 202 import sys 203 write('exception while executing command') 204 write('type: %s value: %s' % tuple(sys.exc_info()[:2])) 205 write('') 206 write('') 207 write('DONE in %s seconds' % long(time.time() - start)) 208 out.write(str(footer))
209 210 security.declareProtected('Change Device', 'manage_testDataSource')
211 - def manage_testDataSource(self, testDevice, REQUEST):
212 ''' Test the datasource by executing the command and outputting the 213 non-quiet results. 214 ''' 215 # set up the output method for our test 216 out = REQUEST.RESPONSE 217 def write(lines): 218 ''' Output (maybe partial) result text. 219 ''' 220 # Looks like firefox renders progressive output more smoothly 221 # if each line is stuck into a table row. 222 startLine = '<tr><td class="tablevalues">' 223 endLine = '</td></tr>\n' 224 if out: 225 if not isinstance(lines, list): 226 lines = [lines] 227 for l in lines: 228 if not isinstance(l, str): 229 l = str(l) 230 l = l.strip() 231 l = cgi.escape(l) 232 l = l.replace('\n', endLine + startLine) 233 out.write(startLine + l + endLine)
234 235 # use our input and output to call the testDataSource Method 236 errorLog = messaging.IMessageSender(self).sendToBrowser 237 return self.testDataSourceAgainstDevice(testDevice, 238 REQUEST, 239 write, 240 errorLog)
241
242 - def parsers(self):
243 from Products.DataCollector.Plugins import loadParserPlugins 244 return sorted([p.modPath for p in loadParserPlugins(self.getDmd())])
245 246 247 248 InitializeClass(BasicDataSource) 249