aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@colazero.tele.tg18.gathering.org>2018-03-26 13:04:05 +0200
committerroot <root@colazero.tele.tg18.gathering.org>2018-03-26 13:04:05 +0200
commitbe54730288b9925003e88788e65f11199cc8292b (patch)
treef5a96e9b34fa43fb1fc36cc6923c346d75ed9f5f
parentd6a5794527b555dca86be61c757d24bb86930dd3 (diff)
Mange dager med rot på TG18
-rw-r--r--.gitignore2
-rwxr-xr-xcollectors/dhcptail.pl2
-rwxr-xr-xcollectors/snmpfetchng.pl45
-rw-r--r--include/nms/util.pm12
-rwxr-xr-xtemplating/templating.py3
-rwxr-xr-xweb/api/public/dhcp10
-rwxr-xr-xweb/api/public/switch-state8
-rwxr-xr-xweb/api/write/network-update57
-rwxr-xr-xweb/api/write/switch-update2
-rw-r--r--web/index.html5
-rw-r--r--web/js/nms-info-box.js8
-rw-r--r--web/js/nms-map-handlers.js21
-rw-r--r--web/js/nms.js2
13 files changed, 74 insertions, 103 deletions
diff --git a/.gitignore b/.gitignore
index 35d595f..292e2fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
.*.swp
data/
+web/templates/
+web/files/
diff --git a/collectors/dhcptail.pl b/collectors/dhcptail.pl
index 5fd8cf0..5f117b9 100755
--- a/collectors/dhcptail.pl
+++ b/collectors/dhcptail.pl
@@ -27,7 +27,7 @@ my %months = (
my $realtime = 0;
my ($dbh, $q,$check);
$dbh = nms::db_connect();
-$q = $dbh->prepare("INSERT INTO dhcp (dhcp_server,switch,time,ip,mac) VALUES($nms::config::dhcp_id,(SELECT switch FROM switches WHERE ?::inet << subnet4 and deleted = false ORDER BY sysname LIMIT 1),?,?,?)");
+$q = $dbh->prepare("INSERT INTO dhcp (dhcp_server,network,time,ip,mac) VALUES($nms::config::dhcp_id,(SELECT network FROM networks WHERE ?::inet << subnet4 ORDER BY name LIMIT 1),?,?,?)");
$check = $dbh->prepare("SELECT max(time)::timestamp - ?::timestamp < '0s'::interval as doit FROM dhcp where dhcp_server = $nms::config::dhcp_id;");
open(SYSLOG, "tail -n 9999999 -F /var/log/messages |") or die "Unable to tail syslog: $!";
diff --git a/collectors/snmpfetchng.pl b/collectors/snmpfetchng.pl
index 9c06f4a..4312606 100755
--- a/collectors/snmpfetchng.pl
+++ b/collectors/snmpfetchng.pl
@@ -32,7 +32,7 @@ EOF
# Borrowed from snmpfetch.pl
our $qswitch = $dbh->prepare(<<"EOF")
SELECT
- sysname,switch,host(mgmt_v4_addr) as ip,host(mgmt_v6_addr) as ip2,community,
+ sysname,switch,host(mgmt_v6_addr) as ip,host(mgmt_v4_addr) as ip2,community,
DATE_TRUNC('second', now() - last_updated - poll_frequency) AS overdue
FROM
switches
@@ -70,7 +70,9 @@ sub populate_switches
my $ip;
$ip = $ref->{'ip'};
if (!defined($ip) or $ip eq "") {
- $ip = 'udp6:[' . $ref->{'ip2'} . ']';
+ $ip = 'udp:[' . $ref->{'ip2'} . ']';
+ } else {
+ $ip = 'udp6:[' . $ip . ']';
}
push @switches, {
'sysname' => $ref->{'sysname'},
@@ -95,6 +97,7 @@ sub inner_loop
$dbh->commit;
my $s = SNMP::Session->new(DestHost => $switch{'mgtip'},
Community => $switch{'community'},
+ Timeout => 1000000,
UseEnums => 1,
Version => '2');
my $ret = $s->bulkwalk(0, 10, @nms::config::snmp_objects, sub{ callback(\%switch, @_); });
@@ -162,7 +165,7 @@ sub callback{
for my $nic (@nicids) {
$tree2{'ports'}{$tree{$nic}{'ifName'}} = $tree{$nic};
my $tmp_field = '';
- for my $tmp_key (keys $tree{$nic}) {
+ for my $tmp_key (keys %{$tree{$nic}}) {
if(looks_like_number($tree{$nic}{$tmp_key})) {
$tmp_field = $tree{$nic}{$tmp_key};
} else {
@@ -170,23 +173,25 @@ sub callback{
}
my $cv = AE::cv;
- $influx->write(
- database => $nms::config::influx_database,
- data => [
- {
- measurement => 'ports',
- tags => {
- switch => $switch{'sysname'},
- interface => $tree{$nic}{'ifName'},
- },
- fields => { $tmp_key => $tmp_field },
- }],
- on_success => $cv,
- on_error => sub {
- $cv->croak("Failed to write data: @_");
- }
- );
- $cv->recv;
+ if (defined($tree{$nic}{'ifName'}) and $tree{$nic}{'ifName'} ne "") {
+ $influx->write(
+ database => $nms::config::influx_database,
+ data => [
+ {
+ measurement => 'ports',
+ tags => {
+ switch => $switch{'sysname'},
+ interface => $tree{$nic}{'ifName'},
+ },
+ fields => { $tmp_key => $tmp_field },
+ }],
+ on_success => $cv,
+ on_error => sub {
+ $cv->croak("Failed to write data: @_");
+ }
+ );
+ $cv->recv;
+ }
}
delete $tree{$nic};
diff --git a/include/nms/util.pm b/include/nms/util.pm
index 511da33..69f5392 100644
--- a/include/nms/util.pm
+++ b/include/nms/util.pm
@@ -91,10 +91,11 @@ sub guess_placement_dx {
$y = 880;
$xx = $x + 230;
$yy = $y + 40;
- } elsif ($name =~ /^distro(\d)$/) {
+ } elsif ($name =~ /^s(\d).floor$/) {
my $d = ($1);
+ $d -= 1;
$src = "distro";
- $x = 1550 - $d * 700;
+ $x = 1550 - $d * 600;
$y = 410;
$xx = $x + 230;
$yy = $y + 40;
@@ -180,11 +181,12 @@ sub guess_placement_tg {
$y = int(759 + 20.5 * $s);
$xx = $x + 65;
$yy = $y + 14;
- } elsif ($name =~ /^distro(\d)/) {
+ } elsif ($name =~ /^s(\d).floor/) {
my $d = ($1);
$src = "distro";
- $x = 292 + $d * 165;
- $y = 415;
+ $d -= 1;
+ $x = 260 + $d * 145;
+ $y = 417;
$xx = $x + 130;
$yy = $y + 20;
} else {
diff --git a/templating/templating.py b/templating/templating.py
index 3a29d7b..32abb0c 100755
--- a/templating/templating.py
+++ b/templating/templating.py
@@ -22,6 +22,8 @@ def updateData():
def netmask(ip):
return netaddr.IPNetwork(ip).netmask
+def cidr(ip):
+ return netaddr.IPNetwork(ip).prefixlen
def networkId(ip):
return netaddr.IPNetwork(ip).ip
def getFirstDhcpIp(ip):
@@ -36,6 +38,7 @@ def getPort(src):
env = Environment(loader=FileSystemLoader(['templates/','/opt/gondul/data/templates', '/opt/gondul/web/templates']), trim_blocks=True)
env.filters["netmask"] = netmask
+env.filters["cidr"] = cidr
env.filters["networkId"] = networkId
env.filters["getFirstDhcpIp"] = getFirstDhcpIp
env.filters["getLastDhcpIp"] = getLastDhcpIp
diff --git a/web/api/public/dhcp b/web/api/public/dhcp
index 0b0bb49..f153a49 100755
--- a/web/api/public/dhcp
+++ b/web/api/public/dhcp
@@ -8,16 +8,16 @@ use warnings;
use Data::Dumper;
nms::web::setwhen('60m');
-my $q = $nms::web::dbh->prepare('select distinct on (sysname) extract(epoch from date_trunc(\'second\',time)) as time,sysname from dhcp join switches on dhcp.switch = switches.switch where ' . $nms::web::when . ' and switches.deleted = false order by sysname,time desc;');
+my $q = $nms::web::dbh->prepare('select distinct on (name) extract(epoch from date_trunc(\'second\',time)) as time,name from dhcp join networks on dhcp.network = networks.network where ' . $nms::web::when . ' order by name,time desc;');
$q->execute();
while ( my $ref = $q->fetchrow_hashref() ) {
- my $sysname = $ref->{'sysname'};
- $json{'dhcp'}{$ref->{'sysname'}} = $ref->{'time'};
+ my $sysname = $ref->{'sname'};
+ $json{'dhcp'}{$ref->{'name'}} = $ref->{'time'};
}
-my $q2 = $nms::web::dbh->prepare("select sysname,count(distinct mac) as clients,count(distinct ip) as addresses,count(mac) as acks from dhcp natural join switches where $nms::web::when and switches.deleted = false group by switches.sysname;");
+my $q2 = $nms::web::dbh->prepare("select name,count(distinct mac) as clients,count(distinct ip) as addresses,count(mac) as acks from dhcp natural join networks where $nms::web::when group by networks.name;");
$q2->execute();
while (my $ref = $q2->fetchrow_hashref()) {
- $nms::web::json{'switches'}{$ref->{sysname}} = $ref;
+ $nms::web::json{'networks'}{$ref->{name}} = $ref;
}
$nms::web::cc{'max-age'} = "10";
diff --git a/web/api/public/switch-state b/web/api/public/switch-state
index 965e881..19bd771 100755
--- a/web/api/public/switch-state
+++ b/web/api/public/switch-state
@@ -14,9 +14,9 @@ my ($switch, $port) = split(/\//,$target,2);
my $q;
if (!defined($switch)) {
- $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' and switches.deleted = false group by switch);');
+ $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' and switches.deleted = false group by switch) and switches.deleted = false and not switches.tags \?& array[\'switchstateignore\'];');
} else {
- $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ' and switches.deleted = false;');
+ $q = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ' and switches.deleted = false and not switches.tags \?& array[\'switchstateignore\'];');
}
$q->execute();
@@ -83,9 +83,9 @@ while ( my $ref = $q->fetchrow_hashref() ) {
nms::web::setwhen('15m','10m');
my $q2;
if (!defined($switch)) {
- $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch);');
+ $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . ' and switches.deleted = false group by switch) and switches.deleted = false and not switches.tags \?& array[\'switchstateignore\'];');
} else {
- $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ';');
+ $q2 = $nms::web::dbh->prepare('select sysname,extract(epoch from date_trunc(\'second\',time)) as time,data from snmp natural join switches where id in (select max(id) from snmp where ' . $nms::web::when . 'group by switch) and sysname = ' . $nms::web::dbh->quote($switch) . ' and switches.deleted = false and not switches.tags \?& array[\'switchstateignore\'];');
}
$q2->execute();
diff --git a/web/api/write/network-update b/web/api/write/network-update
index f6684c5..6344c37 100755
--- a/web/api/write/network-update
+++ b/web/api/write/network-update
@@ -23,51 +23,23 @@ my @dups;
my $sth = $nms::web::dbh->prepare("SELECT name FROM networks WHERE name=?");
-my @fields = ('name','last_updated','placement','subnet4','subnet6','gw4','gw6','routing_point','vlan','tags');
-
-sub convertplace
-{
- my %in = %{$_[0]};
- my %out = ();
-
- if (not defined $in{'x1'} and defined($in{'x'})) {
- $out{'x1'} = int($in{'x'});
- $out{'y1'} = int($in{'y'});
- $out{'xx'} = int($in{'x'} + $in{'width'});
- $out{'yy'} = int($in{'y'} + $in{'height'});
- } else {
- return \%in;
- }
- return \%out;
-}
+my @fields = ('name','last_updated','subnet4','subnet6','gw4','gw6','routing_point','vlan','tags');
foreach my $tmp2 (@tmp) {
my %network = %{$tmp2};
my $affected = 0;
my %template = ();
map { $template{$_} = 'DEFAULT' } @fields;
- if (not defined($network{'sysname'})) {
+ if (not defined($network{'name'})) {
next;
}
- $sth->execute( $network{'sysname'});
+ $sth->execute( $network{'name'});
while ( my @row = $sth->fetchrow_array ) {
$affected += 1;
}
if ($affected == 0) {
- my %placement;
- if (not defined ($network{'placement'})) {
- %placement = guess_placement($network{'sysname'});
- } else {
- %placement = %{convertplace($network{'sysname'})};
- }
- my ($x1,$x2,$y1,$y2);
- $x1 = $placement{'x1'};
- $y1 = $placement{'y1'};
- $x2 = $placement{'xx'};
- $y2 = $placement{'yy'};
- $network{'placement'} = "(($x1,$y1),($x2,$y2))";
map {
if (defined ($template{$_})) {
@@ -76,24 +48,9 @@ foreach my $tmp2 (@tmp) {
} keys %network;
- $nms::web::dbh->do("INSERT INTO NETWORKS (name, last_updated, placement, subnet4, subnet6, routing_point, gw4, gw6, vlan, tags) VALUES ($template{'sysname'}, $template{'last_updated'}, $template{'placement'}, $template{'subnet4'}, $template{'subnet6'}, $template{'routing_point'}, $template{'gw4'}, $template{'gw6'}, $template{'vlan'}, $template{'tags'});");
- push @added, $network{'sysname'};
+ $nms::web::dbh->do("INSERT INTO NETWORKS (name, last_updated, subnet4, subnet6, routing_point, gw4, gw6, vlan, tags) VALUES ($template{'name'}, $template{'last_updated'}, $template{'subnet4'}, $template{'subnet6'}, $template{'routing_point'}, $template{'gw4'}, $template{'gw6'}, $template{'vlan'}, $template{'tags'});");
+ push @added, $network{'name'};
} else {
- if (defined($network{'placement'})) {
- my %placement;
- if ($network{'placement'} eq "reset") {
- %placement = guess_placement($network{'sysname'});
- } else {
- %placement = %{convertplace($network{'placement'})};
- }
- my ($x1,$x2,$y1,$y2);
- $x1 = $placement{'x1'};
- $y1 = $placement{'y1'};
- $x2 = $placement{'xx'};
- $y2 = $placement{'yy'};
- $network{'placement'} = "(($x1,$y1),($x2,$y2))";
- push @dups, "not really, but: " . $network{'placement'};
- }
if (defined($network{'tags'})) {
$network{'tags'} =~ s/'/"/g;
}
@@ -103,8 +60,8 @@ foreach my $tmp2 (@tmp) {
push @set, "$_=" . $dbh->quote($network{$_});
}
} keys %network;
- $nms::web::dbh->do("UPDATE NETWORKS SET " . join(", ", @set) . "WHERE name=" . $dbh->quote($network{'sysname'}) . ";");
- push @dups, $network{'sysname'};
+ $nms::web::dbh->do("UPDATE networks SET " . join(", ", @set) . "WHERE name=" . $dbh->quote($network{'name'}) . ";");
+ push @dups, $network{'name'};
}
}
$json{'networks_addded'} = \@added;
diff --git a/web/api/write/switch-update b/web/api/write/switch-update
index b71548b..bcf69e1 100755
--- a/web/api/write/switch-update
+++ b/web/api/write/switch-update
@@ -23,7 +23,7 @@ my @dups;
my $sth = $nms::web::dbh->prepare("SELECT sysname FROM switches WHERE sysname=?");
-my @fields = ( 'community', 'tags', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v4_gw', 'mgmt_v4_netsize', 'mgmt_v6_addr', 'mgmt_v6_gw', 'mgmt_v6_netsize', 'mgmt_vlan', 'placement', 'poll_frequency', 'subnet4', 'subnet6', 'sysname', 'traffic_vlan', 'deleted');
+my @fields = ( 'community', 'tags', 'distro_name', 'distro_phy_port', 'mgmt_v4_addr', 'mgmt_v6_addr', 'mgmt_vlan', 'placement', 'poll_frequency', 'sysname', 'traffic_vlan', 'deleted');
sub convertplace
{
diff --git a/web/index.html b/web/index.html
index 2fee54f..7b07f09 100644
--- a/web/index.html
+++ b/web/index.html
@@ -143,6 +143,7 @@
<div class="span3 col-lg-6">
<textarea id="template-input" class="form-control" cols="80" rows="25"></textarea>
<div class="form-inline">
+ https://gondul.tg.lol/api/templates/
<div class="form-group">
<select onchange="nmsTemplate.fromFile(this.value)" class="form-control" id="nmsTemplate-select">
<option value="">Select template</option>
@@ -150,7 +151,7 @@
</div>
<div class="form-group">
<label for="template-query-params">Query parameters</label>
- <input type="text" class="form-control" id="template-query-params" value="?switch=e13-1&foo=bar" />
+ <input type="text" class="form-control" id="template-query-params" value="?a=r1.ring:ge-1/0/2.0:mgmt+irb.666" />
</div>
<div class="form-group">
<button onclick="nmsTemplate.test()" class="btn btn-primary">Test</button>
@@ -158,7 +159,7 @@
</div>
</div>
<div class="span3 col-lg-6">
- <textarea id="template-output" class="form-control" disabled cols="80" rows="25"></textarea>
+ <textarea id="template-output" class="form-control" readonly cols="80" rows="25"></textarea>
</div>
</div>
</div>
diff --git a/web/js/nms-info-box.js b/web/js/nms-info-box.js
index 8f34031..4e8b18d 100644
--- a/web/js/nms-info-box.js
+++ b/web/js/nms-info-box.js
@@ -686,7 +686,7 @@ var switchPortsPanel = function () {
}
} catch(e) {};
- groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifDescr + ' </a><small>' + snmpJson[obj].ifAlias + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>';
+ groupObj.innerHTML = '<span class="panel-heading" style="display:block;"><a class="collapse-controller" role="button" data-toggle="collapse" href="#'+cleanObj+'-group">' + snmpJson[obj].ifDescr + ' </a><small>' + snmpJson[obj].ifName + '</small><span class="pull-right">' + traffic + '<i class="btn-xs ' + button + '"><span class="glyphicon ' + glyphicon + '" title="' + title + '" aria-hidden="true"></span></i></span></span>';
var groupObjCollapse = document.createElement("div");
groupObjCollapse.id = cleanObj + "-group";
@@ -1389,7 +1389,7 @@ var networkEditPanel = function() {
};
this.save = function () {
- var myData = nmsInfoBox._editStringify(this.sw);
+ var myData = nmsInfoBox._editStringify(this.sw,"name");
$.ajax({
type: "POST",
url: "/api/write/network-update",
@@ -1505,7 +1505,7 @@ nmsInfoBox._editChange = function(sw, v) {
out.value = myData;
};
-nmsInfoBox._editStringify = function(sw) {
- nmsInfoBox._editValues['sysname'] = sw;
+nmsInfoBox._editStringify = function(sw, sysname='sysname') {
+ nmsInfoBox._editValues[sysname] = sw;
return JSON.stringify([nmsInfoBox._editValues]);
};
diff --git a/web/js/nms-map-handlers.js b/web/js/nms-map-handlers.js
index f9fe52b..7200c60 100644
--- a/web/js/nms-map-handlers.js
+++ b/web/js/nms-map-handlers.js
@@ -516,13 +516,13 @@ function getDhcpColor(stop)
function dhcpUpdater()
{
- if (!testTree(nmsData,['dhcp','dhcp']) || !testTree(nmsData,['switches','switches'])) {
+ if (!testTree(nmsData,['dhcp','dhcp']) || !testTree(nmsData,['switches','switches']) || !testTree(nmsData,['smanagement','switches'])) {
return
}
var now = nmsData.dhcp.time;
for (var sw in nmsData.switches.switches) {
var c = nmsColor.blue;
- var s = nmsData.dhcp.dhcp[sw];
+ var s = nmsData.dhcp.dhcp[nmsData.smanagement.switches[sw].traffic_vlan];
if (s == undefined) {
nmsMap.setSwitchColor(sw,c);
continue;
@@ -536,9 +536,9 @@ function dhcpInfo(sw) {
var ret = new handlerInfo("dhcp","DHCP state");
ret.why = "No DHCP data";
ret.data[0].description = "DHCP age";
- if (testTree(nmsData,['dhcp','dhcp',sw])) {
+ if (testTree(nmsData,['dhcp','dhcp',nmsData.smanagement.switches[sw].traffic_vlan])) {
var now = nmsData.dhcp.time;
- var then = nmsData.dhcp.dhcp[sw];
+ var then = nmsData.dhcp.dhcp[nmsData.smanagement.switches[sw].traffic_vlan];
var diff = now - then;
var divider = 6;
if(tagged(sw,'slowdhcp')) {
@@ -551,11 +551,11 @@ function dhcpInfo(sw) {
} else {
ret.data[0].value = "No DHCP data";
if (testTree(nmsData,['smanagement','switches',sw])) {
- if (nmsData.smanagement.switches[sw].subnet4 == undefined ||
- nmsData.smanagement.switches[sw].subnet4 == "") {
- ret.data[0].value = "No associated subnets";
+ if (nmsData.smanagement.switches[sw].traffic_vlan == undefined ||
+ nmsData.smanagement.switches[sw].traffic_vlan == "") {
+ ret.data[0].value = "No associated networks";
ret.score = 0;
- ret.why = "No subnet registered";
+ ret.why = "No network associated";
} else {
ret.score = 350;
ret.why = "No DHCP data";
@@ -565,9 +565,10 @@ function dhcpInfo(sw) {
ret.why = "No management data for DHCP";
}
}
- if (testTree(nmsData,['dhcp','switches',sw,'clients'])) {
+ if (testTree(nmsData,['dhcp','networks',nmsData.smanagement.switches[sw].traffic_vlan,'clients'])) {
ret.data[1] = {};
- ret.data[1].value = nmsData.dhcp.switches[sw].clients;
+ ret.data[1].value = nmsData.dhcp.networks[nmsData.smanagement.switches[sw].traffic_vlan].clients;
+ console.log()
ret.data[1].description = "DHCP clients";
}
if (testTree(nmsData,['switches','switches',sw, 'tags'])) {
diff --git a/web/js/nms.js b/web/js/nms.js
index 0caac24..5e2dc22 100644
--- a/web/js/nms.js
+++ b/web/js/nms.js
@@ -134,7 +134,7 @@ function nmsTimer(handler, interval, name, description) {
function byteCount(bytes,precision) {
if (precision ==undefined)
precision = 1;
- var units = ['', 'K', 'M', 'G', 'T', 'P'];
+ var units = ['', 'K', 'M', 'G', 'T', 'P', 'E','Z'];
var i = 0;
while (bytes > 1024) {
bytes = bytes / 1024;