Commit c0fbcdc5 authored by Leigh Stoller's avatar Leigh Stoller

New version of the admin aggregate status page.

parent 9c966b49
<?php
#
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file 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 Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
#
# Aggregate Status.
#
function Do_AggregateStatus()
{
global $this_user;
global $ajax_args;
$blob = array();
if (!(ISADMIN() || ISFOREIGN_ADMIN())) {
SPITAJAX_ERROR(-1, "Not enough permission");
return -1;
}
$ams = Aggregate::AllAggregatesList();
while (list($index, $aggregate) = each($ams)) {
$urn = $aggregate->urn();
$blob[$urn] =
array("urn" => $urn,
"name" => $aggregate->name(),
"abbrev" => $aggregate->abbreviation(),
"nickname" => $aggregate->nickname(),
"url" => $aggregate->weburl(),
"disabled" => intval($aggregate->disabled()),
"adminonly" => intval($aggregate->adminonly()),
"datasets" => intval($aggregate->has_datasets()),
"reservations" => intval($aggregate->reservations()),
"monitor" => $aggregate->nomonitor() ? 0 : 1,
"status" => $aggregate->status(),
"last_contact" => $aggregate->last_success(),
"last_error" => $aggregate->last_error(),
"pcount" => intval($aggregate->pcount()),
"pfree" => intval($aggregate->pfree()),
"portals" => $aggregate->portals(),
"typeinfo" => $aggregate->typeinfo);
}
SPITAJAX_RESPONSE($blob);
}
# Local Variables:
# mode:php
# End:
?>
<?php
#
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file 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 Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
chdir("..");
include("defs.php3");
include_once("geni_defs.php");
chdir("apt");
include("quickvm_sup.php");
$page_title = "Status";
#
# Get current user.
#
RedirectSecure();
$this_user = CheckLoginOrRedirect();
$isadmin = (ISADMIN() ? 1 : 0);
$isfadmin = (ISFOREIGN_ADMIN() ? 1 : 0);
if (! (ISADMIN() || ISFOREIGN_ADMIN())) {
SPITUSERERROR("You do not have permission to view this page");
}
SPITHEADER(1);
echo "<link rel='stylesheet'
href='css/tablesorter.css'>\n";
echo "<div id='page-body'>
<div id='waitwait_div'></div>
<div id='oops_div'></div>
</div>\n";
echo "<script type='text/javascript'>\n";
echo " window.ISADMIN = $isadmin;\n";
echo " window.ISFADMIN = $isfadmin;\n";
echo "</script>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='js/lib/jquery.tablesorter.min.js'></script>\n";
echo "<script src='js/lib/jquery.tablesorter.widgets.min.js'></script>\n";
REQUIRE_UNDERSCORE();
REQUIRE_SUP();
REQUIRE_MOMENT();
SPITREQUIRE("js/aggregate-status");
AddTemplateList(array("aggregate-status", "waitwait-modal", "oops-modal"));
SPITFOOTER();
?>
......@@ -88,6 +88,7 @@ class Aggregate
function has_datasets() { return $this->field('has_datasets'); }
function reservations() { return $this->field('reservations'); }
function isfederate() { return $this->field('isfederate'); }
function nomonitor() { return $this->field('nomonitor'); }
function portals() { return $this->field('portals'); }
# accessors for the status info.
......@@ -245,6 +246,26 @@ class Aggregate
return $am_array;
}
#
# All aggregates
#
function AllAggregatesList() {
$am_array = array();
$query_result =
DBQueryFatal("select urn from apt_aggregates");
while ($row = mysql_fetch_array($query_result)) {
$urn = $row["urn"];
if (! ($aggregate = Aggregate::Lookup($urn))) {
TBERROR("Aggregate::SupportsReservations: ".
"Could not load aggregate $urn!", 1);
}
$am_array[$urn] = $aggregate;
}
return $am_array;
}
function ThisAggregate()
{
global $DEFAULT_AGGREGATE_URN;
......
......@@ -809,7 +809,7 @@ class Instance
# Return a list of types not to show user.
#
function NodeTypePruneList() {
global $ISEMULAB, $ISCLOUD, $ISAPT, $ISPNET, $ISPOWDER;
global $ISEMULAB, $ISCLOUD, $ISAPT, $ISPNET, $ISPOWDER, $TBMAINSITE;
$skiptypes = array("dboxvm" => true,
"d430k" => true,
......@@ -820,7 +820,7 @@ class Instance
"d2100" => true,
"pc2400w" => true);
if ($ISEMULAB || $ISCLOUD || $ISAPT) {
if (($ISEMULAB || $ISCLOUD || $ISAPT) && $TBMAINSITE) {
$skiptypes["sdr"] = true;
$skiptypes["nuc5300"] = true;
$skiptypes["enodeb"] = true;
......
$(function ()
{
'use strict';
var templates = APT_OPTIONS.fetchTemplateList(['aggregate-status',
'waitwait-modal', 'oops-modal']);
var template = _.template(templates['aggregate-status']);
var waitwait = templates['waitwait-modal'];
var oops = templates['oops-modal'];
function initialize()
{
window.APT_OPTIONS.initialize(sup);
$('#waitwait_div').html(waitwait);
$('#oops_div').html(oops);
LoadStatus();
}
function LoadStatus(earliest)
{
var callback = function(json) {
console.log(json);
if (json.code) {
console.log("Could not get status data: " + json.value);
return;
}
RenderPage(json.value);
};
var args = null;
var xmlthing = sup.CallServerMethod(null, "aggregate-status",
"AggregateStatus", args);
xmlthing.done(callback);
}
var flagshelp =
"<table class='table table-condensed table-bordered'>" +
" <tr><td>D</td><td>Disabled</td></tr>" +
" <tr><td>A</td><td>Admin only</td></tr>" +
" <tr><td>R</td><td>Reservations</td></tr>" +
" <tr><td>d</td><td>Datasets</td></tr>" +
" <tr><td>M</td><td>Monitored</td></tr>" +
"</table>";
function RenderPage(status)
{
_.each(status, function(value, key) {
// Generate a "flags" string.
var flags = "";
flags += (value.disabled ? "D" : "-");
flags += (value.adminonly ? "A" : "-");
flags += (value.reservations ? "R" : "-");
flags += (value.datasets ? "d" : "-");
flags += (value.monitor ? "M" : "-");
value.flags = flags;
// Ratio
if (value.pcount) {
var pcount = parseInt(value.pcount);
var pfree = parseInt(value.pfree);
value.ratio = Math.round(((pcount - pfree) / pcount) * 100)
value.ratio = "" + value.ratio + "%";
}
else {
value.ratio = "0%";
}
});
var html = template({"status" : status,
"isadmin" : window.ISADMIN,
"isfadmin" : window.ISFADMIN});
$('#page-body').html(html);
// Format dates with moment before display.
$('.format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html())
.format("ddd MMM D h:mm A"));
}
});
$('.table-status')
.tablesorter({
theme : 'green',
// initialize zebra and filter widgets
widgets: ["zebra", "resizable"],
headers: {
0: {
sorter : "text",
}
},
sortList: [[1,1],[0,0]],
});
$('#flags-help').attr('data-content', flagshelp);
$('[data-toggle="popover"]').popover({
placement: 'auto',
html: true,
});
$('[data-toggle="tooltip"]').tooltip({
placement: 'auto',
});
}
$(document).ready(initialize);
});
......@@ -478,7 +478,7 @@ if (!$login_user->portal()) {
echo " </a></li>\n";
}
echo " <li><a href='dashboard.php'>DashBoard</a></li>";
echo " <li><a href='cluster-status.php'>Cluster Status</a></li>";
echo " <li><a href='aggregate-status.php'>Cluster Status</a></li>";
$then = time() - (14 * 3600 * 24);
echo " <li><a href='activity.php?min=$then'>
History Data</a></li>
......
......@@ -425,6 +425,11 @@ $routing = array("geni-login" =>
"guest" => false,
"methods" => array("HistoryRecord" =>
"Do_HistoryRecord")),
"aggregate-status" =>
array("file" => "aggregate-status.ajax",
"guest" => false,
"methods" => array("AggregateStatus" =>
"Do_AggregateStatus")),
);
#
......
<div class='row'>
<div class='col-sm-12'>
<table class="table table-condensed table-bordered table-status">
<thead>
<tr>
<th class="text-nowrap">Name</th>
<th>Status
<a href='#' class='btn btn-xs'
data-toggle='tooltip'
data-trigger='hover'
data-html="false"
data-delay='{"hide":100, "show":300}'
title='Click for cluster status details'>
<span class='glyphicon glyphicon-question-sign'
style='margin-bottom: 4px;'></span></a>
</th>
<th>Last Contact</th>
<th class="sorter-false">Flags
<a href='#' class='btn btn-xs' id="flags-help"
data-toggle='popover'
data-trigger='hover'
data-html="true"
data-delay='{"hide":100, "show":300}'
data-content=''>
<span class='glyphicon glyphicon-question-sign'
style='margin-bottom: 4px;'></span></a>
</th>
<th>% Full</th>
<th>Inuse</th>
<th>Total</th>
<th class="sorter-false">URN</th>
<th class="sorter-false">URL</th>
</tr>
</thead>
<tbody>
<% _.each(status, function(value, key) { %>
<tr>
<td><%- value.name %></td>
<td>
<% if (value.status == "down" && value.last_error != "") { %>
<span style="text-decoration: underline;"
data-toggle='popover'
data-trigger='hover'
data-delay='{"hide":100, "show":500}'
data-html='false'
data-content="<%- value.last_error%>"><%- value.status %>
</span>
<% } else if (value.status == "up") { %>
<a target="_blank"
href="cluster-status.php?cluster=<%- value.nickname %>">
<%- value.status %></a>
<% } else { %>
<%- value.status %></a>
<% } %>
</td>
<td class="format-date"><%- value.last_contact %></td>
<td><%- value.flags %></td>
<td><%- value.ratio %></td>
<td><%- value.pcount - value.pfree %></td>
<td><%- value.pcount %></td>
<td align="center">
<a href="#"
data-toggle='popover'
data-html='true'
data-trigger='click'
data-title="Aggregate URN"
data-content="<input type=text readonly=readonly
class=form-control
onClick='this.select();'
value='<%- value.urn %>'>">
<span class="glyphicon glyphicon-expand"></span>
</a>
</td>
<td align="center">
<% if (value.url != "") { %>
<a href="<%- value.url %>" target="_blank">
<span class="glyphicon glyphicon-link"></span></a>
<% } %>
</td>
</tr>
<% }); %>
</tbody>
</table>
</div>
</div>
......@@ -79,6 +79,9 @@
<div class='col-sm-7'>
<div class='panel panel-default' id='cluster-status-panel'>
<div class="panel-heading">
<a href="aggregate-status.php" target="_blank">
<span style="margin-right: 10px;"
class='glyphicon glyphicon-new-window pull-right'></span></a>
<h5><center>Cluster Status</center></h5>
</div>
<div class='panel-body panel-body-dashboard'>
......
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