Refactoring of interface to use bootstrap for the interface, bower for the management, merge of everything into one page
This commit is contained in:
parent
6b863b78fd
commit
f091774b74
10 changed files with 220 additions and 384 deletions
4
.bowerrc
Normal file
4
.bowerrc
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"directory": "www/vendor/",
|
||||||
|
"analytics": false
|
||||||
|
}
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -60,4 +60,4 @@ target/
|
||||||
# application
|
# application
|
||||||
www/*.html
|
www/*.html
|
||||||
www/hosts/*.html
|
www/hosts/*.html
|
||||||
www/networks/*.html
|
www/vendor
|
||||||
|
|
11
bower.json
Normal file
11
bower.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "saltinventory",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"jquery": ">=2.1.4",
|
||||||
|
"jquery-number": ">=2.1.6",
|
||||||
|
"datatables": ">=1.10.9",
|
||||||
|
"bootstrap": "~3.3.5"
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,19 +4,17 @@
|
||||||
# Requirements:
|
# Requirements:
|
||||||
#
|
#
|
||||||
# * salt
|
# * salt
|
||||||
# * python-netaddr
|
|
||||||
#
|
#
|
||||||
|
|
||||||
import salt.client
|
import salt.client
|
||||||
from netaddr import *
|
import salt.runner
|
||||||
|
import salt.config
|
||||||
from jinja2 import Template, BaseLoader, TemplateNotFound, FileSystemLoader, Environment
|
from jinja2 import Template, BaseLoader, TemplateNotFound, FileSystemLoader, Environment
|
||||||
|
|
||||||
# settings
|
# settings
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
'base_path': 'www/',
|
'base_path': 'www/',
|
||||||
'host_page_path': 'www/hosts/',
|
|
||||||
'network_page_path': 'www/networks/',
|
|
||||||
'template_path': 'templates/',
|
'template_path': 'templates/',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,94 +24,35 @@ class Inventorizer:
|
||||||
config = None
|
config = None
|
||||||
|
|
||||||
saltcmd = None
|
saltcmd = None
|
||||||
|
saltrun = None
|
||||||
|
|
||||||
host_list = {}
|
host_list = {}
|
||||||
network_list = {}
|
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
self.saltcmd = salt.client.LocalClient()
|
self.saltcmd = salt.client.LocalClient()
|
||||||
|
|
||||||
|
opts = salt.config.master_config('/etc/salt/master')
|
||||||
|
self.saltrun = salt.runner.RunnerClient(opts)
|
||||||
|
|
||||||
self.process()
|
self.process()
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
self.collectHostData()
|
self.collectHostData()
|
||||||
self.createHostList()
|
self.createHostList()
|
||||||
self.collectNetworkData()
|
|
||||||
self.createHostPages()
|
|
||||||
self.createNetworkList()
|
|
||||||
self.createNetworkPages()
|
|
||||||
|
|
||||||
def collectHostData(self):
|
def collectHostData(self):
|
||||||
self.host_list = self.saltcmd.cmd('*', 'grains.items')
|
self.host_list = self.saltcmd.cmd('*', 'grains.items')
|
||||||
|
self.stat_list = self.saltrun.cmd('manage.status')
|
||||||
def collectNetworkData(self):
|
|
||||||
result = self.saltcmd.cmd('*', 'network.interfaces')
|
|
||||||
for hostname, hostdata in result.iteritems():
|
|
||||||
for interface, interfacedata in hostdata.iteritems():
|
|
||||||
|
|
||||||
if interfacedata.has_key('inet'):
|
|
||||||
for netdata in interfacedata['inet']:
|
|
||||||
ip = IPNetwork(netdata['address'] + '/' + netdata['netmask'])
|
|
||||||
host = {'hostname': hostname, 'address': netdata['address'], 'netobj': ip}
|
|
||||||
self.addNetworkHost(ip, host)
|
|
||||||
|
|
||||||
if interfacedata.has_key('secondary'):
|
|
||||||
for netdata in interfacedata['secondary']:
|
|
||||||
ip = IPNetwork(netdata['address'] + '/' + netdata['netmask'])
|
|
||||||
host = {'hostname': hostname, 'address': netdata['address'], 'netobj': ip}
|
|
||||||
self.addNetworkHost(ip, host)
|
|
||||||
|
|
||||||
if interfacedata.has_key('inet6'):
|
|
||||||
for netdata in interfacedata['inet6']:
|
|
||||||
ip = IPNetwork(netdata['address'] + '/' + netdata['prefixlen'])
|
|
||||||
host = {'hostname': hostname, 'address': netdata['address'], 'netobj': ip}
|
|
||||||
self.addNetworkHost(ip, host)
|
|
||||||
|
|
||||||
|
|
||||||
def addNetworkHost(self, ip, host):
|
|
||||||
if self.network_list.has_key(ip.cidr):
|
|
||||||
self.network_list[ip.cidr].append(host)
|
|
||||||
else:
|
|
||||||
self.network_list[ip.cidr] = [host]
|
|
||||||
|
|
||||||
def createHostList(self):
|
def createHostList(self):
|
||||||
fo = open(self.config['base_path'] + "hostlist.html", "wb")
|
fo = open(self.config['base_path'] + "hostlist.html", "wb")
|
||||||
env = Environment(loader = FileSystemLoader(config['template_path']))
|
env = Environment(loader = FileSystemLoader(config['template_path']))
|
||||||
template = env.get_template('hostlist_template.html')
|
template = env.get_template('hostlist_template.html')
|
||||||
fo.write(template.render({'hostlist': self.host_list}))
|
fo.write(template.render({'hostlist': self.host_list, 'statlist': self.stat_list}))
|
||||||
fo.close
|
fo.close
|
||||||
|
|
||||||
def createHostPages(self):
|
|
||||||
for hostname, hostdata in self.host_list.iteritems():
|
|
||||||
self.createHostPage(hostname, hostdata)
|
|
||||||
|
|
||||||
def createHostPage(self, hostname, hostdata):
|
|
||||||
fo = open(self.config['host_page_path'] + hostname + ".html", "wb")
|
|
||||||
env = Environment(loader = FileSystemLoader(config['template_path']))
|
|
||||||
template = env.get_template('host_template.html')
|
|
||||||
fo.write(template.render(hostdata))
|
|
||||||
fo.close
|
|
||||||
|
|
||||||
def createNetworkList(self):
|
|
||||||
fo = open(self.config['base_path'] + "networklist.html", "wb")
|
|
||||||
env = Environment(loader = FileSystemLoader(config['template_path']))
|
|
||||||
env.filters['len'] = self.lenFilter
|
|
||||||
template = env.get_template('networklist_template.html')
|
|
||||||
fo.write(template.render({'networklist': self.network_list}))
|
|
||||||
fo.close
|
|
||||||
|
|
||||||
def createNetworkPages(self):
|
|
||||||
for network, networkdata in self.network_list.iteritems():
|
|
||||||
self.createNetworkPage(network, networkdata)
|
|
||||||
|
|
||||||
def createNetworkPage(self, network, networkdata):
|
|
||||||
fo = open(self.config['network_page_path'] + str(network.cidr).replace('/', '_') + ".html", "wb")
|
|
||||||
env = Environment(loader = FileSystemLoader(config['template_path']))
|
|
||||||
env.filters['replace'] = self.replaceFilter
|
|
||||||
template = env.get_template('network_template.html')
|
|
||||||
fo.write(template.render({'network': network, 'data': networkdata}))
|
|
||||||
fo.close
|
|
||||||
|
|
||||||
def lenFilter(self, list):
|
def lenFilter(self, list):
|
||||||
return len(list)
|
return len(list)
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{ id }}</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.4/css/jquery.dataTables.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../res/style.css">
|
|
||||||
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="../res/jquery.number.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="http://cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js"></script>
|
|
||||||
<script type="text/javascript" class="init">
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<header class="header clearfix">
|
|
||||||
<div class="logo">Inventory | {{ id }}</div>
|
|
||||||
|
|
||||||
<nav class="menu_main">
|
|
||||||
<ul>
|
|
||||||
<li><a href="../hostlist.html">Hostlist</a></li>
|
|
||||||
<li><a href="../networklist.html">Networks</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<article class="article clearfix">
|
|
||||||
<h2>System information</h2>
|
|
||||||
<h3>Generic</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Operating System: {{ kernel }} ({{ kernelrelease }})</li>
|
|
||||||
<li>Distribution: {{ lsb_distrib_description }}</li>
|
|
||||||
<li>Machine type: {% if virtual != "physical" %} Virtual ({{ virtual }}) {% else %} Physical {% endif %}</li>
|
|
||||||
<li>Architecture: {{ osarch }}</li>
|
|
||||||
<li>Salt version: {{ saltversion }}</li>
|
|
||||||
</ul>
|
|
||||||
<h3>CPU</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Numer of CPUs: {{ num_cpus }}</li>
|
|
||||||
<li>CPU architecture: {{ cpuarch }}</li>
|
|
||||||
<li>CPU model: {{ cpu_model }}</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Memory</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Total memory: {{ mem_total }}</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Storage</h3>
|
|
||||||
<ul>
|
|
||||||
<li></li>
|
|
||||||
<li></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Network</h3>
|
|
||||||
<ul>
|
|
||||||
<li></li>
|
|
||||||
<li></li>
|
|
||||||
</ul>
|
|
||||||
</article>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,137 +1,137 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
<title>Host list</title>
|
<title>Host list</title>
|
||||||
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.4/css/jquery.dataTables.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="res/style.css">
|
|
||||||
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="res/jquery.number.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="http://cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js"></script>
|
|
||||||
<script type="text/javascript" class="init">
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
|
|
||||||
// search box for each column (http://www.datatables.net/examples/api/multi_filter.html) - Part 1
|
|
||||||
|
|
||||||
$('#hostlist thead td').each( function () {
|
|
||||||
var title = $('#hostlist thead th').eq( $(this).index() ).text();
|
|
||||||
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
var table = $('#hostlist').DataTable({
|
|
||||||
"footerCallback": function ( row, data, start, end, display ) {
|
|
||||||
var api = this.api(), data;
|
|
||||||
|
|
||||||
// Remove the formatting to get integer data for summation
|
|
||||||
var intVal = function ( i ) {
|
|
||||||
return typeof i === 'string' ?
|
|
||||||
i.replace(/[\$,]/g, '')*1 :
|
|
||||||
typeof i === 'number' ?
|
|
||||||
i : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Total over this page
|
|
||||||
// mem
|
|
||||||
memTotal = api
|
|
||||||
.column( 2, { page: 'current'} )
|
|
||||||
.data()
|
|
||||||
.reduce( function (a, b) {
|
|
||||||
return intVal(a) + intVal(b);
|
|
||||||
}, 0 );
|
|
||||||
// cpu
|
|
||||||
cpuTotal = api
|
|
||||||
.column( 3, { page: 'current'} )
|
|
||||||
.data()
|
|
||||||
.reduce( function (a, b) {
|
|
||||||
return intVal(a) + intVal(b);
|
|
||||||
}, 0 );
|
|
||||||
|
|
||||||
// Update footer
|
|
||||||
$( api.column( 2 ).footer() ).html(
|
|
||||||
$.number(memTotal, 0, ",", ".")
|
|
||||||
);
|
|
||||||
|
|
||||||
$( api.column( 3 ).footer() ).html(
|
|
||||||
cpuTotal
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// search box for each column (http://www.datatables.net/examples/api/multi_filter.html) - Part 2
|
|
||||||
|
|
||||||
// Apply the search
|
|
||||||
table.columns().eq( 0 ).each( function ( colIdx ) {
|
|
||||||
$( 'input', table.column( colIdx ).header() ).on( 'keyup change', function () {
|
|
||||||
table
|
|
||||||
.column( colIdx )
|
|
||||||
.search( this.value, true )
|
|
||||||
.draw();
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
$('td.number').number( true, 0, ",", "." );
|
|
||||||
} );
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/dist/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../vendor/datatables/media/css/jquery.dataTables.css">
|
||||||
|
|
||||||
|
<script type="text/javascript" language="javascript" src="vendor/jquery/dist/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" language="javascript" src="vendor/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||||
|
<script type="text/javascript" language="javascript" src="vendor/jquery-number/jquery.number.min.js"></script>
|
||||||
|
<script type="text/javascript" language="javascript" src="vendor/datatables/media/js/jquery.dataTables.min.js"></script>
|
||||||
|
<script type="text/javascript" language="javascript" src="res/inittable.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="container">
|
||||||
<div class="container">
|
<div class="jumbotron">
|
||||||
|
<h1>Inventory <small>Salt minions list</small></h1>
|
||||||
<header class="header clearfix">
|
</div>
|
||||||
<div class="logo">Inventory | Host list</div>
|
|
||||||
|
|
||||||
<nav class="menu_main">
|
|
||||||
<ul>
|
|
||||||
<li class="active"><a href="hostlist.html">Hostlist</a></li>
|
|
||||||
<li><a href="networklist.html">Networks</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<article class="article clearfix">
|
|
||||||
|
|
||||||
<h2>Hosts</h2>
|
<div class="container-fluid">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h2>Available minions</h2>
|
||||||
|
<table id="hostlist" class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Machine type</th>
|
||||||
|
<th>OS</th>
|
||||||
|
<th>Roles</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>RAM (MB)</th>
|
||||||
|
<th># CPUs</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Machine type</td>
|
||||||
|
<td>OS</td>
|
||||||
|
<td>Roles</td>
|
||||||
|
<td>IP</td>
|
||||||
|
<td>RAM (MB)</td>
|
||||||
|
<td># CPUs</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for name, data in hostlist.iteritems() %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-info" data-toggle="modal" data-target="#{{ name.translate(None, '.') }}">
|
||||||
|
<span class="glyphicon glyphicon-search" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
{{ name }}
|
||||||
|
</td>
|
||||||
|
<td>{% if data.virtual != "physical" %} Virtual ({{ data.virtual }}) {% else %} Physical {% endif %}</td>
|
||||||
|
<td>{{ data.lsb_distrib_description }}</td>
|
||||||
|
<td>{% for role in data.roles %} {{ role }} {% endfor %}</td>
|
||||||
|
<td>{{ data.fqdn_ip }}</td>
|
||||||
|
<td class="right number">{{ data.mem_total }}</td>
|
||||||
|
<td class="right">{{ data.num_cpus }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td style="font-weight: bold;">Total:</th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
<td style="font-weight: bold;"></th>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
<h2>Disconnected minions</h2>
|
||||||
|
<table id="statuslist" class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for name in statlist %}
|
||||||
|
<tr class="danger">
|
||||||
|
<td>{{ name }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% for name, data in hostlist.iteritems() %}
|
||||||
|
<div class="modal" id="{{ name.translate(None, '.') }}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h1 class="modal-title" id="myModalLabel">{{ name }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h2>System information</h2>
|
||||||
|
<h3>Generic</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Operating System: {{ data.kernel }} ({{ data.kernelrelease }})</li>
|
||||||
|
<li>Distribution: {{ data.lsb_distrib_description }}</li>
|
||||||
|
<li>Machine type: {% if data.virtual != "physical" %} Virtual ({{ data.virtual }}) {% else %} Physical {% endif %}</li>
|
||||||
|
<li>Architecture: {{ data.osarch }}</li>
|
||||||
|
<li>Salt version: {{ data.saltversion }}</li>
|
||||||
|
</ul>
|
||||||
|
<h3>CPU</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Numer of CPUs: {{ data.num_cpus }}</li>
|
||||||
|
<li>CPU architecture: {{ data.cpuarch }}</li>
|
||||||
|
<li>CPU model: {{ data.cpu_model }}</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Memory</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Total memory: {{ data.mem_total }}</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Roles</h3>
|
||||||
|
<ul>
|
||||||
|
{% for role in data.roles %}
|
||||||
|
<li>{{ role }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table id="hostlist" class="display">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>OS</th>
|
|
||||||
<th>RAM (MB)</th>
|
|
||||||
<th># CPUs</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Name</th>
|
|
||||||
<td>OS</th>
|
|
||||||
<td>RAM</th>
|
|
||||||
<td># CPUs</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for name, data in hostlist.iteritems() %}
|
|
||||||
<tr>
|
|
||||||
<td><a href = 'hosts/{{ name }}.html'>{{ name }}</a></td>
|
|
||||||
<td>{{ data.lsb_distrib_description }}</td>
|
|
||||||
<td class="right number">{{ data.mem_total }}</td>
|
|
||||||
<td class="right">{{ data.num_cpus }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
<th class="right"></th>
|
|
||||||
<th class="right"></th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>{{ network.cidr }}</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.4/css/jquery.dataTables.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="../res/style.css">
|
|
||||||
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="../res/jquery.number.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="http://cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js"></script>
|
|
||||||
<script type="text/javascript" class="init">
|
|
||||||
$(document).ready(function() {
|
|
||||||
var table = $('#adresses').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<header class="header clearfix">
|
|
||||||
<div class="logo">Inventory | {{ network.cidr }}</div>
|
|
||||||
|
|
||||||
<nav class="menu_main">
|
|
||||||
<ul>
|
|
||||||
<li><a href="../hostlist.html">Hostlist</a></li>
|
|
||||||
<li><a href="../networklist.html">Networks</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<article class="article clearfix">
|
|
||||||
<h2>Adresses</h2>
|
|
||||||
<table id="adresses" class="display">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Address</th>
|
|
||||||
<th>Host</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Address</th>
|
|
||||||
<td>Host</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for netdata in data %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ netdata['address'] }}</td>
|
|
||||||
<td><a href="../hosts/{{ netdata['hostname'] }}.html">{{ netdata['hostname'] }}</a></td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,67 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
|
|
||||||
<title>Network list</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.4/css/jquery.dataTables.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="res/style.css">
|
|
||||||
<script type="text/javascript" language="javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="res/jquery.number.min.js"></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="http://cdn.datatables.net/1.10.4/js/jquery.dataTables.min.js"></script>
|
|
||||||
<script type="text/javascript" class="init">
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
var table = $('#networklist').DataTable();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<header class="header clearfix">
|
|
||||||
<div class="logo">Inventory | Network list</div>
|
|
||||||
|
|
||||||
<nav class="menu_main">
|
|
||||||
<ul>
|
|
||||||
<li><a href="hostlist.html">Hostlist</a></li>
|
|
||||||
<li class="active"><a href="networklist.html">Networks</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<article class="article clearfix">
|
|
||||||
|
|
||||||
<h2>Networks</h2>
|
|
||||||
|
|
||||||
<table id="networklist" class="display">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Network</th>
|
|
||||||
<th>Usage</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Network</th>
|
|
||||||
<td>Usage</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for network, data in networklist.iteritems() %}
|
|
||||||
<tr>
|
|
||||||
<td><a href = 'networks/{{ network.cidr|replace('/', '_') }}.html'>{{ network.cidr }}</a></td>
|
|
||||||
<td>{{ data|len }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
68
www/res/inittable.js
Normal file
68
www/res/inittable.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#hostlist thead td').each( function () {
|
||||||
|
var title = $('#hostlist thead th').eq( $(this).index() ).text();
|
||||||
|
$(this).html( '<input type="text" class="form-control" placeholder="Search '+title+'" />' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
var table = $('#hostlist').DataTable({
|
||||||
|
'paging': false,
|
||||||
|
'info': false,
|
||||||
|
'dom': 't',
|
||||||
|
'footerCallback': function ( row, data, start, end, display ) {
|
||||||
|
var api = this.api(), data;
|
||||||
|
|
||||||
|
// Remove the formatting to get integer data for summation
|
||||||
|
var intVal = function ( i ) {
|
||||||
|
return typeof i === 'string' ?
|
||||||
|
i.replace(/[\$,]/g, '')*1 :
|
||||||
|
typeof i === 'number' ?
|
||||||
|
i : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Total over this page
|
||||||
|
hostsTotal = api
|
||||||
|
.rows()
|
||||||
|
.count();
|
||||||
|
|
||||||
|
// mem
|
||||||
|
memTotal = api
|
||||||
|
.column( 5, { page: 'current'} )
|
||||||
|
.data()
|
||||||
|
.reduce( function (a, b) {
|
||||||
|
return intVal(a) + intVal(b);
|
||||||
|
}, 0 );
|
||||||
|
// cpu
|
||||||
|
cpuTotal = api
|
||||||
|
.column( 6, { page: 'current'} )
|
||||||
|
.data()
|
||||||
|
.reduce( function (a, b) {
|
||||||
|
return intVal(a) + intVal(b);
|
||||||
|
}, 0 );
|
||||||
|
|
||||||
|
// Update footer
|
||||||
|
$( api.column( 1 ).footer() ).html(
|
||||||
|
$.number(hostsTotal, 0, '.', ' ')
|
||||||
|
);
|
||||||
|
|
||||||
|
$( api.column( 5 ).footer() ).html(
|
||||||
|
$.number(memTotal, 0, '.', ' ')
|
||||||
|
);
|
||||||
|
|
||||||
|
$( api.column( 6 ).footer() ).html(
|
||||||
|
cpuTotal
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Apply the search
|
||||||
|
table.columns().eq( 0 ).each( function ( colIdx ) {
|
||||||
|
$( 'input', table.column( colIdx ).header() ).on( 'keyup change', function () {
|
||||||
|
table
|
||||||
|
.column( colIdx )
|
||||||
|
.search( this.value, true )
|
||||||
|
.draw();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
$('td.number').number( true, 0, '.', ' ' );
|
||||||
|
});
|
Reference in a new issue