Commit b8dd8dd7 authored by Tomas Hlavacek's avatar Tomas Hlavacek

Initial commit with minimalistic technology demonstrator for ULG.

parents
ULG development version 0.1
- development started in June 2012
- sponsored by CZ.NIC (http://www.nic.cz)
- intention is to create a versatile Looking Glass for various routers
- genshi and cherrypy was used in the beginning
- cherrypy was later dropped and simple CGI was used instead
Basic instalation procedure is:
1) install prerequisites: Python 2.7, Genshi, Python CGI module 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
5) create .htaccess file with following contents:
<FilesMatch "(.pyc|.*~)">
Deny from all
</FilesMatch>
Options +ExecCGI
AddHandler cgi-script .py
(Or use corresponding config of your web server.)
6) access http://yourserver/path-to-ulg/index.py via browser
7) change texts and templates in defaults.py and templates/index.py and other files in templates/
Contacts:
1) Author: tmshlvck@gmail.com or tomas.hlavacek@nic.cz
2) GIT hub https://github.com/tmshlvck/ulg
Future plans:
This "pre-release" is only a preview and "technology demonstrator". Requests and contributions are welcomed. I indend to support BIRD (http://bird.network.cz) and Cisco routers and switches and support typical BGP-related commands and also IGP and L2 management commands in order to make LG more useful for ordinary NOC staff especially for information aquisition during outages and problems.
#!/usr/bin/env python
#
# ULG - Universal Looking Glass
# by Tomas Hlavacek (tomas.hlavacek@nic.cz)
# last udate: June 21 2012
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ulg import *
routers = [
CiscoRouter(host='testrouter1.core.company.com', user='xyz', password='xyz'),
CiscoRouter(host='testrouter2.core.company.com', user='xyz', password='xyz'),
BirdRouterLocal('/var/run/bird.ctl')
]
#!/usr/bin/env python
#
# ULG - Universal Looking Glass
# by Tomas Hlavacek (tomas.hlavacek@nic.cz)
# last udate: June 21 2012
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# HTML presentation settings
header = 'Universal looking glass test header'
refresh_interval = 5 # interval of html refresh
usage_limit = 1 # maximum concurrently processed requests
# Settings defaults
always_start_thread = True
debug = True
default_bird_sock = '/var/run/bird.ctl'
# Template dir relative to the index.py script
template_dir = 'templates'
index_template_file = 'index.html'
display_template_file = 'display.html'
# Paths to external programs
bin_ssh = '/usr/bin/ssh'
# Output (localized) strings
STRING_SESSION_OVERLIMIT = "<em>Limit of maximum concurrently running sessions and/or queries has been reached. The command can not be executed now. Please retry later.</em>"
STRING_ARBITRARY_ERROR = "Error encountered. Operation aborted. See log for further details."
This diff is collapsed.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/">
<head>
<title>Universal Looking Glass</title>
<py:if test="defined('refresh')">
<meta http-equiv="refresh" content="$refresh" py:if="defined('refresh') and (refresh>0)" />
</py:if>
<script type="text/javascript">
function updateFormParams()
{
var rs=document.getElementById("routerselect");
var cs=document.getElementById("commandselect");
<py:for each="ridx,router in enumerate(routers)">
<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())">
<![CDATA[ if((rs.options[rs.selectedIndex].value==$ridx) && (cs.options[cs.selectedIndex].value==$cidx)) { ]]>
<py:choose>
<py:when test="routers[ridx].listCommands()[cidx].getParamSpec() and (routers[ridx].listCommands()[cidx].getParamSpec().getType() == 'text')">
document.getElementById("paramrow").innerHTML=' \
<th align="left"> \
<label for="param">3. ${routers[ridx].listCommands()[cidx].getParamSpec().getName()}:</label> \
</th> \
<td align="left"> \
<input type="text" id="param1" name="param1" value="${routers[ridx].listCommands()[cidx].getParamSpec().getDefault()}" /></td>';
</py:when>
<py:otherwise>
document.getElementById("paramrow").innerHTML='';
</py:otherwise>
</py:choose>
}
</py:for>
</py:for>
}
function updateFormCommands()
{
var rs=document.getElementById("routerselect");
<py:for each="ridx,router in enumerate(routers)">
if(rs.options[rs.selectedIndex].value==$ridx) {
document.getElementById("commandselect").innerHTML='<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())"><py:choose><py:when test="cidx == default_command"><option value="$cidx" selected="selected">${cmd.getName()}</option></py:when><py:otherwise><option value="$cidx">${cmd.getName()}</option></py:otherwise></py:choose></py:for>';
}
</py:for>
updateFormParams()
}
</script>
</head>
<body class="index">
<script>
window.onload=updateFormCommands;
</script>
<div id="header">
<py:choose>
<py:when test="defaults.header">
<h1>ULG - $defaults.header</h1>
</py:when>
<py:otherwise>
<h1>ULG</h1>
</py:otherwise>
</py:choose>
</div>
<p>Select router to perform operation on, then select a command to perform and add (optional) argument if needed.</p>
<form action="runcommand" method="post">
<input type="hidden" name="session" value="$default_session" py:if="defined('default_session') and (default_session)" />
<table summary="Form settings">
<tbody>
<tr>
<th align="left"><label for="router">1. Router selection:</label></th>
<td>
<select id="routerselect" name="router" onchange="updateFormCommands()">
<py:for each="ridx,rtr in enumerate(routers)">
<py:choose>
<py:when test="ridx == default_router">
<option value="$ridx" selected="selected">
${rtr.getName()}
</option>
</py:when>
<py:otherwise>
<option value="$ridx">
${rtr.getName()}
</option>
</py:otherwise>
</py:choose>
</py:for>
</select>
</td>
</tr>
<tr height="10">
</tr>
<tr>
<th align="left" valign="top">2. Command selection:</th>
<td align="left">
<select id="commandselect" name="command" onchange="updateFormParams()">
<py:for each="cidx,cmd in enumerate(routers[default_router].listCommands())">
<py:choose>
<py:when test="cidx == default_command">
<option value="$cidx" selected="selected">
${cmd.getName()}
</option>
</py:when>
<py:otherwise>
<option value="$cidx">
${cmd.getName()}
</option>
</py:otherwise>
</py:choose>
</py:for>
</select>
</td>
</tr>
<tr height="10"></tr>
<tr id="paramrow">
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Submit" />
</td>
</tr>
</tbody>
</table>
</form>
<div id="result">
<hr/>
<py:choose>
<py:when test="defined('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>
</p>
</div>
<div id="footer">
<hr/>
<p class="legalese" align="right"><small>© 2012 Tomas Hlavacek</small></p>
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/">
<head>
<title>Universal Looking Glass</title>
<py:if test="defined('refresh')">
<meta http-equiv="refresh" content="$refresh" py:if="defined('refresh') and (refresh>0)" />
</py:if>
<script type="text/javascript">
function updateFormParams()
{
var rs=document.getElementById("routerselect");
var cs=document.getElementById("commandselect");
<py:for each="ridx,router in enumerate(routers)">
<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())">
<![CDATA[ if((rs.options[rs.selectedIndex].value==$ridx) && (cs.options[cs.selectedIndex].value==$cidx)) { ]]>
document.getElementById("paramsect").innerHTML=' \
<py:for each="pidx,param in enumerate(routers[ridx].listCommands()[cidx].getParamSpecs())">
<py:choose>
<py:when test="param.getType() == 'select'">
<tr> SELECT TODO!!! </tr> \
</py:when>
<py:otherwise>
<tr> \
<th align="left"> \
<label for="param">${pidx+3}. ${param.getName()}:</label> \
</th> \
<td align="left"> \
<input type="text" name="param${pidx}" value="${param.getDefault()}" /> \
</td> \
</tr> \
</py:otherwise>
</py:choose>
</py:for>';
}
</py:for>
</py:for>
}
function updateFormCommands()
{
var rs=document.getElementById("routerselect");
<py:for each="ridx,router in enumerate(routers)">
if(rs.options[rs.selectedIndex].value==$ridx) {
document.getElementById("commandselect").innerHTML='<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())"><py:choose><py:when test="cidx == default_commandid"><option value="$cidx" selected="selected">${cmd.getName()}</option></py:when><py:otherwise><option value="$cidx">${cmd.getName()}</option></py:otherwise></py:choose></py:for>';
}
</py:for>
updateFormParams()
}
</script>
</head>
<body class="index">
<script>
window.onload=updateFormCommands;
</script>
<div id="header">
<py:choose>
<py:when test="defaults.header">
<h1>ULG - $defaults.header</h1>
</py:when>
<py:otherwise>
<h1>ULG</h1>
</py:otherwise>
</py:choose>
</div>
<p>Select router to perform operation on, then select a command to perform and add (optional) argument if needed.</p>
<form action="index.py?action=runcommand" method="post">
<input type="hidden" name="sessionid" value="$default_sessionid" py:if="defined('default_sessionid') and (default_sessionid)" />
<table summary="Form settings">
<tbody>
<tr>
<th align="left"><label for="router">1. Router selection:</label></th>
<td>
<select id="routerselect" name="routerid" onchange="updateFormCommands()">
<py:for each="ridx,rtr in enumerate(routers)">
<py:choose>
<py:when test="ridx == default_routerid">
<option value="$ridx" selected="selected">
${rtr.getName()}
</option>
</py:when>
<py:otherwise>
<option value="$ridx">
${rtr.getName()}
</option>
</py:otherwise>
</py:choose>
</py:for>
</select>
</td>
</tr>
<tr height="10">
</tr>
<tr>
<th align="left" valign="top">2. Command selection:</th>
<td align="left">
<select id="commandselect" name="commandid" onchange="updateFormParams()">
</select>
</td>
</tr>
<tr height="10"></tr>
</tbody>
<tbody id="paramsect">
</tbody>
<tbody>
<tr>
<td></td>
<td>
<input type="submit" value="Submit" />
</td>
</tr>
</tbody>
</table>
</form>
<div id="result">
<hr/>
<py:choose>
<py:when test="defined('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>
</p>
</div>
<div id="footer">
<hr/>
<p class="legalese" align="right"><small>(c) 2012 Tomas Hlavacek</small></p>
</div>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/">
<head>
<title>Universal Looking Glass</title>
<py:if test="defined('refresh')">
<meta http-equiv="refresh" content="$refresh" py:if="defined('refresh') and (refresh>0)" />
</py:if>
<script type="text/javascript">
function updateFormParams()
{
var rs=document.getElementById("routerselect");
var cs=document.getElementById("commandselect");
<py:for each="ridx,router in enumerate(routers)">
<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())">
<![CDATA[ if((rs.options[rs.selectedIndex].value==$ridx) && (cs.options[cs.selectedIndex].value==$cidx)) { ]]>
document.getElementById("paramsect").innerHTML=' \
<py:for each="pidx,param in enumerate(routers[ridx].listCommands()[cidx].getParamSpecs())">
<py:choose>
<py:when test="param.getType() == 'select'">
<tr> SELECT TODO!!! </tr> \
</py:when>
<py:otherwise>
<tr> \
<th align="left"> \
<label for="param">${pidx+3}. ${param.getName()}:</label> \
</th> \
<td align="left"> \
<input type="text" name="param${pidx}" value="${param.getDefault()}" /> \
</td> \
</tr> \
</py:otherwise>
</py:choose>
</py:for>';
}
</py:for>
</py:for>
}
function updateFormCommands()
{
var rs=document.getElementById("routerselect");
<py:for each="ridx,router in enumerate(routers)">
if(rs.options[rs.selectedIndex].value==$ridx) {
document.getElementById("commandselect").innerHTML='<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())"><py:choose><py:when test="cidx == default_commandid"><option value="$cidx" selected="selected">${cmd.getName()}</option></py:when><py:otherwise><option value="$cidx">${cmd.getName()}</option></py:otherwise></py:choose></py:for>';
}
</py:for>
updateFormParams()
}
</script>
</head>
<body class="index">
<script>
window.onload=updateFormCommands;
</script>
<div id="header">
<py:choose>
<py:when test="defaults.header">
<h1>ULG - $defaults.header</h1>
</py:when>
<py:otherwise>
<h1>ULG</h1>
</py:otherwise>
</py:choose>
</div>
<p>Select router to perform operation on, then select a command to perform and add (optional) argument if needed.</p>
<form action="runcommand" method="post">
<input type="hidden" name="sessionid" value="$default_sessionid" py:if="defined('default_sessionid') and (default_sessionid)" />
<table summary="Form settings">
<tbody>
<tr>
<th align="left"><label for="router">1. Router selection:</label></th>
<td>
<select id="routerselect" name="routerid" onchange="updateFormCommands()">
<py:for each="ridx,rtr in enumerate(routers)">
<py:choose>
<py:when test="ridx == default_routerid">
<option value="$ridx" selected="selected">
${rtr.getName()}
</option>
</py:when>
<py:otherwise>
<option value="$ridx">
${rtr.getName()}
</option>
</py:otherwise>
</py:choose>
</py:for>
</select>
</td>
</tr>
<tr height="10">
</tr>
<tr>
<th align="left" valign="top">2. Command selection:</th>
<td align="left">
<select id="commandselect" name="commandid" onchange="updateFormParams()">
</select>
</td>
</tr>
<tr height="10"></tr>
</tbody>
<tbody id="paramsect">
</tbody>
<tbody>
<tr>
<td></td>
<td>
<input type="submit" value="Submit" />
</td>
</tr>
</tbody>
</table>
</form>
<div id="result">
<hr/>
<py:choose>
<py:when test="defined('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>
</p>
</div>
<div id="footer">
<hr/>
<p class="legalese" align="right"><small>(c) 2012 Tomas Hlavacek</small></p>
</div>
</body>
</html>
#!/usr/bin/env python
#
# ULG - Universal Looking Glass
# by Tomas Hlavacek (tomas.hlavacek@nic.cz)
# last udate: June 21 2012
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Imports
import os, sys
import random
import cherrypy
import config
import defaults
import ulg
import index
import sys
import re
import time
# main
if __name__=="__main__":
r = config.routers[0]
# print r.runCommand(r.listCommands()[0],[])
# print "Test router 0 command 0 passed. \n\n"
u = index.ULGCgi()
print u.renderULGIndex(routerid=0,commandid=0,sessionid=None)
print "Test ULG index passed. \n\n"
rdr = u.renderULGAction(routerid=0,commandid=0,sessionid=None,**{})
print "Test ULG run action passed. Rdr exc = %s \n\n" % str(rdr)
m = re.compile('sessionid=([^"]+)"',re.M).search(rdr)
if(m):
sessionid = m.groups()[0]
print "Test ULG run action passed with sessionid="+str(sessionid) + "\n\n"
else:
print "Failed ULG run action.\n\n"
sys.exit(0)
print u.renderULGResult(sessionid=sessionid)
print "Test ULG result passed 1st time. Sleeping 5 seconds."
time.sleep(5)
print u.renderULGResult(sessionid=sessionid)
print "Test ULG result passed 2nd time. Sleeping 5 seconds."
time.sleep(5)
print u.renderULGResult(sessionid=sessionid)
print "Test ULG result passed 3rd time. Finish."
This diff is collapsed.
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