Commit 7564c408 authored by Leigh Stoller's avatar Leigh Stoller

Improvements to admin extend:

1. Provide text box to add to email message that is sent to user.

2. Track outstanding admin required requests, add a Deny button for those.

3. Add option to experiment listing for admins, to see outstanding admin
   required approval.
parent cfd5b9e8
......@@ -104,6 +104,7 @@ class Instance
function extension_reason() { return $this->field('extension_reason'); }
function extension_history() { return $this->field('extension_history'); }
function extension_lockout() { return $this->field('extension_adminonly'); }
function extension_requested(){return $this->field('extension_requested');}
function physnode_count() { return $this->field('physnode_count'); }
function virtnode_count() { return $this->field('virtnode_count'); }
function servername() { return $this->field('servername'); }
......@@ -357,6 +358,15 @@ class Instance
"where uuid='$uuid'");
}
function SetExtensionRequested($value)
{
$uuid = $this->uuid();
DBQueryWarn("update apt_instances set ".
" extension_requested='$value' ".
"where uuid='$uuid'");
}
function AddExtensionHistory($text)
{
$uuid = $this->uuid();
......
......@@ -29,6 +29,16 @@ define(['underscore', 'js/quickvm_sup',
event.preventDefault();
RequestExtension();
});
if (isadmin) {
$('#howlong_extend').change(function() {
EnableSubmitButton();
});
// Button handler.
$('button#deny-extension').click(function (event) {
event.preventDefault();
DenyExtension();
});
}
/*
* If the modal contains the slider, set it up.
......@@ -61,16 +71,18 @@ define(['underscore', 'js/quickvm_sup',
/*
* Countdown for text box.
*/
$('#why_extend').on('focus keyup', function (e) {
UpdateCountdown();
});
// Clear existing text.
$('#why_extend').val('');
// Current usage.
if (physnode_count) {
$("#extend_usage").removeClass("hidden");
$('#current_usage').val(Math.round(physnode_hours));
$('#future_usage').val(Math.round(physnode_count * 24));
if (! isadmin) {
$('#why_extend').on('focus keyup', function (e) {
UpdateCountdown();
});
// Clear existing text.
$('#why_extend').val('');
// Current usage.
if (physnode_count) {
$("#extend_usage").removeClass("hidden");
$('#current_usage').val(Math.round(physnode_hours));
$('#future_usage').val(Math.round(physnode_count * 24));
}
}
}
......@@ -283,6 +295,7 @@ define(['underscore', 'js/quickvm_sup',
if (isadmin) {
howlong = $("#howlong_extend").val();
reason = $("#extend_message").val();
}
else {
if (howlong == null) {
......@@ -326,6 +339,30 @@ define(['underscore', 'js/quickvm_sup',
return;
});
}
function DenyExtension()
{
var message = $("#extend_message").val();
sup.HideModal('#extend_modal');
if (!isadmin) {
return;
}
var deny_callback = function(json) {
sup.HideModal("#waitwait-modal");
if (json.code) {
sup.SpitOops("oops", "Failed to Deny: " + json.value);
return;
}
}
sup.ShowModal("#waitwait-modal");
var xmlthing = sup.CallServerMethod(null,
"status",
"DenyExtension",
{"uuid" : uuid,
"message" : message});
xmlthing.done(deny_callback);
}
function EnableSubmitButton()
{
......@@ -345,7 +382,7 @@ define(['underscore', 'js/quickvm_sup',
}
}
return function(thisuuid, func, admin, guest, extendfor,
url, pcount, phours)
url, needapproval, pcount, phours)
{
isadmin = admin;
isguest = guest;
......@@ -353,6 +390,8 @@ define(['underscore', 'js/quickvm_sup',
callback = func;
physnode_count = pcount;
physnode_hours = phours;
console.info(needapproval);
$('#extend_div').html(isadmin ?
adminExtendString : isguest ?
......@@ -362,8 +401,14 @@ define(['underscore', 'js/quickvm_sup',
// some of the content, since we need to know its width.
$(modalname).on('shown.bs.modal', function (e) {
Initialize();
if (extendfor && isadmin) {
$("#howlong_extend").val(extendfor);
if (admin) {
if (extendfor) {
$("#howlong_extend").val(extendfor);
EnableSubmitButton();
}
else {
DisableSubmitButton();
}
}
if ($('#extension_reason').length) {
$("#why_extend").val($('#extension_reason').val());
......@@ -376,6 +421,9 @@ define(['underscore', 'js/quickvm_sup',
if (admin && url) {
$("#extend_graphs_img").attr("src", url);
}
if (admin && needapproval) {
$("#deny-extension").removeClass("hidden");
}
$(modalname).off('shown.bs.modal');
});
$(modalname).modal('show');
......
......@@ -156,6 +156,7 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
event.preventDefault();
ShowExtendModal(uuid, RequestExtensionCallback, isadmin,
isguest, null, window.APT_OPTIONS.freenodesurl,
window.APT_OPTIONS.extension_requested,
window.APT_OPTIONS.physnode_count,
window.APT_OPTIONS.physnode_hours);
});
......@@ -302,6 +303,7 @@ function (_, sup, moment, marked, UriTemplate, ShowImagingModal,
ShowExtendModal(uuid, RequestExtensionCallback, isadmin, isguest,
window.APT_OPTIONS.extend,
window.APT_OPTIONS.freenodesurl,
window.APT_OPTIONS.extension_requested,
window.APT_OPTIONS.physnode_count,
window.APT_OPTIONS.physnode_hours);
}
......
......@@ -35,10 +35,16 @@ $dblink = GetDBLink("sa");
# Verify page arguments.
#
$optargs = OptionalPageArguments("target_user", PAGEARG_USER,
"all", PAGEARG_BOOLEAN);
"all", PAGEARG_BOOLEAN,
"extend", PAGEARG_BOOLEAN);
if (!isset($all)) {
$all = 0;
}
# Admin only.
if (!isset($extend)) {
$extend = 0;
}
#
# Get current user.
#
......@@ -66,7 +72,11 @@ echo "<link rel='stylesheet'
$query_result1 = null;
$query_result2 = null;
if ($all && ISADMIN()) {
if (($all || $extend) && ISADMIN()) {
$where = "";
if ($extend) {
$where = "where a.extension_requested=1";
}
$query_result1 =
DBQueryFatal("select a.*,s.expires,s.hrn,u.email, ".
" (UNIX_TIMESTAMP(now()) > ".
......@@ -86,7 +96,7 @@ if ($all && ISADMIN()) {
"left join geni.geni_slices as s on ".
" s.uuid=a.slice_uuid ".
"left join geni.geni_users as u on u.uuid=a.creator_uuid ".
"order by a.creator");
"$where order by a.creator");
}
else {
$query_result1 =
......@@ -263,11 +273,19 @@ echo "<div class='row'>
col-xs-12 col-xs-offset-0'>\n";
if (mysql_num_rows($query_result1) == 0) {
$message = "<b>No experiments to show you. Maybe you want to ".
"<a href='instantiate.php'>start one?</a></b><br>";
$message = "<b>No experiments to show you.</b> ";
if (! ($all || $extend)) {
$message .= "Maybe you want to ".
"<b><a href='instantiate.php'>start one?</a></b><br>";
}
echo $message;
}
else {
if (ISADMIN() && !$extend) {
echo "<a href='myexperiments.php?extend=1'>
Show Outstanding Extensions Requests</a><br>";
}
SPITROWS($all, "table1", $query_result1);
}
if ($query_result2 && mysql_num_rows($query_result2)) {
......
......@@ -84,6 +84,8 @@ $routing = array("myprofiles" =>
"Do_ConsoleURL",
"RequestExtension" =>
"Do_RequestExtension",
"DenyExtension" =>
"Do_DenyExtension",
"SnapShot" =>
"Do_Snapshot",
"SnapshotStatus" =>
......
......@@ -303,7 +303,10 @@ function Do_RequestExtension()
SPITAJAX_ERROR(1, "Must be an integer 1 <= days <= 365");
goto bad;
}
$reason = "Extended by site administrator";
$reason = "Your experiment was extended by the site administrator.\n";
if (isset($ajax_args["reason"]) && $ajax_args["reason"] != "") {
$reason .= "\n" . $ajax_args["reason"];
}
}
else {
if (!isset($ajax_args["reason"]) || $ajax_args["reason"] == "") {
......@@ -448,9 +451,11 @@ function Do_RequestExtension()
$instance->SendEmail($creator->email(),
"Experiment Extension: $uuid",
"A request to extend your experiment was made and ".
"granted.\n".
"Your reason was:\n\n". $reason . "\n\n".
(ISADMIN() ? $reason :
"A request to extend your experiment was made and ".
"granted.\n".
"Your reason was:\n\n". $reason) .
"\n\n".
"Your experiment was started on $created\n".
"Your experiment will now expire at $new_expires\n".
"It is running on $cluster\n\n\n".
......@@ -465,6 +470,9 @@ function Do_RequestExtension()
if (! ISADMIN()) {
$instance->SetExtensionReason($reason);
}
else {
$instance->SetExtensionRequested(1);
}
$instance->BumpExtensionCount($granted);
}
elseif ($retval > 0) {
......@@ -481,6 +489,67 @@ delay:
sleep(1);
}
#
# Deny extension,
#
function Do_DenyExtension()
{
global $instance, $creator, $this_user, $suexec_output;
global $ajax_args;
global $TBMAIL_OPS, $APTMAIL, $EXTENSIONS, $APTBASE;
$reason = "";
$message = "";
if (StatusSetupAjax(1)) {
goto bad;
}
$uuid = $instance->uuid();
$slice = GeniSlice::Lookup("sa", $instance->slice_uuid());
if (!slice) {
SPITAJAX_ERROR(1, "no slice for instance");
goto bad;
}
if (!ISADMIN()) {
SPITAJAX_ERROR(1, "You do not have permission to do this.");
goto bad;
}
$reason = "Your extension was denied by the site administrator!\n";
if (isset($ajax_args["message"]) && $ajax_args["message"] != "") {
$reason .= "\n" . $ajax_args["message"];
}
$expires = date("Y-m-d H:i:s T", strtotime($slice->expires()));
$created = date("Y-m-d H:i:s T", strtotime($instance->created()));
$now = date("Y-m-d H:i:s T", time());
#
# We store each extension request in an ongoing text field.
#
$text =
"Date: $now\n".
"Expires: $expires\n".
"Reason:\n".
$reason . "\n\n".
"-----------------------------------------------\n";
$instance->AddExtensionHistory($text);
$instance->SendEmail($creator->email(),
"Experiment Extension Denied: $uuid",
$reason .
"\n\n".
"Your experiment was started on $created\n".
"Your experiment expires at $expires\n".
"$APTBASE/status.php?uuid=$uuid\n",
"From: $EXTENSIONS\n" .
"BCC: $EXTENSIONS");
$instance->SetExtensionRequested(0);
SPITAJAX_RESPONSE("Success");
bad:
delay:
sleep(1);
}
#
# Helper for above.
#
......@@ -517,6 +586,7 @@ function needAdminApproval($wanted, $granted, $reason, $message)
$instance->SetExtensionReason($reason);
$instance->BumpExtensionCount($granted);
$instance->SetExtensionRequested(1);
# XXX
SPITAJAX_ERROR(2, "Your request requires admininstrator approval".
......
......@@ -219,6 +219,8 @@ echo " window.APT_OPTIONS.dossh = $dossh;\n";
echo " window.APT_OPTIONS.publicURL = $public_url;\n";
echo " window.APT_OPTIONS.lockdown = $lockdown;\n";
echo " window.APT_OPTIONS.lockout = $lockout;\n";
echo " window.APT_OPTIONS.extension_requested = " .
$instance->extension_requested() . ";\n";
echo " window.APT_OPTIONS.AJAXURL = 'server-ajax.php';\n";
echo " window.APT_OPTIONS.physnode_count = " .
$instance->physnode_count() . ";\n";
......
......@@ -9,10 +9,10 @@
<div class='row'>
<div class='col-sm-12'>
<form id='extend_request_form' role='form'>
<center><h4>How many Days? Default is 1 day</h4></center>
<center><h4>How many Days?</h4></center>
<div class='row'>
<div class='col-sm-2 col-sm-offset-5'>
<input id='howlong_extend' type='text' placeholder='1'
<input id='howlong_extend' type='text'
class='form-control'>
</div>
</div>
......@@ -47,9 +47,22 @@
</div>
<br>
</div>
<button class='btn btn-primary btn-sm align-center'
id='request-extension'
type='submit' name='request'>Extend</button>
<center>
Message to send to user
<br>
<textarea id='extend_message'
class='form-control'
rows=5></textarea>
<br>
<button class='btn btn-danger btn-sm hidden'
style='margin-right: 20px;'
id='deny-extension'
type='submit' name='request'>Deny</button>
<button class='btn btn-primary btn-sm'
id='request-extension'
type='submit' name='request'>Extend</button>
</center>
</div>
</form>
</div>
</div>
......
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