def controlT(): #global rrdFilesPath ntopSpoolPath = ntop.getSpoolPath() nameFileConfig = 'rrdAlarmConfig.txt' tempFileName = 'rrdAlarmStart.tmp' configuration = None TWODECIMAL = decimal.Decimal(10)**-2 timeStart = time.time() alarmsFired = 0 checkedFiles = 0 fmt = '%a, %d %b %Y %H:%M:%S' #format of the time showed form = cgi.FieldStorage() #get the parameter passed via the url noHTML = bool(form.getvalue('noHTML')) configFile = form.getvalue('configFile') if configFile and len(configFile) > 0: nameFileConfig = str(configFile) try: tempFile = open(os.path.join(ntopSpoolPath, tempFileName), 'r') configuration = pickle.load(tempFile) tempFile.close() if configuration and ( timeStart < float(configuration['timeStart']) + float(60)): ntop.sendHTTPHeader(1) ntop.printHTMLHeader('RRD Alarm Called too early!', 1, 0) ntop.sendString( "Wait at least a minute. Last Time started: %s" % time.strftime(fmt, time.localtime(configuration['timeStart']))) ntop.printHTMLFooter() return 0 #exit because the script was started less than one minute ago else: configuration['timeStart'] = timeStart except IOError: #the tempFile does not exist or some other problem print >> sys.stderr, 'RRDAlarm: IOError while accessing tempfile ' + tempFileName configuration = createNewConfiguration( rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) except pickle.PickleError, pickle.UnpicklingError: print >> sys.stderr, "RRDAlarm: Problems during the UnPickling load, tempFile Delete..." os.remove(os.path.join(ntopSpoolPath, tempFileName)) return -1
def controlT(): # global rrdFilesPath ntopSpoolPath = ntop.getSpoolPath() nameFileConfig = "rrdAlarmConfig.txt" tempFileName = "rrdAlarmStart.tmp" configuration = None TWODECIMAL = decimal.Decimal(10) ** -2 timeStart = time.time() alarmsFired = 0 checkedFiles = 0 fmt = "%a, %d %b %Y %H:%M:%S" # format of the time showed form = cgi.FieldStorage() # get the parameter passed via the url noHTML = bool(form.getvalue("noHTML")) configFile = form.getvalue("configFile") if configFile and len(configFile) > 0: nameFileConfig = str(configFile) try: tempFile = open(os.path.join(ntopSpoolPath, tempFileName), "r") configuration = pickle.load(tempFile) tempFile.close() if configuration and (timeStart < float(configuration["timeStart"]) + float(60)): ntop.sendHTTPHeader(1) ntop.printHTMLHeader("RRD Alarm Called too early!", 1, 0) ntop.sendString( "Wait at least a minute. Last Time started: %s" % time.strftime(fmt, time.localtime(configuration["timeStart"])) ) ntop.printHTMLFooter() return 0 # exit because the script was started less than one minute ago else: configuration["timeStart"] = timeStart except IOError: # the tempFile does not exist or some other problem print >>sys.stderr, "RRDAlarm: IOError while accessing tempfile " + tempFileName configuration = createNewConfiguration(rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) except pickle.PickleError, pickle.UnpicklingError: print >>sys.stderr, "RRDAlarm: Problems during the UnPickling load, tempFile Delete..." os.remove(os.path.join(ntopSpoolPath, tempFileName)) return -1
def begin(): templateFilename = 'rrdAlarmConfigurator.tmpl' # Imports for mako try: from mako.template import Template from mako.runtime import Context from mako.lookup import TemplateLookup from mako import exceptions except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 0) ntop.sendString( "<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font> (sudo easy_install Mako)</center></b>" ) ntop.printHTMLFooter() return # Fix encoding #reload(sys) #sys.setdefaultencoding("latin1") rows = [] pathRRDFiles = os.path.join(ntop.getDBPath(), 'rrd/') nameFileConfig = 'rrdAlarmConfig.txt' #default nameFileConfig pathTempFile = ntop.getSpoolPath() + os.sep form = cgi.FieldStorage() #get from the url the parameter configfile that contains the #path+filename of the configfile to read jsonPathRRD = form.getvalue('pathRRDS') help = form.getvalue('help') documentRoot = os.getenv('DOCUMENT_ROOT', '.') if jsonPathRRD: #a request from the autocomplete script, return a json string with the matching files names ntop.sendHTTPHeader(1) ntop.sendString(jsonListFileInPath(jsonPathRRD, pathRRDFiles)) return elif help == 'true': #show help page templateFilename = 'rrdAlarmConfiguratorHelp.tmpl' ntop.printHTMLHeader('RRD Alarm Configurator Help', 1, 0) else: #normal operation requestFileConfig = form.getvalue('configFile') if requestFileConfig is not None: nameFileConfig = requestFileConfig #get all the scripts in the scripts directory listScripts = readScriptsDir( os.path.join(documentRoot, 'python/rrdalarm/scripts/')) ntop.printHTMLHeader('RRD Alarm Configurator', 1, 0) file_name = os.path.join(pathTempFile, nameFileConfig) try: configFile = open(file_name, 'rt') for line in configFile: line = line.rstrip() #drop the \n at the end if len(line) > 0 and line[0] != '#': rows.append(line.split('\t')) configFile.close() except IOError: try: open(file_name, 'w').close() # Create an empty file if missing except: pass print >> sys.stderr, "RRDAlarm: empty configFile created " + file_name except: print >> sys.stderr, "RRDAlarm: Error reading configFile " + os.path.join( pathTempFile, nameFileConfig) raise #the elaboration will continue but no data will be displayed. #if requestFileConfig is not None: #if the nameFileConfig was specified by user show error #try: # open(os.path.join(pathTempFile,nameFileConfig), 'w') #except: # raise #else: #nameFileConfig='rrdAlarmConfig.txt' #ntop.sendString(exceptions.html_error_template().render()) try: #pprint.pprint(listAllDirs(pathRRDFiles+'rrd/'), sys.stderr) basedir = os.path.join(documentRoot, 'python/templates') mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template(templateFilename) buf = StringIO() ctx = None if (help == 'true'): #show help page ctx = Context(buf) else: ctx = Context(buf, configRows=rows, tempFilePath=pathTempFile, nameFileConfig=nameFileConfig, listScripts=listScripts, pathRRDFiles=pathRRDFiles ) #, rrdDirs=listAllDirs(pathRRDFiles+'rrd/') myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) ntop.printHTMLFooter()
import host import os, os.path import sys #import pprint import glob exceptions_so_far = 0 try: import json except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1) ntop.sendString( "<b><center><font color=red>Please install JSON support in python</font><p></b><br>E.g. 'sudo apt-get install python-json' (on Debian-like systems)</font></center>" ) ntop.printHTMLFooter() exceptions_so_far = 1 # Import modules for CGI handling import cgi, cgitb from StringIO import StringIO #return a json string of filenames from the path expanded with a *, if the result is just one and is a directory it continues the search inside it def jsonListFileInPath(path, ntopSuffix): jsonList = {'results': []} listFile = glob.glob(os.path.join(ntopSuffix, path) + '*') #expand the * and ? into a list of files i = 1
def begin(): # Imports for mako try: from mako.template import Template from mako.runtime import Context from mako.lookup import TemplateLookup from mako import exceptions except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1) ntop.sendString("<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font><p></b><br>(1) 'sudo yum install python-setuptools' (on RedHat-like systems)<br>(2) 'sudo easy_install Mako'</font></center>") ntop.printHTMLFooter() return # Fix encoding #reload(sys) #sys.setdefaultencoding("latin1") templateFilename='ipPortQuery.tmpl' #fb_DB = '/tmp/' #ntop.getPreference ("fastbitDBPath"); #default location of the fastbit DB databasePath = ntop.getPreference ("fastbit.DBPath"); #default location of the fastbit DB if databasePath is None or databasePath=='': ntop.printHTMLHeader('ntop Fastbit Configuration Error', 1, 1) ntop.sendString("<b><center><font color=red>Please set fastbit.DBPath ntop preferences from <i>Admin/Configure/Preferences</i> menu (es: fastbit.DBPath=/tmp/)</b></font></center>") ntop.printHTMLFooter() return #pathFastBit=os.path.join(databasePath,'fastbit'+os.path.sep) form = cgi.FieldStorage(); #get from the url the parameter configfile that contains the #path+filename of the configfile to read fromAuto=form.getvalue('fromAuto') if fromAuto: #print>>sys.stderr, "AJAX REQUEST FOR PARTITION IN "+databasePath+" "+fromAuto jsonString=expandFrom(fromAuto, os.path.join(databasePath, "") ) ntop.sendHTTPHeader(12) ntop.sendString(jsonString) return documentRoot=os.getenv('DOCUMENT_ROOT', '.') selectArg='PROTOCOL,IPV4_SRC_ADDR,L4_SRC_PORT,IPV4_DST_ADDR,L4_DST_PORT,IN_BYTES,IN_PKTS' fromArg=form.getvalue('partition') ipSrc=form.getvalue('ipSrc') ipDst=form.getvalue('ipDst') portSrc=form.getvalue('portSrc') portDst=form.getvalue('portDst') limit = int(form.getvalue('limit', 100)) if limit<0: limit=0 res=None #variable to store the results of the query ntop.printHTMLHeader('IP-Port Query', 1, 0) #regex to check passed parameters ipV4Type=re.compile(r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)') portType=re.compile(r'\d{1,5}') #pprint.pprint(ipV4Type.match(str(ipSrc)), sys.stderr) formatErrorString='' #without the partition do nothing if fromArg : whereArg='1=1' #to avoid leaving the where clause empty if ipSrc: #print>>sys.stderr, 'ECCO '+str(ipV4Type.match(ipSrc)) if ipV4Type.match(ipSrc): whereArg=whereArg+' AND IPV4_SRC_ADDR='+str(ipToNumber(ipSrc)) else: formatErrorString=formatErrorString+'Source ip format invalid! ipv4 format required. ' if portSrc: if portType.match(portSrc): whereArg=whereArg+' AND L4_SRC_PORT='+str(portSrc) else: formatErrorString=formatErrorString+'Source Port format invalid! Number required. ' if ipDst: if ipV4Type.match(ipDst): whereArg=whereArg+' AND IPV4_DST_ADDR='+str(ipToNumber(ipDst)) else: formatErrorString=formatErrorString+'Destination ip format invalid! ipv4 format required. ' if portDst: if portType.match(portDst): whereArg=whereArg+' AND L4_DST_PORT='+str(portDst) else: formatErrorString=formatErrorString+'Destination Port format invalid! Number required. ' try: #pipe = subprocess.Popen (['ntop.getPreference ("fastbit.fbquery")', "-c", selectArg, "-d", fromArg, "-q", whereArg, "-P", "-L", limit], #print>>sys.stderr, "Query passed: SELECT %s FROM %s WHERE %s LIMIT %i" %(selectArg,os.path.join(databasePath, fromArg), whereArg, limit) if formatErrorString=='': res = fastbit.query(os.path.join(databasePath, fromArg), selectArg, whereArg, limit) else: print>>sys.stderr, 'ipPortQuery: ERROR '+formatErrorString ntop.sendString('<center><font color=red>%s</font></center>'%formatErrorString) #print>>sys.stderr, 'Number of records: %i' % len(res['values']) except: print>>sys.stderr, 'ERROR Executing query: '+("SELECT %s FROM %s WHERE %s LIMIT %i" %(selectArg,os.path.join(databasePath, fromArg), whereArg, limit)) res = {} if res is not None and 'columns' in res and 'values' in res: toFormat=getAddrCols(selectArg) #get a list of addr column numbers for x in res['values']: x[0]=getNameByProto(x[0]) #format protocol number to text for j in toFormat: #for every number in the list format as an IP ADDR ipStr=numberToIp(x[j]) x[j]='<a href="/%s.html" class="tooltip">%s</a>' % (ipStr,ipStr) #format ip number to string ip and create a link to ntop host page '''else: print>>sys.stderr, 'ipPortQuery: ERROR partition required' ntop.sendString('<center><font color=red>Partition field required!</font></center>')''' #pprint.pprint(res, sys.stderr) #if res is not None: # res['columns']=['Protocol', 'IP Source Addr', 'IP Dest. Addr', 'Source Port', 'Dest. Port', 'Bytes Rcvd', 'Packets Rcvd'] try: basedir = os.path.join(documentRoot,'python/templates') mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template(templateFilename) buf = StringIO() ctx = Context(buf, results=res) myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) ntop.printHTMLFooter()
import ntop import fastbit #import pprint # Import modules for CGI handling import cgi, cgitb import socket, struct, sys, glob exceptions_so_far = 0 try: import json except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1) ntop.sendString("<b><center><font color=red>Please install JSON support in python</font><p></b><br>E.g. 'sudo apt-get install python-json' (on Debian-like systems)</font></center>") ntop.printHTMLFooter() exceptions_so_far=1 # Parse URL cgitb.enable(); import re, os, os.path from StringIO import StringIO ''' return a list of directories representing tables for fastbit, as long as the list to be returned is len() ==1 iterate to get more results (if possible) ''' def expandTables(string, pathFastbitDir): directoryList=[]
def begin(): templateFilename='rrdAlarmConfigurator.tmpl' # Imports for mako try: from mako.template import Template from mako.runtime import Context from mako.lookup import TemplateLookup from mako import exceptions except: ntop.printHTMLHeader('ntop Python Configuration Error',1,0) ntop.sendString("<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font> (sudo easy_install Mako)</center></b>") ntop.printHTMLFooter() return # Fix encoding #reload(sys) #sys.setdefaultencoding("latin1") rows=[] pathRRDFiles=os.path.join(ntop.getDBPath(),'rrd/') nameFileConfig='rrdAlarmConfig.txt' #default nameFileConfig pathTempFile=ntop.getSpoolPath()+os.sep form = cgi.FieldStorage(); #get from the url the parameter configfile that contains the #path+filename of the configfile to read jsonPathRRD=form.getvalue('pathRRDS') help=form.getvalue('help') documentRoot=os.getenv('DOCUMENT_ROOT', '.') if jsonPathRRD: #a request from the autocomplete script, return a json string with the matching files names ntop.sendHTTPHeader(1) ntop.sendString(jsonListFileInPath(jsonPathRRD, pathRRDFiles)) return elif help == 'true': #show help page templateFilename='rrdAlarmConfiguratorHelp.tmpl' ntop.printHTMLHeader('RRD Alarm Configurator Help', 1, 0) else: #normal operation requestFileConfig=form.getvalue('configFile') if requestFileConfig is not None: nameFileConfig=requestFileConfig #get all the scripts in the scripts directory listScripts=readScriptsDir(os.path.join(documentRoot,'python/rrdalarm/scripts/')) ntop.printHTMLHeader('RRD Alarm Configurator', 1, 0) file_name = os.path.join(pathTempFile,nameFileConfig) try: configFile= open(file_name, 'rt') for line in configFile: line=line.rstrip() #drop the \n at the end if len(line) >0 and line[0] != '#': rows.append(line.split('\t')) configFile.close() except IOError: try: open(file_name, 'w').close() # Create an empty file if missing except: pass print>>sys.stderr, "RRDAlarm: empty configFile created "+file_name except: print>>sys.stderr, "RRDAlarm: Error reading configFile "+os.path.join(pathTempFile,nameFileConfig) raise #the elaboration will continue but no data will be displayed. #if requestFileConfig is not None: #if the nameFileConfig was specified by user show error #try: # open(os.path.join(pathTempFile,nameFileConfig), 'w') #except: # raise #else: #nameFileConfig='rrdAlarmConfig.txt' #ntop.sendString(exceptions.html_error_template().render()) try: #pprint.pprint(listAllDirs(pathRRDFiles+'rrd/'), sys.stderr) basedir = os.path.join(documentRoot,'python/templates') mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template(templateFilename) buf = StringIO() ctx=None if(help =='true'): #show help page ctx = Context(buf) else: ctx = Context(buf, configRows=rows,tempFilePath=pathTempFile, nameFileConfig=nameFileConfig,listScripts=listScripts, pathRRDFiles=pathRRDFiles) #, rrdDirs=listAllDirs(pathRRDFiles+'rrd/') myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) ntop.printHTMLFooter()
def begin(): historyLimit = 10 templateFilename = 'fastbit.tmpl' # Imports for mako try: from mako.template import Template from mako.runtime import Context from mako.lookup import TemplateLookup from mako import exceptions except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 0) ntop.sendString( "<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font> (sudo easy_install Mako)</center></b>" ) ntop.printHTMLFooter() return # Fix encoding #reload(sys) #sys.setdefaultencoding("latin1") ntopSpoolPath = ntop.getSpoolPath() tempQueryHistory = "fbQueryHistory" rows = [] cols = None databasePath = ntop.getDBPath() '''TODO CHANGE THIS!!! fastbit database location''' fb_DB = '/tmp/' #ntop.getPreference ("fastbitDB"); #default location of the fastbit DB if fb_DB is not None: databasePath = fb_DB pathFastBit = os.path.join(databasePath, 'fastbit' + os.path.sep) form = cgi.FieldStorage() #get from the url the parameter configfile that contains the #path+filename of the configfile to read '''Parameters for calling the autocomplete function''' selectAuto = form.getvalue('selectAuto') fromAuto = form.getvalue('fromAuto') documentRoot = os.getenv('DOCUMENT_ROOT', '.') if selectAuto: print >> sys.stderr, "PARAMETRO SELECT PASSATO " + str(selectAuto) #a request from the autocomplete script, return a json string with the matching files names ntop.sendHTTPHeader(1) ntop.sendString(expandSelect(selectAuto, pathFastBit, fromAuto)) return elif fromAuto: ntop.sendHTTPHeader(1) ntop.sendString(expandFrom(fromAuto, pathFastBit)) return else: history = { 'history': [] } #object containing the last 10 queries successfully executed try: tempFile = open(os.path.join(ntopSpoolPath, tempQueryHistory), 'r') history = pickle.load(tempFile) except IOError: #the tempFile does not exist or some other problem print >> sys.stderr, 'Fastbit query: IOError while accessing queries history ' + tempQueryHistory history = { 'history': [] } #object containing the last 10 queries successfully executed except pickle.PickleError, pickle.UnpicklingError: print >> sys.stderr, "Error while loading the queries history removing file..." + os.path.join( ntopSpoolPath, tempQueryHistory) try: os.remove(os.path.join(ntopSpoolPath, tempQueryHistory)) except: pass raise selectArg = form.getvalue('select') fromArg = form.getvalue('from') whereArg = form.getvalue('where') limit = int(form.getvalue('limit', 100)) carPosition = int( form.getvalue('carPosition', 0) ) #to be used to expand in the middle of a string knowing the cursor position... queryPar = ["", "", "", limit] #show limit 100 as default ntop.printHTMLHeader('Fastbit Query', 1, 0) if selectArg and fromArg: queryPar = [selectArg, fromArg, whereArg, limit] try: #pipe = subprocess.Popen (['ntop.getPreference ("fastbit.fbquery")', "-c", selectArg, "-d", fromArg, "-q", whereArg, "-P", "-L", limit], print >> sys.stderr, "Query passed: SELECT %s FROM %s WHERE %s LIMIT %i" % ( selectArg, os.path.join(pathFastBit, fromArg), whereArg, limit) res = fastbit.query(os.path.join(pathFastBit, fromArg), selectArg, whereArg, limit) print >> sys.stderr, 'Number of records: %i' % len( res['values']) except: print >> sys.stderr, 'ERROR Executing query: ' + ( "SELECT %s FROM %s WHERE %s LIMIT %i" % (selectArg, os.path.join(pathFastBit, fromArg), whereArg, limit)) res = {} if res is not None and 'columns' in res: cols = res['columns'] #control if the history list has reach the limit if len(history['history']) >= historyLimit: history['history'] = history['history'][0:historyLimit - 1] #insert the newly executed query at the beginning of the list history['history'] = [ "SELECT %s FROM %s WHERE %s" % (selectArg.upper(), fromArg.upper(), whereArg.upper()) ] + history['history'] saveTempFile(history, os.path.join(ntopSpoolPath, tempQueryHistory)) else: cols = [] if res is not None and 'values' in res: toFormat = getAddrCols( selectArg) #get a list of addr column numbers for x in res['values']: for j in toFormat: #for every number in the list format as an IP ADDR try: #just ipv4 x[j] = socket.inet_ntop(socket.AF_INET, struct.pack('>L', x[j])) except: #could be an ipv6 try: x[j] = socket.inet_ntop( socket.AF_INET6, struct.pack('>L', x[j])) except: #failed ipv6 adn ipv4 conversion print >> sys.stderr, "fastbit.py: IMPOSSIBLE TO FORMAT value: " + str( x[j]) + " TO IP ADDR" #x[1]=socket.inet_ntop(socket.AF_INET,struct.pack('>L',x[1])) rows = res['values']
def begin(): rrdFilesPath = os.path.join(ntop.getDBPath(), 'rrd') ''' Check the existence of the rrd database files that maintain history of this script''' def updateDBS(time, resultsValue, durationValue): #global rrdFilesPath rrdAlarmDbPath = os.path.join(rrdFilesPath, 'rrdAlarm/') if not os.path.exists(rrdAlarmDbPath) or not os.path.isdir( rrdAlarmDbPath): os.mkdir(rrdAlarmDbPath) nameDuration = "duration" nameResults = "results" #nameDuration="duration.rrd" #nameResults="results.rrd" #archives=['RRA:AVERAGE:0.5:1:60', # 'RRA:AVERAGE:0.5:30:6']#1 hour and 3 hours data try: #rrdtool.update(os.path.join(rrdAlarmDbPath,nameDuration), 'N:'+str(durationValue)) ntop.updateRRDGauge(rrdAlarmDbPath, nameDuration, durationValue, 0) #print>>sys.stderr, 'Updating'+str(durationValue) except: print >> sys.stderr, 'RRDAlarm: Error Updating rrdDB ' + nameDuration ''' dataSources=['DS:duration:GAUGE:120:0:U'] rrdtool.create(rrdAlarmDbPath+nameDuration, '--start', str(time), '--step', str(60), dataSources[0], archives[0], archives[1] ) rrdtool.update(rrdAlarmDbPath+nameDuration,'N:'+str(durationValue))''' try: #rrdtool.update(os.path.join(rrdAlarmDbPath,nameResults), 'N:'+str(resultsValue)) ntop.updateRRDGauge(rrdAlarmDbPath, nameResults, resultsValue, 0) except: print >> sys.stderr, 'RRDAlarm: Error Updating rrdDB ' + nameResults ''' dataSources=['DS:results:GAUGE:120:0:U'] rrdtool.create(rrdAlarmDbPath+nameResults, '--start', str(time), '--step', str(60), dataSources[0], archives[0], archives[1] ) rrdtool.update(rrdAlarmDbPath+nameResults, 'N:'+str(resultsValue))''' '''Function that must be called as a new thread so its execution time can be controlled and limited by the main thread. all the controls on the rrds are executed by this function ''' def controlT(): #global rrdFilesPath ntopSpoolPath = ntop.getSpoolPath() nameFileConfig = 'rrdAlarmConfig.txt' tempFileName = 'rrdAlarmStart.tmp' configuration = None TWODECIMAL = decimal.Decimal(10)**-2 timeStart = time.time() alarmsFired = 0 checkedFiles = 0 fmt = '%a, %d %b %Y %H:%M:%S' #format of the time showed form = cgi.FieldStorage() #get the parameter passed via the url noHTML = bool(form.getvalue('noHTML')) configFile = form.getvalue('configFile') if configFile and len(configFile) > 0: nameFileConfig = str(configFile) try: tempFile = open(os.path.join(ntopSpoolPath, tempFileName), 'r') configuration = pickle.load(tempFile) tempFile.close() if configuration and ( timeStart < float(configuration['timeStart']) + float(60)): ntop.sendHTTPHeader(1) ntop.printHTMLHeader('RRD Alarm Called too early!', 1, 0) ntop.sendString( "Wait at least a minute. Last Time started: %s" % time.strftime(fmt, time.localtime(configuration['timeStart']))) ntop.printHTMLFooter() return 0 #exit because the script was started less than one minute ago else: configuration['timeStart'] = timeStart except IOError: #the tempFile does not exist or some other problem print >> sys.stderr, 'RRDAlarm: IOError while accessing tempfile ' + tempFileName configuration = createNewConfiguration( rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) except pickle.PickleError, pickle.UnpicklingError: print >> sys.stderr, "RRDAlarm: Problems during the UnPickling load, tempFile Delete..." os.remove(os.path.join(ntopSpoolPath, tempFileName)) return -1 if configuration['lastModified'] != os.path.getmtime( os.path.join(ntopSpoolPath, nameFileConfig)): #if the configuration file has been changed the temp file must be rebuild and so the configuration dictionary configuration = createNewConfiguration( rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) listRows = [] parameterDic = { } #for each parameter inserted as a key a tupla will be assigned 'parameter':{actionToPerform, text} for threshold in configuration[ 'listThresholds']: #for all the thresholds listFiles = threshold.getListFilename() checkedFiles = checkedFiles + len(listFiles) for fileN in listFiles: #for all the filenames referred by the threshold #rrd_argv=[fileN,'AVERAGE', '--start', threshold.getStartTime(), '--end', threshold.getStartTime()] #Return :((start, end, step), (name1, name2, ...), [(data1, data2, ..), ...]) #print>>sys.stderr, '\nLOOK for the parameters '+str(threshold.getStartTime())+' '+str(threshold.getEndTime())+' '+str(fileN) rrdObj = ((0, 0, 0), (), []) #empty object try: #rrdObj=rrdtool.fetch(fileN, 'AVERAGE', '--start', threshold.getStartTime(), '--end', threshold.getEndTime()) rrdObj = ntop.rrd_fetch(fileN, 'AVERAGE', threshold.getStartTime(), threshold.getEndTime()) except Exception as e: print >> sys.stderr, 'start.py PyRRDTool exception ' + str( e) step = rrdObj[0][2] start = float(rrdObj[0][0]) end = float(rrdObj[0][1]) valueDataTuple = rrdObj[2] #for all the values returned check the threshold (from the end) if alarm has to be fired i = len(valueDataTuple) while i > 0: #for value in valueDataTuple: timeA = (step * i) + start i = i - 1 value = valueDataTuple[i] if threshold.checkIfFire( value[0]): #controls if the threshold was exceeded notFired = False alarmsFired = alarmsFired + 1 listRows.append( (threshold.getUniqueId(), fileN, value[0], threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(timeA)), timeA, threshold.getActionToPerform(), 'ALARM FIRED')) strAlarm = '<ALARM>\nID: %i FILENAME: %s\nVALUE: %s TYPE: %s THRESHOLD VALUE: %f\n LOCALTIME: %s START: %s END: %s\n</ALARM>\n' % ( threshold.getUniqueId(), fileN, value[0], threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(timeA)), threshold.getStartTime(), threshold.getEndTime()) if parameterDic.has_key( threshold.getActionParameter()): parameterDic[threshold.getActionParameter( )]['textAlarm'] = parameterDic[ threshold.getActionParameter( )]['textAlarm'] + strAlarm else: parameterDic[threshold.getActionParameter()] = { 'actionToPerform': threshold.getActionToPerform(), 'textAlarm': strAlarm } break #print>>sys.stderr, 'The type of the threshold was misconfigured!' else: #no alarm was fired listRows.append( (threshold.getUniqueId(), fileN, '-', threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(end)), end, 'None', 'OK') ) #at least one alarm was fired, adding the action to perform, text and parameter to the global dictionary saveTempFile( configuration, os.path.join(ntopSpoolPath, tempFileName) ) #save all the informations usefull for future calling of this script documentRoot = os.getenv('DOCUMENT_ROOT', '.') performActions( parameterDic, documentRoot ) #performs all the actions for the alarms fired (if any) duration = decimal.Decimal(str(time.time() - timeStart)).quantize( TWODECIMAL, decimal.ROUND_CEILING) updateDBS( int(timeStart), alarmsFired, duration ) #update rrds that trace the history of this script TODO check where to place this ntop.sendHTTPHeader(1) if not noHTML: #if this parameter was passed and if true send just the empty http response ntop.printHTMLHeader('RRD Alarm Report', 1, 0) try: basedir = os.path.join(documentRoot, 'python/templates') mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template('rrdAlarmStart.tmpl') buf = StringIO() ctx = Context(buf, listRows=listRows, duration=duration, checkedFiles=checkedFiles, alarmsFired=alarmsFired) myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) return 1 #finally: #condition.notify() ntop.printHTMLFooter() print >> sys.stderr, '%s CET Exit rrdAlarm' % time.strftime( fmt, time.localtime(time.time())) return 0
def begin(): # Imports for mako try: from mako.template import Template from mako.runtime import Context from mako.lookup import TemplateLookup from mako import exceptions except: ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1) ntop.sendString( "<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font><p></b><br>(1) 'sudo yum install python-setuptools' (on RedHat-like systems)<br>(2) 'sudo easy_install Mako'</font></center>" ) ntop.printHTMLFooter() return # Fix encoding #reload(sys) #sys.setdefaultencoding("latin1") templateFilename = 'ipPortQuery.tmpl' #fb_DB = '/tmp/' #ntop.getPreference ("fastbitDBPath"); #default location of the fastbit DB databasePath = ntop.getPreference("fastbit.DBPath") #default location of the fastbit DB if databasePath is None or databasePath == '': ntop.printHTMLHeader('ntop Fastbit Configuration Error', 1, 1) ntop.sendString( "<b><center><font color=red>Please set fastbit.DBPath ntop preferences from <i>Admin/Configure/Preferences</i> menu (es: fastbit.DBPath=/tmp/)</b></font></center>" ) ntop.printHTMLFooter() return #pathFastBit=os.path.join(databasePath,'fastbit'+os.path.sep) form = cgi.FieldStorage() #get from the url the parameter configfile that contains the #path+filename of the configfile to read fromAuto = form.getvalue('fromAuto') if fromAuto: #print>>sys.stderr, "AJAX REQUEST FOR PARTITION IN "+databasePath+" "+fromAuto jsonString = expandFrom(fromAuto, os.path.join(databasePath, "")) ntop.sendHTTPHeader(12) ntop.sendString(jsonString) return documentRoot = os.getenv('DOCUMENT_ROOT', '.') selectArg = 'PROTOCOL,IPV4_SRC_ADDR,L4_SRC_PORT,IPV4_DST_ADDR,L4_DST_PORT,IN_BYTES,IN_PKTS' fromArg = form.getvalue('partition') ipSrc = form.getvalue('ipSrc') ipDst = form.getvalue('ipDst') portSrc = form.getvalue('portSrc') portDst = form.getvalue('portDst') limit = int(form.getvalue('limit', 100)) if limit < 0: limit = 0 res = None #variable to store the results of the query ntop.printHTMLHeader('IP-Port Query', 1, 0) #regex to check passed parameters ipV4Type = re.compile( r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' ) portType = re.compile(r'\d{1,5}') #pprint.pprint(ipV4Type.match(str(ipSrc)), sys.stderr) formatErrorString = '' #without the partition do nothing if fromArg: whereArg = '1=1' #to avoid leaving the where clause empty if ipSrc: #print>>sys.stderr, 'ECCO '+str(ipV4Type.match(ipSrc)) if ipV4Type.match(ipSrc): whereArg = whereArg + ' AND IPV4_SRC_ADDR=' + str( ipToNumber(ipSrc)) else: formatErrorString = formatErrorString + 'Source ip format invalid! ipv4 format required. ' if portSrc: if portType.match(portSrc): whereArg = whereArg + ' AND L4_SRC_PORT=' + str(portSrc) else: formatErrorString = formatErrorString + 'Source Port format invalid! Number required. ' if ipDst: if ipV4Type.match(ipDst): whereArg = whereArg + ' AND IPV4_DST_ADDR=' + str( ipToNumber(ipDst)) else: formatErrorString = formatErrorString + 'Destination ip format invalid! ipv4 format required. ' if portDst: if portType.match(portDst): whereArg = whereArg + ' AND L4_DST_PORT=' + str(portDst) else: formatErrorString = formatErrorString + 'Destination Port format invalid! Number required. ' try: #pipe = subprocess.Popen (['ntop.getPreference ("fastbit.fbquery")', "-c", selectArg, "-d", fromArg, "-q", whereArg, "-P", "-L", limit], #print>>sys.stderr, "Query passed: SELECT %s FROM %s WHERE %s LIMIT %i" %(selectArg,os.path.join(databasePath, fromArg), whereArg, limit) if formatErrorString == '': res = fastbit.query(os.path.join(databasePath, fromArg), selectArg, whereArg, limit) else: print >> sys.stderr, 'ipPortQuery: ERROR ' + formatErrorString ntop.sendString('<center><font color=red>%s</font></center>' % formatErrorString) #print>>sys.stderr, 'Number of records: %i' % len(res['values']) except: print >> sys.stderr, 'ERROR Executing query: ' + ( "SELECT %s FROM %s WHERE %s LIMIT %i" % (selectArg, os.path.join(databasePath, fromArg), whereArg, limit)) res = {} if res is not None and 'columns' in res and 'values' in res: toFormat = getAddrCols( selectArg) #get a list of addr column numbers for x in res['values']: x[0] = getNameByProto(x[0]) #format protocol number to text for j in toFormat: #for every number in the list format as an IP ADDR ipStr = numberToIp(x[j]) x[j] = '<a href="/%s.html" class="tooltip">%s</a>' % ( ipStr, ipStr ) #format ip number to string ip and create a link to ntop host page '''else: print>>sys.stderr, 'ipPortQuery: ERROR partition required' ntop.sendString('<center><font color=red>Partition field required!</font></center>')''' #pprint.pprint(res, sys.stderr) #if res is not None: # res['columns']=['Protocol', 'IP Source Addr', 'IP Dest. Addr', 'Source Port', 'Dest. Port', 'Bytes Rcvd', 'Packets Rcvd'] try: basedir = os.path.join(documentRoot, 'python/templates') mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template(templateFilename) buf = StringIO() ctx = Context(buf, results=res) myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) ntop.printHTMLFooter()
def begin(): rrdFilesPath = os.path.join(ntop.getDBPath(), "rrd") """ Check the existence of the rrd database files that maintain history of this script""" def updateDBS(time, resultsValue, durationValue): # global rrdFilesPath rrdAlarmDbPath = os.path.join(rrdFilesPath, "rrdAlarm/") if not os.path.exists(rrdAlarmDbPath) or not os.path.isdir(rrdAlarmDbPath): os.mkdir(rrdAlarmDbPath) nameDuration = "duration" nameResults = "results" # nameDuration="duration.rrd" # nameResults="results.rrd" # archives=['RRA:AVERAGE:0.5:1:60', # 'RRA:AVERAGE:0.5:30:6']#1 hour and 3 hours data try: # rrdtool.update(os.path.join(rrdAlarmDbPath,nameDuration), 'N:'+str(durationValue)) ntop.updateRRDGauge(rrdAlarmDbPath, nameDuration, durationValue, 0) # print>>sys.stderr, 'Updating'+str(durationValue) except: print >>sys.stderr, "RRDAlarm: Error Updating rrdDB " + nameDuration """ dataSources=['DS:duration:GAUGE:120:0:U'] rrdtool.create(rrdAlarmDbPath+nameDuration, '--start', str(time), '--step', str(60), dataSources[0], archives[0], archives[1] ) rrdtool.update(rrdAlarmDbPath+nameDuration,'N:'+str(durationValue))""" try: # rrdtool.update(os.path.join(rrdAlarmDbPath,nameResults), 'N:'+str(resultsValue)) ntop.updateRRDGauge(rrdAlarmDbPath, nameResults, resultsValue, 0) except: print >>sys.stderr, "RRDAlarm: Error Updating rrdDB " + nameResults """ dataSources=['DS:results:GAUGE:120:0:U'] rrdtool.create(rrdAlarmDbPath+nameResults, '--start', str(time), '--step', str(60), dataSources[0], archives[0], archives[1] ) rrdtool.update(rrdAlarmDbPath+nameResults, 'N:'+str(resultsValue))""" """Function that must be called as a new thread so its execution time can be controlled and limited by the main thread. all the controls on the rrds are executed by this function """ def controlT(): # global rrdFilesPath ntopSpoolPath = ntop.getSpoolPath() nameFileConfig = "rrdAlarmConfig.txt" tempFileName = "rrdAlarmStart.tmp" configuration = None TWODECIMAL = decimal.Decimal(10) ** -2 timeStart = time.time() alarmsFired = 0 checkedFiles = 0 fmt = "%a, %d %b %Y %H:%M:%S" # format of the time showed form = cgi.FieldStorage() # get the parameter passed via the url noHTML = bool(form.getvalue("noHTML")) configFile = form.getvalue("configFile") if configFile and len(configFile) > 0: nameFileConfig = str(configFile) try: tempFile = open(os.path.join(ntopSpoolPath, tempFileName), "r") configuration = pickle.load(tempFile) tempFile.close() if configuration and (timeStart < float(configuration["timeStart"]) + float(60)): ntop.sendHTTPHeader(1) ntop.printHTMLHeader("RRD Alarm Called too early!", 1, 0) ntop.sendString( "Wait at least a minute. Last Time started: %s" % time.strftime(fmt, time.localtime(configuration["timeStart"])) ) ntop.printHTMLFooter() return 0 # exit because the script was started less than one minute ago else: configuration["timeStart"] = timeStart except IOError: # the tempFile does not exist or some other problem print >>sys.stderr, "RRDAlarm: IOError while accessing tempfile " + tempFileName configuration = createNewConfiguration(rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) except pickle.PickleError, pickle.UnpicklingError: print >>sys.stderr, "RRDAlarm: Problems during the UnPickling load, tempFile Delete..." os.remove(os.path.join(ntopSpoolPath, tempFileName)) return -1 if configuration["lastModified"] != os.path.getmtime(os.path.join(ntopSpoolPath, nameFileConfig)): # if the configuration file has been changed the temp file must be rebuild and so the configuration dictionary configuration = createNewConfiguration(rrdFilesPath, os.path.join(ntopSpoolPath, nameFileConfig), timeStart) listRows = [] parameterDic = ( {} ) # for each parameter inserted as a key a tupla will be assigned 'parameter':{actionToPerform, text} for threshold in configuration["listThresholds"]: # for all the thresholds listFiles = threshold.getListFilename() checkedFiles = checkedFiles + len(listFiles) for fileN in listFiles: # for all the filenames referred by the threshold # rrd_argv=[fileN,'AVERAGE', '--start', threshold.getStartTime(), '--end', threshold.getStartTime()] # Return :((start, end, step), (name1, name2, ...), [(data1, data2, ..), ...]) # print>>sys.stderr, '\nLOOK for the parameters '+str(threshold.getStartTime())+' '+str(threshold.getEndTime())+' '+str(fileN) rrdObj = ((0, 0, 0), (), []) # empty object try: # rrdObj=rrdtool.fetch(fileN, 'AVERAGE', '--start', threshold.getStartTime(), '--end', threshold.getEndTime()) rrdObj = ntop.rrd_fetch(fileN, "AVERAGE", threshold.getStartTime(), threshold.getEndTime()) except Exception as e: print >>sys.stderr, "start.py PyRRDTool exception " + str(e) step = rrdObj[0][2] start = float(rrdObj[0][0]) end = float(rrdObj[0][1]) valueDataTuple = rrdObj[2] # for all the values returned check the threshold (from the end) if alarm has to be fired i = len(valueDataTuple) while i > 0: # for value in valueDataTuple: timeA = (step * i) + start i = i - 1 value = valueDataTuple[i] if threshold.checkIfFire(value[0]): # controls if the threshold was exceeded notFired = False alarmsFired = alarmsFired + 1 listRows.append( ( threshold.getUniqueId(), fileN, value[0], threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(timeA)), timeA, threshold.getActionToPerform(), "ALARM FIRED", ) ) strAlarm = ( "<ALARM>\nID: %i FILENAME: %s\nVALUE: %s TYPE: %s THRESHOLD VALUE: %f\n LOCALTIME: %s START: %s END: %s\n</ALARM>\n" % ( threshold.getUniqueId(), fileN, value[0], threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(timeA)), threshold.getStartTime(), threshold.getEndTime(), ) ) if parameterDic.has_key(threshold.getActionParameter()): parameterDic[threshold.getActionParameter()]["textAlarm"] = ( parameterDic[threshold.getActionParameter()]["textAlarm"] + strAlarm ) else: parameterDic[threshold.getActionParameter()] = { "actionToPerform": threshold.getActionToPerform(), "textAlarm": strAlarm, } break # print>>sys.stderr, 'The type of the threshold was misconfigured!' else: # no alarm was fired listRows.append( ( threshold.getUniqueId(), fileN, "-", threshold.getType(), threshold.getValue(), time.strftime(fmt, time.localtime(end)), end, "None", "OK", ) ) # at least one alarm was fired, adding the action to perform, text and parameter to the global dictionary saveTempFile( configuration, os.path.join(ntopSpoolPath, tempFileName) ) # save all the informations usefull for future calling of this script documentRoot = os.getenv("DOCUMENT_ROOT", ".") performActions(parameterDic, documentRoot) # performs all the actions for the alarms fired (if any) duration = decimal.Decimal(str(time.time() - timeStart)).quantize(TWODECIMAL, decimal.ROUND_CEILING) updateDBS( int(timeStart), alarmsFired, duration ) # update rrds that trace the history of this script TODO check where to place this ntop.sendHTTPHeader(1) if not noHTML: # if this parameter was passed and if true send just the empty http response ntop.printHTMLHeader("RRD Alarm Report", 1, 0) try: basedir = os.path.join(documentRoot, "python/templates") mylookup = TemplateLookup(directories=[basedir]) myTemplate = mylookup.get_template("rrdAlarmStart.tmpl") buf = StringIO() ctx = Context( buf, listRows=listRows, duration=duration, checkedFiles=checkedFiles, alarmsFired=alarmsFired ) myTemplate.render_context(ctx) ntop.sendString(buf.getvalue()) except: ntop.sendString(exceptions.html_error_template().render()) return 1 # finally: # condition.notify() ntop.printHTMLFooter() print >>sys.stderr, "%s CET Exit rrdAlarm" % time.strftime(fmt, time.localtime(time.time())) return 0