Commit 9257c82b authored by Leigh B Stoller's avatar Leigh B Stoller

Relocate the code that creates the holding project and group into GeniUtil,

since it is now needed from the blockstore (dataset) code.
parent 80b2d1b7
......@@ -122,7 +122,6 @@ my $IMAGE_SETUP = "$TB/sbin/image_setup";
my $SHAREVLAN = "$TB/sbin/sharevlan";
my $FWNAME = "fw";
my $API_VERSION = 1;
my $USELOCALPROJ = 0;
#
# Tell the client what API revision we support. The correspondence
......@@ -6040,8 +6039,7 @@ sub GeniExperiment($;$)
my $uuid = $slice->uuid();
my $urn = $slice->urn();
my ($pid, $gid, $eid);
my ($project, $group);
my $eid;
my $experiment = Experiment->Lookup($uuid);
return $experiment
......@@ -6050,194 +6048,15 @@ sub GeniExperiment($;$)
# The eid is derived from the slice urn.
(undef, undef, $eid) = GeniHRN::Parse($urn);
require Project;
require Group;
# Get the project and group.
my $group = GeniUtil::GetHoldingProject($urn, $creator);
return $group
if (GeniResponse::IsResponse($group));
#
# BUG: We need to check the sub auth chain to make sure that
# there the common prefix. Otherwise, a subsa could sign a
# slice credential for someone else.
#
#
# If the slice is from this Emulab (SA), then we are going to create the
# experiment in the local project.
#
if (GeniHRN::Authoritative($urn, $OURDOMAIN) && $USELOCALPROJ) {
#
# If no creator, this is a placeholder slice. Since its local
# we can come up with a creator, but later.
#
if (!defined($creator)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Cannot do local placeholder slices yet");
}
#
# For now, the creator has to be a local user and have their
# default project set. Until we have project signed credentials.
#
if (! $creator->IsLocal()) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"$creator is not a local user for local project");
}
if (!defined($creator->DefaultProject())) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"No default project for $creator");
}
$project = $creator->DefaultProject();
if (!defined($project)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not get local project for $slice");
}
# No sub groups for local projects. Maybe later?
$pid = $gid = $project->pid();
}
else {
#
# The top level domain of the SA becomes the project name, but the
# dots are illegal of course, and there might be sub authorities
# (colon separated). We use the primary for the project and the
# first sub-authority for the group.
#
my ($domain, undef, undef) = GeniHRN::Parse($urn);
my @tokens = split(":", $domain);
my $project_id = shift(@tokens);
my $group_id = shift(@tokens) if (@tokens);
my $project_urn = GeniHRN::Generate($project_id, "authority", "sa");
#
# See if the project exists.
#
$project = Project->LookupNonLocal($project_urn);
if (!defined($project)) {
#
# For now, lets assume that the domain has legal chars, except
# of course for the dots, which we transform to dashes cause
# underscores are not allowed in project ids.
#
$project_id =~ s/\./-/g;
if (!Project->ValidPID($project_id)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Cannot form a valid local project name from $project_urn");
}
my $project = $group->GetProject();
my $pid = $project->pid;
my $gid = $group->gid();
#
# Write out a little XML file describing the project, and
# let the existing backend script deal with it all.
#
my ($fh, $filename) = tempfile(UNLINK => 0);
if (!defined($fh)) {
print STDERR "Could not create temp file for $project_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
print $fh "<project>\n";
print $fh " <attribute name=\"name\">\n";
print $fh " <value>$project_id</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"short description\">\n";
print $fh " <value>$project_urn</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"nonlocal_id\">\n";
print $fh " <value>$project_urn</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"nonlocal_type\">\n";
print $fh " <value>protogeni</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"leader\">\n";
print $fh " <value>geniuser</value>\n";
print $fh " </attribute>\n";
print $fh "</project>\n";
close($fh);
if (! chmod(0755, $filename)) {
print STDERR "Could not chmod $filename\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
#
# This operation has to be done as an admin person.
#
GeniUtil::FlipToElabMan();
my $output = GeniUtil::ExecQuiet("$WAP $NEWPROJECT -l $filename");
if ($?) {
GeniUtil::FlipToGeniUser();
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating project description");
}
unlink($filename);
$output = GeniUtil::ExecQuiet("$WAP $MAKEPROJECT $project_id");
my $ecode = $?;
GeniUtil::FlipToGeniUser();
if ($ecode) {
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating project");
}
$project = Project->LookupNonLocal($project_urn);
if (!defined($project)) {
print STDERR "Cannot lookup new project for $project_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error locating project after creation");
}
}
$pid = $gid = $project->pid();
#
# If there is a sub authority, create a subgroup for it.
#
if (defined($group_id)) {
if (!Group->ValidGID($group_id)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid local group name $group_id");
}
$group = $project->LookupGroup($group_id);
if (!defined($group)) {
my $pid_idx = $project->pid_idx();
#
# Write out a little XML file describing the group, and
# let the existing backend script deal with it all.
#
my ($fh, $filename) = tempfile(UNLINK => 0);
if (!defined($fh)) {
print STDERR "Could not create temp file for group $group_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
print $fh "<group>\n";
print $fh " <attribute name=\"project\">\n";
print $fh " <value>$pid_idx</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_id\">\n";
print $fh " <value>$group_id</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_leader\">\n";
print $fh " <value>geniuser</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_description\">\n";
print $fh " <value></value>\n";
print $fh " </attribute>\n";
print $fh "</group>\n";
close($fh);
my $output = GeniUtil::ExecQuiet("$NEWGROUP $filename");
if ($?) {
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating group");
}
unlink($filename);
$group = $project->LookupGroup($group_id);
if (!defined($group)) {
print STDERR "Cannot lookup new group for $group_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error locating group after creation");
}
}
$gid = $group->gid();
}
}
#
# Form an eid for the experiment.
#
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# Copyright (c) 2008-2014 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -39,7 +39,12 @@ use vars qw(@ISA @EXPORT);
use English;
use Data::Dumper;
use XML::Simple;
use File::Temp qw(tempfile);
use POSIX qw(strftime);
use Date::Parse;
use Time::Local;
use GeniHRN;
use GeniResponse;
# Configure variables
my $TB = "@prefix@";
......@@ -53,6 +58,12 @@ my $GENIUSER = "geniuser";
my $GENIGROUP = "GeniSlices";
my $PROTOUSER = "elabman";
my $PROTOPROJ = "emulab-ops";
my $USELOCALPROJ = 0;
my $SUDO = "/usr/local/bin/sudo";
my $WAP = "$TB/sbin/withadminprivs";
my $NEWGROUP = "$TB/bin/newgroup";
my $NEWPROJECT = "$TB/sbin/newproj";
my $MAKEPROJECT = "$TB/sbin/mkproj";
use vars qw($EXTENSIONS_NS $XSI_NS $EXTENSIONS_PREFIX $EXTENSIONS_SCHEMA_LOCATION $CREDENTIAL_SCHEMA_LOCATION);
#Extensions namespace URI.
......@@ -220,5 +231,198 @@ sub ExecQuiet($)
return $output;
}
#
# Lookup and create project and group for a given SA domain.
# Return the group, the caller can get the project from it.
#
sub GetHoldingProject($$)
{
my ($urn, $creator) = @_;
my ($project, $group);
require Project;
require Group;
#
# If the slice is from this Emulab (SA), then we are going to create the
# experiment in the local project.
#
if (GeniHRN::Authoritative($urn, $OURDOMAIN) && $USELOCALPROJ) {
#
# If no creator, this is a placeholder slice. Since its local
# we can come up with a creator, but later.
#
if (!defined($creator)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Cannot do local placeholder slices yet");
}
#
# For now, the creator has to be a local user and have their
# default project set. Until we have project signed credentials.
#
if (! $creator->IsLocal()) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"$creator is not a local user for local project");
}
if (!defined($creator->DefaultProject())) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"No default project for $creator");
}
$project = $creator->DefaultProject();
if (!defined($project)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not get local project for slice");
}
# No sub groups for local projects. Maybe later?
$group = $project->GetProjectGroup();
}
else {
#
# The top level domain of the SA becomes the project name, but the
# dots are illegal of course, and there might be sub authorities
# (colon separated). We use the primary for the project and the
# first sub-authority for the group.
#
my ($domain, undef, undef) = GeniHRN::Parse($urn);
my @tokens = split(":", $domain);
my $project_id = shift(@tokens);
my $group_id = shift(@tokens) if (@tokens);
my $project_urn = GeniHRN::Generate($project_id, "authority", "sa");
#
# See if the project exists.
#
$project = Project->LookupNonLocal($project_urn);
if (!defined($project)) {
#
# For now, lets assume that the domain has legal chars, except
# of course for the dots, which we transform to dashes cause
# underscores are not allowed in project ids.
#
$project_id =~ s/\./-/g;
if (!Project->ValidPID($project_id)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Cannot form a valid local project name from $project_urn");
}
#
# Write out a little XML file describing the project, and
# let the existing backend script deal with it all.
#
my ($fh, $filename) = tempfile(UNLINK => 0);
if (!defined($fh)) {
print STDERR "Could not create temp file for $project_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
print $fh "<project>\n";
print $fh " <attribute name=\"name\">\n";
print $fh " <value>$project_id</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"short description\">\n";
print $fh " <value>$project_urn</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"nonlocal_id\">\n";
print $fh " <value>$project_urn</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"nonlocal_type\">\n";
print $fh " <value>protogeni</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"leader\">\n";
print $fh " <value>geniuser</value>\n";
print $fh " </attribute>\n";
print $fh "</project>\n";
close($fh);
if (! chmod(0755, $filename)) {
print STDERR "Could not chmod $filename\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
#
# This operation has to be done as an admin person.
#
GeniUtil::FlipToElabMan();
my $output = GeniUtil::ExecQuiet("$WAP $NEWPROJECT -l $filename");
if ($?) {
GeniUtil::FlipToGeniUser();
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating project description");
}
unlink($filename);
$output = GeniUtil::ExecQuiet("$WAP $MAKEPROJECT $project_id");
my $ecode = $?;
GeniUtil::FlipToGeniUser();
if ($ecode) {
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating project");
}
$project = Project->LookupNonLocal($project_urn);
if (!defined($project)) {
print STDERR "Cannot lookup new project for $project_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error locating project after creation");
}
}
$group = $project->GetProjectGroup();
#
# If there is a sub authority, create a subgroup for it.
#
if (defined($group_id)) {
if (!Group->ValidGID($group_id)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid local group name $group_id");
}
$group = $project->LookupGroup($group_id);
if (!defined($group)) {
my $pid_idx = $project->pid_idx();
#
# Write out a little XML file describing the group, and
# let the existing backend script deal with it all.
#
my ($fh, $filename) = tempfile(UNLINK => 0);
if (!defined($fh)) {
print STDERR "Could not create temp file for group $group_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
print $fh "<group>\n";
print $fh " <attribute name=\"project\">\n";
print $fh " <value>$pid_idx</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_id\">\n";
print $fh " <value>$group_id</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_leader\">\n";
print $fh " <value>geniuser</value>\n";
print $fh " </attribute>\n";
print $fh " <attribute name=\"group_description\">\n";
print $fh " <value></value>\n";
print $fh " </attribute>\n";
print $fh "</group>\n";
close($fh);
my $output = GeniUtil::ExecQuiet("$NEWGROUP $filename");
if ($?) {
print STDERR $output;
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error creating group");
}
unlink($filename);
$group = $project->LookupGroup($group_id);
if (!defined($group)) {
print STDERR "Cannot lookup new group for $group_id\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Internal error locating group after creation");
}
}
}
}
return $group;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
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