Commit 59eed578 authored by Leigh Stoller's avatar Leigh Stoller

Portal version of Show Node. Also Show Vlan and List Vlans (which

includes members ad switch path).
parent e9a24fa8
<?php
#
# Copyright (c) 2000-2019 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("node_defs.php");
chdir("apt");
include("quickvm_sup.php");
# Must be after quickvm_sup.php since it changes the auth domain.
$page_title = "Node Console";
#
# Get current user.
#
RedirectSecure();
$this_user = CheckLoginOrRedirect();
$this_idx = $this_user->uid_idx();
$isadmin = (ISADMIN() ? "true" : "false");
#
# Verify page arguments.
#
$reqargs = RequiredPageArguments("node", PAGEARG_NODE);
if (!$node) {
SPITUSERERROR("No such node!");
}
$node_id = $node->node_id();
if (!($isadmin || $node->AccessCheck($this_user, $TB_NODEACCESS_LOADIMAGE))) {
SPITUSERERROR("Not enough permission!");
}
SPITHEADER(1);
#
# Get the tipline auto stuff to generate the auth object.
#
$query_result =
DBQueryFatal("SELECT server, portnum, keylen, keydata, disabled " .
"FROM tiplines WHERE node_id='$node_id'" );
if (mysql_num_rows($query_result) == 0) {
SPITUSERERROR("Node does not have a console line!");
}
$row = mysql_fetch_array($query_result);
$server = $row["server"];
$portnum = $row["portnum"];
$keylen = $row["keylen"];
$keydata = $row["keydata"];
$disabled= $row["disabled"];
if ($disabled) {
SPITUSERERROR("The tipline is currently disabled!");
}
#
# Read in the fingerprint of the capture certificate
#
$capfile = "$TBETC_DIR/capture.fingerprint";
$lines = file($capfile);
if (!$lines) {
TBERROR("Unable to open $capfile!", 1);
}
$fingerline = rtrim($lines[0]);
if (!preg_match("/Fingerprint=([\w:]+)$/",$fingerline,$matches)) {
TBERROR("Unable to find fingerprint in string $fingerline!",1);
}
$certhash = str_replace(":","",strtolower($matches[1]));
#
# Array of stuff that we need to create the auth object
#
$console = array();
$console["server"] = $server;
$console["portnum"] = $portnum;
$console["keylen"] = $keylen;
$console["keydata"] = $keydata;
$console["certhash"] = $certhash;
$console_auth = $node->ConsoleAuthObject($this_user, $console);
echo "<center>
<div id='console-div' ".
" style='width: 90%;'></div>";
echo " <button class='btn btn-danger btn-sm hidden'
style='margin-top: 15px;'
id='console-close'>
Close</button>
</center>\n";
echo "<script type='text/javascript'>\n";
echo " window.NODE_ID = '$node_id';\n";
echo " window.ISADMIN = $isadmin;\n";
echo "</script>\n";
echo "<script type='text/plain' id='auth-json'>\n";
echo $console_auth;
echo "</script>\n";
REQUIRE_UNDERSCORE();
REQUIRE_SUP();
SPITREQUIRE("js/console.js");
SPITFOOTER();
?>
$(function ()
{
'use strict';
var authjson = null;
var authobject = null;
function initialize()
{
window.APT_OPTIONS.initialize(sup);
authjson = _.unescape($('#auth-json')[0].textContent);
authobject = JSON.parse(authjson);
StartConsole();
}
function StartConsole()
{
var baseurl = authobject.baseurl;
var callback = function(json) {
console.info("StartConsole", json);
var split = json.split(':');
var session = split[0];
var port = split[1];
var url = baseurl + ':' + port + '/' + '#' +
encodeURIComponent(document.location.href) + ',' + session;
console.log(url);
// We create the console iframe inside the div.
var iwidth = "100%";
var iheight = 500;
$('#console-div').html('<iframe id="console_iframe" ' +
'width=' + iwidth + ' ' +
'height=' + iheight + ' ' +
'src=\'' + url + '\'>');
$('#console-close').removeClass("hidden");
var killme = function () {
var url = baseurl + ':' + port + '/quit' +
'?session=' + session;
console.log("killme: " + url);
$.ajax({
"url" : url,
"type" : 'GET',
});
};
// Install a click handler for the close button.
$("#console-close").click(function(e) {
e.preventDefault();
killme();
$("#console-close").off("click");
$(window).off("beforeunload");
});
// Use an unload event to terminate the console.
$(window).on("beforeunload", function() {
console.info("Unload function called");
killme();
});
};
var callback_failed = function(jqXHR, textStatus) {
var acceptURL = baseurl + '/accept_cert.html';
console.log("Request failed: ", jqXHR);
$('#console-div')
.html("An SSL certificate must be accepted by your " +
"browser to continue. Please click " +
"<a href='" + acceptURL + "'>here</a> " +
"to be redirected.");
}
var xmlthing = $.ajax({
// the URL for the request
url: baseurl + '/d77e8041d1ad',
// the data to send (will be converted to a query string)
data: {
auth: authjson,
},
// Needs to be a POST to send the auth object.
type: 'POST',
// Ask for plain text for easier parsing.
dataType : 'text',
});
xmlthing.done(callback);
xmlthing.fail(callback_failed);
}
$(document).ready(initialize);
});
$(function ()
{
'use strict';
var templates = APT_OPTIONS.fetchTemplateList(['list-vlans']);
var mainTemplate = _.template(templates['list-vlans']);
function initialize()
{
window.APT_OPTIONS.initialize(sup);
var args = null;
if (window.UUID !== undefined) {
args = {"uuid" : window.UUID};
}
sup.CallServerMethod(null, "vlan", "List", args,
function(json) {
console.info("list", json);
if (json.code) {
alert("Could not get vlan list " +
"from server: " + json.value);
return;
}
GeneratePageBody(json.value);
});
}
function GeneratePageBody(vlans)
{
// Generate the template.
var html = mainTemplate({
vlans: vlans,
isadmin: window.ISADMIN,
});
$('#main-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("lll"));
}
});
// This activates the popover subsystem.
$('[data-toggle="popover"]').popover({
trigger: 'hover',
});
// This activates the tooltip subsystem.
$('[data-toggle="tooltip"]').tooltip({
trigger: 'hover',
});
var table = $(".tablesorter")
.tablesorter({
theme : 'green',
widgets: ["filter"],
widgetOptions: {
// include child row content while filtering, if true
filter_childRows : true,
// include all columns in the search.
filter_anyMatch : true,
// class name applied to filter row and each input
filter_cssFilter : 'form-control',
// search from beginning
filter_startsWith : false,
// Set this option to false for case sensitive search
filter_ignoreCase : true,
// Only one search box.
filter_columnFilters : true,
}
});
}
$(document).ready(initialize);
});
$(function ()
{
'use strict';
var templates = APT_OPTIONS.fetchTemplateList(['show-node',
'oops-modal',
'waitwait-modal']);
var mainTemplate = _.template(templates['show-node']);
var formfields = null;
function JsonParse(id)
{
return JSON.parse(_.unescape($(id)[0].textContent));
}
function isEllipsisActive(e) {
return (e.offsetWidth < e.scrollWidth);
}
function initialize()
{
window.APT_OPTIONS.initialize(sup);
RegeneratePageBody();
}
var editbutton =
'<a href="#" class="pull-right edit-button" ' +
' style="margin-left: 5px;"> ' +
' <span class="glyphicon glyphicon-edit" ' +
' style="margin-top: 6px; font-size: 12px;" ' +
' data-toggle="tooltip" ' +
' data-trigger="hover" ' +
' title="Change current value"></span></a>';
var savebutton =
'<a href="#" class="save-button" ' +
' style="margin-left: 5px; font-size: 12px"> ' +
' <span class="glyphicon glyphicon-ok" ' +
' style="margin-top: 6px; font-size: 12px;" ' +
' data-toggle="tooltip" ' +
' data-trigger="hover" ' +
' title="Save new value"></span></a>';
var cancelbutton =
'<a href="#" class="cancel-button" ' +
' style="margin-left: 5px; font-size: 12px"> ' +
' <span class="glyphicon glyphicon-remove" ' +
' style="margin-top: 6px; font-size: 12px;" ' +
' data-toggle="tooltip" ' +
' data-trigger="hover" ' +
' title="Cancel"></span></a>';
function RegeneratePageBody()
{
sup.CallServerMethod(null, "node", "GetInfo",
{"node_id" : window.NODE_ID},
function(json) {
console.info("info", json);
if (json.code) {
alert("Could not get node info " +
"from server: " + json.value);
return;
}
GeneratePageBody(json.value);
});
}
function GeneratePageBody(fields)
{
formfields = fields;
// Generate the template.
var html = mainTemplate({
fields: fields,
isadmin: window.ISADMIN,
canedit: window.CANEDIT,
console: window.CONSOLE,
browserconsole: window.BROWSERCONSOLE,
"YesNo": function (val) { return (val ? "Yes" : "No"); },
});
$('#main-body').html(html);
// Now we can do this.
$('#oops_div').html(templates['oops-modal']);
$('#waitwait_div').html(templates['waitwait-modal']);
// Format dates with moment before display.
$('.format-date').each(function() {
var date = $.trim($(this).html());
if (date != "") {
$(this).html(moment($(this).html()).format("lll"));
}
});
// This activates the popover subsystem.
$('[data-toggle="popover"]').popover({
trigger: 'hover',
});
// This activates the tooltip subsystem.
$('[data-toggle="tooltip"]').tooltip({
trigger: 'hover',
});
// See https://stackoverflow.com/questions/21168521/table-fixed-header-and-scrollable-body
var $th = $('.table-fixed').find('thead th')
$('.table-fixed').on('scroll', function() {
$th.css('transform', 'translateY('+ this.scrollTop +'px)');
});
// Javascript to enable link to tab
if (document.location.hash) {
var hash = document.location.hash;
hash = hash.replace(/(:|\.|\[|\]|,)/g, "\\$1");
console.info(hash);
if ($(hash).length) {
var rowTop = $(hash).offset().top;
var rowPos = $(hash).position()
var tabTop = $(".table-fixed").offset().top;
console.info(rowTop, tabTop, rowPos);
// Scroll the wires table so its in view
$('body, html').animate({
scrollTop: $(".table-fixed").offset().top,
}, 500, 'linear');
$(hash).closest("tr").addClass("highlight");
$('.table-fixed').animate({
scrollTop: $(hash).position().top - 100,
}, 500, 'linear');
}
}
}
$(document).ready(initialize);
});
$(function ()
{
'use strict';
var templates = APT_OPTIONS.fetchTemplateList(['show-vlan']);
var mainTemplate = _.template(templates['show-vlan']);
function initialize()
{
window.APT_OPTIONS.initialize(sup);
sup.CallServerMethod(null, "vlan", "GetInfo",
{"vlan_id" : window.VLAN_ID},
function(json) {
console.info("info", json);
if (json.code) {
alert("Could not get vlan info " +
"from server: " + json.value);
return;
}
GeneratePageBody(json.value);
});
}
function GeneratePageBody(info)
{
// Generate the template.
var html = mainTemplate({
info: info,
});
$('#main-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("lll"));
}
});
// This activates the popover subsystem.
$('[data-toggle="popover"]').popover({
trigger: 'hover',
});
// This activates the tooltip subsystem.
$('[data-toggle="tooltip"]').tooltip({
trigger: 'hover',
});
}
$(document).ready(initialize);
});
<?php
#
# Copyright (c) 2000-2019 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");
chdir("apt");
include("quickvm_sup.php");
# Must be after quickvm_sup.php since it changes the auth domain.
$page_title = "List Vlans";
#
# Get current user.
#
RedirectSecure();
$this_user = CheckLoginOrRedirect();
$this_idx = $this_user->uid_idx();
if (!ISADMIN()) {
SPITUSERERROR("Not enough permission!");
}
$optargs = OptionalPageArguments("experiment", PAGEARG_EXPERIMENT);
SPITHEADER(1);
echo "<link rel='stylesheet'
href='css/tablesorter.css'>\n";
# Place to hang the toplevel template.
echo "<div id='main-body'></div>\n";
if (isset($experiment)) {
$uuid = $experiment->uuid();
echo "<script type='text/javascript'>\n";
echo " window.UUID = '$uuid';\n";
echo "</script>\n";
}
REQUIRE_UNDERSCORE();
REQUIRE_SUP();
REQUIRE_MOMENT();
SPITREQUIRE("js/list-vlans.js",
"<script src='js/lib/jquery.tablesorter.min.js'></script>".
"<script src='js/lib/jquery.tablesorter.widgets.min.js'></script>".
"<script src='js/lib/sugar.min.js'></script>".
"<script src='js/lib/jquery.tablesorter.parser-date.js'></script>");
AddTemplateList(array("list-vlans"));
SPITFOOTER();
?>
<?php
#
# Copyright (c) 2000-2019 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_once("webtask.php");
include_once("experiment_defs.php");
include_once("node_defs.php");
include_once("imageid_defs.php");
include_once("osinfo_defs.php");
chdir("apt");
#
# All functions take the node id.
#
$node = null;
function CheckPageArgs($write)
{
global $this_user, $ajax_args, $node;
global $TB_NODEACCESS_READINFO, $TB_NODEACCESS_MODIFYINFO;
if (!isset($ajax_args["node_id"])) {
SPITAJAX_ERROR(-1, "Missing node ID");
return -1;
}
$node_id = $ajax_args["node_id"];
if (!TBvalid_node_id($node_id)) {
SPITAJAX_ERROR(-1, "Invalid node ID");
return -1;
}
$node = Node::Lookup($node_id);
if (!$node) {
SPITAJAX_ERROR(-1, "No such node");
return -1;
}
if (ISADMIN()) {
return 0;
}
if (($write &&
! $node->AccessCheck($this_user, $TB_NODEACCESS_MODIFYINFO)) ||
! $node->AccessCheck($this_user, $TB_NODEACCESS_READINFO)) {
SPITAJAX_ERROR(-1, "Not enough permission");
return -1;
}
return 0;
}
#
# Get the info for a node.
#
function Do_GetInfo()
{
global $this_user, $ajax_args, $node;
global $TBBASE, $ISEMULAB, $TBMAINSITE, $OURDOMAIN;
if (CheckPageArgs(0)) {
return;
}
if ($node->def_boot_osid()) {
$def_boot_image = $node->def_boot_image();
}
$type_url = "$TBBASE/shownodetype.php3?node_type=" . $node->type();
$blob = array();
$blob["node_id"] = $node->node_id();
$blob["phys_nodeid"] = $node->phys_nodeid();
$blob["type"] = $node->type();
$blob["class"] = $node->TypeClass();
$blob["type_url"] = $type_url;
$blob["control_ip"] = $node->ControlIP();
$blob["management_ip"] = $node->ManagementIP();
$blob["eventstate"] = $node->eventstate();
$blob["op_mode"] = $node->op_mode();
$blob["role"] = $node->role();
$blob["hasconsole"] = $node->HasSerialConsole();
$blob["expinfo"] = GetExpInfo($node);
$blob["attributes"] = GetAttributes($node);
$blob["features"] = GetFeatures($node);
$blob["subbossinfo"] = $node->SubBossInfo();
if (isset($def_boot_image)) {
$imageid = $def_boot_image->imageid();
$version = $def_boot_image->version();
$url = "show-image.php?imageid=${imageid}&version=${version}";
$blob["def_boot_image_uuid"] = $def_boot_image->uuid();
$blob["def_boot_image_name"] = $def_boot_image->imagename();
$blob["def_boot_image_vers"] = $def_boot_image->version();
$blob["def_boot_image_url"] = $url;
if ($node->def_boot_cmd_line() && $node->def_boot_cmd_line() != "") {
$blob["def_boot_cmd_line"] = $node->def_boot_cmd_line();
}
}
if ($node->next_boot_osid()) {
$osid = $node->next_boot_osid();
$vers = $node->next_boot_osid_vers();
$osinfo = OSInfo::Lookup($osid, $vers);
if ($osinfo) {
$url = "$TBBASE/showosinfo.php?osid=${osid}&version=${vers}";
$blob["next_boot_osinfo_uuid"] = $osinfo->uuid();
$blob["next_boot_osinfo_name"] = $osinfo->osname();
$blob["next_boot_osinfo_vers"] = $osinfo->vers();
$blob["next_boot_osinfo_url"] = $url;
}
if ($node->next_boot_cmd_line() &&
$node->next_boot_cmd_line() != "") {
$blob["next_boot_cmd_line"] = $node->next_boot_cmd_line();
}
}
if ($node->temp_boot_osid()) {
$osid = $node->temp_boot_osid();
$vers = $node->temp_boot_osid_vers();
$osinfo = OSInfo::Lookup($osid, $vers);
if ($osinfo) {
$url = "$TBBASE/showosinfo.php?osid=${osid}&version=${vers}";
$blob["temp_boot_osinfo_uuid"] = $osinfo->uuid();
$blob["temp_boot_osinfo_name"] = $osinfo->osname();
$blob["temp_boot_osinfo_vers"] = $osinfo->vers();
$blob["temp_boot_osinfo_url"] = $url;
}
}
if ($node->pxe_boot_path() && $node->pxe_boot_path() != "") {
$blob["pxe_boot_path"] = $node->pxe_boot_path();
}
if ($node->next_pxe_boot_path() && $node->next_pxe_boot_path() != "") {
$blob["next_pxe_boot_path"] = $node->next_pxe_boot_path();
}
$blob["interfaces"] = $node->GetInterfaceInfo();
$blob["vinterfaces"] = $node->GetVinterfaces();
$blob["vlans"] = $node->GetVlans();
if (!$node->IsVirtNode()) {
$blob["vnodes"] = $node->GetVnodes();
}
SPITAJAX_RESPONSE($blob);
}
#
# Get the node attributes (minus root password)
#
function GetAttributes($node)