Commit 3f9caa80 authored by Tomas Hlavacek's avatar Tomas Hlavacek

ULG Cisco decorators and select commands added.

parent fe1747c3
......@@ -7,7 +7,8 @@ ULG development version 0.1
Basic instalation procedure is:
1) install prerequisites: Python 2.7, Genshi, Python CGI module and pexpect
1) install prerequisites: Python 2.7, Genshi, Python CGI module, urllib
and pexpect
2) deploy files in src directory to some place in WWW tree
3) edit config.py to set up routers and credentials
4) edit defaults.py to set up paths
......
......@@ -25,6 +25,7 @@ usage_limit = 1 # maximum concurrently processe
# Settings defaults
always_start_thread = True
debug = False
rescan_on_display = False
persistent_storage_file = '/tmp/ulg.data'
session_dir = '/tmp'
usage_counter_file = '/tmp/ulg.lock'
......@@ -49,6 +50,9 @@ STRING_SESSION_OVERLIMIT = "<em>Limit of maximum concurrently running sessions a
STRING_ARBITRARY_ERROR = "Error encountered. Operation aborted. See log for further details."
STRING_IPADDRESS = "IP address"
STRING_IPSUBNET = "IP subnet"
STRING_MACADDRESS = "MAC address"
STRING_NONEORINTORIPADDRESS = "None or Interface or IP address"
STRING_INTERFACE = "Interface"
# URL generator functions
def getASNURL(asn):
......
......@@ -28,21 +28,21 @@
<py:when test="param.getType() == 'select'">
<td align="left"> \
<select name="param${pidx}"> \
<py:for each="paridx,parname in enumerate(param.getOptionNames())">
<py:for each="paridx,partuple in enumerate(param.getOptions())">
<py:choose>
<py:when test="default_routerid == ridx and default_commandid == cidx and defined('default_params') and pidx &lt; len(default_params) and paridx == int(default_params[pidx])">
<option value="$paridx" selected="selected"> \
${parname} \
<py:when test="default_routerid == ridx and default_commandid == cidx and defined('default_params') and partuple[0] == default_params[pidx]">
<option value="${partuple[0]}" selected="selected"> \
${partuple[1]} \
</option> \
</py:when>
<py:when test="paridx == param.getDefault()">
<option value="$paridx" selected="selected"> \
${parname} \
<py:when test="partuple[0] == param.getDefault()">
<option value="${partuple[0]}" selected="selected"> \
${partuple[1]} \
</option> \
</py:when>
<py:otherwise>
<option value="$paridx"> \
${parname} \
<option value="${partuple[0]}"> \
${partuple[1]} \
</option> \
</py:otherwise>
</py:choose>
......@@ -157,17 +157,17 @@
</table>
</form>
<div id="result">
<hr/>
<hr py:if="(defined('result') and result) or (defined('refresh') and (refresh>0))"/>
<py:choose>
<py:when test="defined('result') and result">
${result}
</py:when>
<py:otherwise>
<em>No result.</em>
</py:otherwise>
</py:choose>
<p py:if="defined('refresh') and (refresh>0)">
<em>Refreshing in $refresh seconds.</em>
<em>Please wait for data from the router...</em><br/>
<em>The page is going to be refreshed in $refresh seconds.</em>
</p>
</div>
<div id="footer">
......
......@@ -164,6 +164,42 @@ def testULGLog(testmessage="Test message no. 1."):
print traceback.format_exc()
return False
def testULGRescan():
try:
for r in config.routers:
r.rescanHook()
print "OK: Test running rescan."
return True
except Exception as e:
print "FAIL: Test running rescan.\n Exception="+str(e)
print traceback.format_exc()
return False
def testULGPersistentStorage():
try:
ps = ulgmodel.PersistentStorage.load()
ps.set('test','teststring')
ps.save()
ps2 = ulgmodel.PersistentStorage.load()
if(ps2.get('test') == 'teststring'):
ps2.delete('test')
if(ps2.get('test') == None):
print "OK: Test persistent storage."
return True
else:
print "FAIL: Test persistent storage: Delete performed no effect."
return False
else:
print "FAIL: Test persistent storage: Set performed no effect."
return False
except Exception as e:
print "FAIL: Test persistent storage.\n Exception="+str(e)
print traceback.format_exc()
return False
#####################################
results = []
......@@ -199,6 +235,10 @@ if __name__=="__main__":
runTest(testULGLog())
runTest(testULGRescan())
runTest(testULGPersistentStorage())
reportResults()
......@@ -23,6 +23,7 @@ import os, sys
import random
import time
import pickle
import re
import config
import defaults
......@@ -31,6 +32,8 @@ import ulgmodel
### ULG cron script
SESSION_FILE_REGEX='^ulg-.*\.session$'
class ULGCron:
def __init__(self):
pass
......@@ -40,13 +43,21 @@ class ULGCron:
r.rescanHook()
def clearSessions(self):
pass
sre = re.compile(SESSION_FILE_REGEX)
for file in os.listdir(defaults.session_dir):
if sre.match(file):
fp = defaults.session_dir+'/'+file
ulgmodel.log('Removing file '+fp)
try:
os.unlink(fp)
except OSError as e:
ulgmodel.log('Error while removing file '+fp+' '+str(e))
def run(self):
ulgmodel.log("ULG cron run.")
ulgmodel.log('ULG cron run.')
self.rescanRouters()
self.clearSessions()
ulgmodel.log("ULG cron finished.")
ulgmodel.log('ULG cron finished.')
# main
......
......@@ -30,6 +30,7 @@ import md5
import pickle
import re
import fcntl
import urllib
import traceback
import config
......@@ -163,9 +164,9 @@ class DecoratorHelper:
return os.path.basename(__file__)
def getURL(self,action,parameters={}):
url=self.getScriptURL() + ("?action=%s" % action)
url=self.getScriptURL() + ("?action=%s" % urllib.quote(action))
for k in parameters.keys():
url = url + '&' + k + '=' + parameters[k]
url = url + '&' + k + '=' + urllib.quote(parameters[k])
return url
def getIndexURL(self):
......@@ -201,7 +202,7 @@ class DecoratorHelper:
return ('<pre>%s</pre>' % text)
def ahref(self,url,text):
return ('<a href=%s>%s</a>' % (url,text))
return ('<a href=%s>%s</a>' % (str(url),str(text)))
class ULGCgi:
def __init__(self):
......@@ -354,11 +355,11 @@ class ULGCgi:
session.cleanParameters()
for pidx,ps in enumerate(session.getCommand().getParamSpecs()):
if('param'+str(pidx) in moreparams.keys()):
session.addParameter(moreparams['param'+str(pidx)])
session.addParameter(str(moreparams['param'+str(pidx)]))
else:
session.addParameter(ps.getDefault())
# run the command (possibly in a separate thread)
# run the command (possibly in a separate process)
self.runCommand(session)
# redirect to the session display
......
This diff is collapsed.
......@@ -24,6 +24,8 @@ import re
from time import localtime, strftime
from genshi.template import TemplateLoader
from genshi.core import Markup
import pickle
import fcntl
import defaults
......@@ -33,7 +35,7 @@ def log(*messages):
try:
with open(defaults.log_file, 'a') as l:
for m in messages:
l.write(strftime("%b %d %Y %H:%M:%S: ", localtime()) + m)
l.write(strftime("%b %d %Y %H:%M:%S: ", localtime()) + m + "\n")
except Exception:
pass
......@@ -41,18 +43,19 @@ def debug(message):
log('DEBUG:' + message)
class PersistentStorgage(object):
def __init__(self,filename=defaults.persistent_storage_file):
self.filename = filename
class PersistentStorage(object):
def __init__(self):
self.data = {}
def save(self):
f = open(self.filename,'wb')
def save(self,filename=defaults.persistent_storage_file):
# TODO: locking
f = open(filename,'wb')
pickle.dump(self, f)
f.close()
@staticmethod
def load(filename=defaults.persistent_storage_file):
# TODO: locking
if(os.path.isfile(filename)):
f = open(filename, 'rb')
s = pickle.load(f)
......@@ -67,6 +70,10 @@ class PersistentStorgage(object):
def set(self,key,value):
self.data[key] = value
def delete(self,key):
if(key in self.data.keys()):
del(self.data[key])
def getDict(self):
return self.data
......@@ -140,9 +147,11 @@ class TextParameter(object):
else:
raise Exception("Invalid input encountered: Check did not passed.")
class SelectionParameter(object):
def __init__(self,option_tuples=[],name=defaults.STRING_PARAMETER,default=0):
"option_tupes=[(name,value),(name2,value2),(name3equalsvalue3,),...]"
class SelectionParameter(TextParameter):
def __init__(self,option_tuples=[],name=defaults.STRING_PARAMETER,default=None):
"option_tupes=[(value,name),(value2,name2),(value3equalsname3,),...]"
self.option_tuples = []
self.setOptions(option_tuples)
self.name=name
self.default=default
......@@ -150,41 +159,38 @@ class SelectionParameter(object):
def getType(self):
return 'select'
def getName(self):
return self.name
def getDefault(self):
return self.default
if(self.default and (self.default in [v[0] for v in self.getOptions()])):
return self.default
else:
return self.getOptions()[0]
def setOptions(self,option_tuples):
self.option_tuples=option_tuples
self.option_tuples = []
for o in option_tuples:
if(len(o) >= 2):
self.option_tuples.append(tuple((o[0],o[1],)))
elif(len(o) == 1):
self.option_tuples.append(tuple((o[0],o[0],)))
else:
raise Exception("Invalid option passed in SelectionParameter configuration. Zero-sized tuple.")
def getOptions(self):
return self.option_tuples
def getOptionNames(self):
return [o[0] for o in self.getOptions()]
def checkInput(self,input):
index=0
try:
index=int(input)
except ValueError:
return False
if(index>=0 and index<len(self.getOptions())):
if(input and (input in [v[0] for v in self.getOptions()])):
return True
else:
return False
def normalizeInput(self,input):
log("DEBUG: returning selection parameterd input: "+str(input))
if(self.checkInput(input)):
if(len(self.getOptions()[int(input)])==2):
return self.getOptions()[int(input)][1]
else:
return self.getOptions()[int(input)][0]
return input
else:
raise Exception("Invalid input encountered: Check did not passed.")
raise Exception("Invalid input encountered: Check did not passed.")
class TextCommand(object):
def __init__(self,command,param_specs=[],name=None):
......@@ -221,7 +227,6 @@ class TextCommand(object):
return True
def normalizeParameters(self,parameters):
if parameters == None:
return []
......@@ -266,7 +271,7 @@ class AnyCommand(TextCommand):
class Router(object):
def __init__(self):
self.setCommands({})
self.setCommands([])
self.setName('')
def setName(self,name):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment