Commit 7da77590 authored by Leigh B Stoller's avatar Leigh B Stoller

Add project option to list historical reservations for the project.

parent 2a9160f0
......@@ -1069,33 +1069,55 @@ sub DoPrediction()
#
sub DoHistory()
{
my $optlist = "";
my $portal;
my $optlist = "p";
my $isproj = 0;
my $errmsg;
my $blob = {};
my ($user, $geniuser);
my $blob = {};
my $args = {};
my ($user, $geniuser, $project);
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"p"})) {
$isproj++;
}
usage()
if (@ARGV > 1);
# Argument is a target user.
if (@ARGV) {
$user = User->Lookup($ARGV[0]);
if (!defined($user)) {
fatal("No such user");
if ($isproj) {
$project = Project->Lookup($ARGV[0]);
if (!defined($project)) {
fatal("No such project");
}
if (!$this_user->IsAdmin() &&
!$project->AccessCheck($this_user, TB_PROJECT_READINFO())) {
fatal("No permission to access project reservation history")
}
}
if (!$this_user->IsAdmin() && !$this_user->SameUser($user)) {
fatal("No permission to access reservation history for $user")
else {
$user = User->Lookup($ARGV[0]);
if (!defined($user)) {
fatal("No such user");
}
if (!$this_user->IsAdmin() && !$this_user->SameUser($user)) {
fatal("No permission to access reservation history for $user")
}
$geniuser = GeniUser->CreateFromLocal($user);
}
$geniuser = GeniUser->CreateFromLocal($user);
}
else {
$geniuser = GeniUser->CreateFromLocal($this_user);
}
if ($isproj) {
$args = {"project_urn" => $project->urn()->asString()};
}
else {
$args = {"user_urn" => $geniuser->urn()->asString()};
}
if ($aggregate->CheckStatus(\$errmsg, 1)) {
UserError($errmsg);
......@@ -1104,14 +1126,16 @@ sub DoHistory()
# PortalRPC will use the root context in this case, which is
# essentially saying the caller is an admin. But thats okay
# for this call, it is just informational.
my $response =
APT_Geni::PortalRPC($authority, undef,
"ReservationHistory",
{"user_urn" => $geniuser->urn()->asString()});
"ReservationHistory", $args);
if (GeniResponse::IsError($response)) {
ExitWithError($response);
}
print Dumper($response);
#
# Munge the return value like we do above, converting user/proj
......@@ -1123,8 +1147,9 @@ sub DoHistory()
foreach my $res (@reslist) {
my $userhrn = GeniHRN->new($res->{'user'});
my $geniuser = MapUserURN($userhrn);
if ($userhrn->domain() eq $OURDOMAIN &&
$userhrn->id eq $geniuser->uid()) {
($isproj || $userhrn->id eq $geniuser->uid())) {
$res->{'remote_uid'} = $res->{'uid'};
$res->{'uid'} = $geniuser->uid();
$res->{'uid_idx'} = $geniuser->idx();
......@@ -1148,7 +1173,6 @@ sub DoHistory()
# We need numbers.
$res->{'nodes'} = int($res->{'nodes'});
$res->{'using'} = int($res->{'using'});
# Backwards compat
if (!exists($res->{'nodes'})) {
......
......@@ -63,6 +63,7 @@ use POSIX qw(strftime);
use Time::Local;
use File::Temp qw(tempfile tmpnam);
use Project;
use User;
use NodeType;
use Node;
......@@ -1681,27 +1682,56 @@ sub ReservationHistory($)
{
my ($argref) = @_;
my @history = ();
my @reservations;
my $hasperm = CheckPermission(1);
return $hasperm
if (GeniResponse::IsError($hasperm));
return GeniResponse->MalformedArgsResponse("Missing user URN")
if (!exists($argref->{'user_urn'}));
return GeniResponse->MalformedArgsResponse("Invalid user URN")
if (!GeniHRN::IsValid($argref->{'user_urn'}));
return GeniResponse->MalformedArgsResponse("Missing target URN")
if (! (exists($argref->{'user_urn'}) ||
exists($argref->{'project_urn'})));
if (exists($argref->{'user_urn'})) {
return GeniResponse->MalformedArgsResponse("Invalid user URN")
if (!GeniHRN::IsValid($argref->{'user_urn'}));
# User may not exist, which is okay.
my $geniuser = GeniUser->Lookup($argref->{'user_urn'}, 1);
goto nohistory
if (!defined($geniuser));
# Collect historical reservations.
@reservations =
Reservation->HistoricalReservations(undef,
$geniuser->emulab_user(),
undef);
}
else {
my $project;
# User may not exist, which is okay.
my $geniuser = GeniUser->Lookup($argref->{'user_urn'}, 1);
goto nohistory
if (!defined($geniuser));
return GeniResponse->MalformedArgsResponse("Invalid project URN")
if (!GeniHRN::IsValid($argref->{'project_urn'}));
#
# Collect historical reservations.
#
my @reservations =
Reservation->HistoricalReservations(undef,
$geniuser->emulab_user(), undef);
my $hrn = GeniHRN->new($argref->{'project_urn'});
if ($hrn->domain() eq $OURDOMAIN) {
$project = Project->Lookup($hrn->id());
}
else {
#
# We got a project URN but we need to lookup using the SA urn.
#
my $purn = GeniHRN::Generate($hrn->authority(), "authority", "sa");
$project = Project->LookupNonLocal($purn);
}
# Project may not exist, which is okay.
goto nohistory
if (!defined($project));
# Collect historical reservations.
@reservations =
Reservation->HistoricalReservations($project, undef, undef);
}
foreach my $res (@reservations) {
my $pid = $res->pid();
......@@ -1712,6 +1742,9 @@ sub ReservationHistory($)
next;
}
my $projurn = $project->nonlocalurn();
# Need the user for each res.
my $user = User->Lookup($res->uid_idx());
my @timeline = ResUtil::CreateTimeline($project, $res);
# We do not want to send back more then we need.
......@@ -1727,8 +1760,8 @@ sub ReservationHistory($)
$blob->{"uuid"} = $res->uuid() || "";
$blob->{"project"} = $projurn;
$blob->{"pid"} = $pid;
$blob->{"user"} = $geniuser->emulab_user()->nonlocalurn();
$blob->{"uid"} = $geniuser->emulab_user()->uid();
$blob->{"user"} = $user->nonlocalurn();
$blob->{"uid"} = $user->uid();
$blob->{"nodes"} = $res->nodes();
$blob->{"type"} = $res->type();
$blob->{"created"} = TBDateStringGMT($res->created());
......
......@@ -70,7 +70,7 @@ $(function ()
"showcontrols" : false,
"showproject" : true,
"showactivity" : false,
"showuser" : false,
"showuser" : (window.UID !== undefined ? false : true),
"showusing" : false,
"showstatus" : false,
"name" : name,
......@@ -124,10 +124,16 @@ $(function ()
});
$('#' + name).removeClass("hidden");
}
var args = {"cluster" : name};
if (window.UID !== undefined) {
args["uid"] = window.UID;
}
else {
args["pid"] = window.PID;
}
var xmlthing = sup.CallServerMethod(null, "reserve",
"ReservationHistory",
{"cluster" : name,
"uid" : window.UID});
"ReservationHistory", args);
xmlthing.done(callback);
});
}
......
......@@ -40,21 +40,29 @@ $isadmin = (ISADMIN() ? 1 : 0);
# Verify page arguments. Cluster is a domain that we turn into a URN.
#
$optargs = OptionalPageArguments("cluster", PAGEARG_STRING,
"target_user", PAGEARG_USER);
"target_user", PAGEARG_USER,
"target_project", PAGEARG_PROJECT);
if (! isset($target_user)) {
$target_user = $this_user;
if (isset($target_project)) {
$target_pid = $target_project->pid();
if (!$isadmin && !ISFOREIGN_ADMIN() &&
!$target_project->AccessCheck($this_user, $TB_PROJECT_READINFO)) {
SPITUSERERROR("You do not have permission to view this information!");
return;
}
}
$target_uid = $target_user->uid();
else {
if (! isset($target_user)) {
$target_user = $this_user;
}
$target_uid = $target_user->uid();
#
# Verify that this uid is a member of one of the projects that the
# target_uid is in. Must have proper permission in that group too.
#
if (!$isadmin && !ISFOREIGN_ADMIN() &&
!$target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
SPITUSERERROR("You do not have permission to view this information!");
return;
if (!$isadmin && !ISFOREIGN_ADMIN() &&
!$target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
SPITUSERERROR("You do not have permission to view this information!");
return;
}
}
SPITHEADER(1);
......@@ -98,7 +106,12 @@ echo "<div id='main-body'></div>\n";
echo "<script type='text/javascript'>\n";
echo " window.ISADMIN = $isadmin;\n";
echo " window.UID = '$target_uid';\n";
if (isset($target_project)) {
echo " window.PID = '$target_pid';\n";
}
else {
echo " window.UID = '$target_uid';\n";
}
echo "</script>\n";
REQUIRE_UNDERSCORE();
......
......@@ -830,26 +830,49 @@ function Do_ReservationHistory()
SPITAJAX_ERROR(-1, "No such cluster");
return;
}
if (!isset($ajax_args["uid"])) {
SPITAJAX_ERROR(-1, "Missing target uid");
if (! (isset($ajax_args["uid"]) || isset($ajax_args["pid"]))) {
SPITAJAX_ERROR(-1, "Missing target argument");
return -1;
}
$uid = $ajax_args["uid"];
if (isset($ajax_args["uid"])) {
$uid = $ajax_args["uid"];
if (!TBvalid_uid($uid)) {
SPITAJAX_ERROR(-1, "Invalid target uid");
return -1;
}
$target_user = User::Lookup($uid);
if (!$target_user) {
sleep(2);
SPITAJAX_ERROR(-1, "Unknown target uid");
return -1;
}
if (!ISADMIN() && !ISFOREIGN_ADMIN() &&
!$target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
SPITAJAX_ERROR(-1, "Not enough permission");
return -1;
if (!TBvalid_uid($uid)) {
SPITAJAX_ERROR(-1, "Invalid target uid");
return -1;
}
$target_user = User::Lookup($uid);
if (!$target_user) {
sleep(2);
SPITAJAX_ERROR(-1, "Unknown target uid");
return -1;
}
if (!ISADMIN() && !ISFOREIGN_ADMIN() &&
!$target_user->AccessCheck($this_user, $TB_USERINFO_READINFO)) {
SPITAJAX_ERROR(-1, "Not enough permission");
return -1;
}
$args = $target_user->uid();
}
else {
$pid = $ajax_args["pid"];
if (!TBvalid_pid($pid)) {
SPITAJAX_ERROR(-1, "Invalid target pid");
return -1;
}
$target_project = Project::Lookup($pid);
if (!$target_project) {
sleep(2);
SPITAJAX_ERROR(-1, "Unknown target pid");
return -1;
}
if (!ISADMIN() && !ISFOREIGN_ADMIN() &&
!$target_project->AccessCheck($this_user, $TB_PROJECT_READINFO)) {
SPITAJAX_ERROR(-1, "Not enough permission");
return -1;
}
$args = "-p " . $target_project->pid();
}
$this_uid = $this_user->uid();
$urn = $aggregate->urn();
......@@ -858,7 +881,7 @@ function Do_ReservationHistory()
$retval = SUEXEC($this_uid, "nobody",
"webmanage_reservations -a '$urn' ".
" -t $webtask_id history $uid",
" -t $webtask_id history $args",
SUEXEC_ACTION_IGNORE);
if ($retval) {
$webtask->Refresh();
......
......@@ -80,6 +80,8 @@
Create Reservation</a></li>
<li><a href="activity.php?project=<%= target_project %>">
Experiment History</a></li>
<li><a href="reservation-history.php?project=<%= target_project %>">
Reservation History</a></li>
<li role="presentation">
<a href='<%- emulablink %>'>
Emulab Project Page</a></li>
......
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