Commit 8c6bae5a authored by Leigh B. Stoller's avatar Leigh B. Stoller

Checkpoint

parent 3aa90d6b
...@@ -24,6 +24,7 @@ use GeniResponse; ...@@ -24,6 +24,7 @@ use GeniResponse;
use User; use User;
use GeniUser; use GeniUser;
use GeniSlice; use GeniSlice;
use GeniComponent;
use libtestbed; use libtestbed;
use emutil; use emutil;
use English; use English;
...@@ -84,7 +85,8 @@ sub LookupSlice($) ...@@ -84,7 +85,8 @@ sub LookupSlice($)
# Return a blob. # Return a blob.
my $blob = { "hrn" => $slice->hrn(), my $blob = { "hrn" => $slice->hrn(),
"uuid" => $slice->uuid(), "uuid" => $slice->uuid(),
"creator_uuid" => $slice->creator_uuid() }; "creator_uuid" => $slice->creator_uuid(),
"cert" => $slice->cert() };
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob); return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
} }
...@@ -197,6 +199,7 @@ sub RegisterSlice($) ...@@ -197,6 +199,7 @@ sub RegisterSlice($)
my $hrn = $argref->{'hrn'}; my $hrn = $argref->{'hrn'};
my $uuid = $argref->{'uuid'}; my $uuid = $argref->{'uuid'};
my $creator_uuid = $argref->{'creator_uuid'}; my $creator_uuid = $argref->{'creator_uuid'};
my $cert = $argref->{'cert'};
if (! (defined($hrn) && defined($uuid) && defined($creator_uuid))) { if (! (defined($hrn) && defined($uuid) && defined($creator_uuid))) {
return Protogeni::MalformedArgsResponse(); return Protogeni::MalformedArgsResponse();
...@@ -210,11 +213,14 @@ sub RegisterSlice($) ...@@ -210,11 +213,14 @@ sub RegisterSlice($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"uuid: Invalid characters"); "uuid: Invalid characters");
} }
if (! ($creator_uuid =~ /^[-\w]*$/)) { if (! ($creator_uuid =~ /^[-\w]*$/)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"creator_uuid: Invalid characters"); "creator_uuid: Invalid characters");
} }
if (! ($cert =~ /^[\012\015\040-\176]*$/)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"cert: Invalid characters");
}
# #
# Make sure the geni user exists. # Make sure the geni user exists.
...@@ -261,7 +267,8 @@ sub RegisterSlice($) ...@@ -261,7 +267,8 @@ sub RegisterSlice($)
"Improper format for uuid"); "Improper format for uuid");
} }
my $newslice = GeniSlice->Create($hrn, $uuid, $creator_uuid, $sa_idx); my $newslice = GeniSlice->Create($hrn, $uuid, $creator_uuid, $cert,
$sa_idx);
if (!defined($newslice)) { if (!defined($newslice)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"$hrn/$uuid could not be registered"); "$hrn/$uuid could not be registered");
...@@ -278,28 +285,30 @@ sub RegisterSlice($) ...@@ -278,28 +285,30 @@ sub RegisterSlice($)
sub DiscoverResources($) sub DiscoverResources($)
{ {
my ($argref) = @_; my ($argref) = @_;
my $slice_uuid = $argref->{'slice_uuid'}; my $slice = $argref->{'slice'};
if (!defined($slice_uuid)) { # This is a certificate. Ignored for now.
if (!defined($slice)) {
return Protogeni::MalformedArgsResponse(); return Protogeni::MalformedArgsResponse();
} }
if (! ($slice_uuid =~ /^[-\w]*$/)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"uuid: Invalid characters");
}
# #
# Return simple list of components (hashes). # Return simple list of components (hashes).
# #
my @results = (); my @results = ();
my $query_result = DBQueryWarn("select uuid,hrn,url from geni_components"); my $query_result = DBQueryWarn("select uuid from geni_components");
return GeniResponse->Create(GENIRESPONSE_DBERROR) return GeniResponse->Create(GENIRESPONSE_DBERROR)
if (!defined($query_result)); if (!defined($query_result));
while (my ($component_uuid,$hrn,$url) = $query_result->fetchrow_array()) { while (my ($component_uuid) = $query_result->fetchrow_array()) {
my $component = GeniComponent->Lookup($component_uuid);
return GeniResponse->Create(GENIRESPONSE_DBERROR)
if (!defined($component));
push(@results, { "uuid" => $component_uuid, push(@results, { "uuid" => $component_uuid,
"hrn" => $hrn, "hrn" => $component->hrn(),
"url" => $url}); "url" => $component->url(),
"cert" => $component->cert() });
} }
return GeniResponse->Create(GENIRESPONSE_SUCCESS, \@results); return GeniResponse->Create(GENIRESPONSE_SUCCESS, \@results);
} }
......
...@@ -24,7 +24,6 @@ use GeniDB; ...@@ -24,7 +24,6 @@ use GeniDB;
use Genixmlrpc; use Genixmlrpc;
use GeniResponse; use GeniResponse;
use User; use User;
use GeniUser;
use libtestbed; use libtestbed;
use English; use English;
use Data::Dumper; use Data::Dumper;
...@@ -37,21 +36,21 @@ my $TBAUDIT = "@TBAUDITEMAIL@"; ...@@ -37,21 +36,21 @@ my $TBAUDIT = "@TBAUDITEMAIL@";
my $BOSSNODE = "@BOSSNODE@"; my $BOSSNODE = "@BOSSNODE@";
my $OURDOMAIN = "@OURDOMAIN@"; my $OURDOMAIN = "@OURDOMAIN@";
my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net"; my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net";
my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc"; my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc/ch";
# #
# Lookup a user at the clearing house. # Lookup a user at the clearing house.
# #
sub LookupUser($$) sub LookupUser($$)
{ {
my ($user, $pref) = @_; my ($uuid, $pref) = @_;
$$pref = undef; $$pref = undef;
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::LookupUser", "CH::LookupUser",
{ "uuid" => $user->uuid()}); { "uuid" => $uuid });
return -1 return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
...@@ -64,14 +63,14 @@ sub LookupUser($$) ...@@ -64,14 +63,14 @@ sub LookupUser($$)
# #
sub LookupSlice($$) sub LookupSlice($$)
{ {
my ($experiment, $pref) = @_; my ($uuid, $pref) = @_;
$$pref = undef; $$pref = undef;
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::LookupSlice", "CH::LookupSlice",
{ "uuid" => $experiment->uuid()}); { "uuid" => $uuid });
return -1 return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
...@@ -83,29 +82,17 @@ sub LookupSlice($$) ...@@ -83,29 +82,17 @@ sub LookupSlice($$)
# Register a local Emulab user at the Geni ClearingHouse (which in the # Register a local Emulab user at the Geni ClearingHouse (which in the
# prototype is Utah Emulab). # prototype is Utah Emulab).
# #
sub RegisterUser($) sub RegisterUser($$$$$)
{ {
my ($user) = @_; my ($hrn, $uuid, $name, $email, $cert) = @_;
my $cert;
if ($user->SSLCert(1, \$cert)) {
print STDERR
"Geni::RegisterUser - No encrypted certificate found for $user\n";
return -1;
}
# XXX Form hrn from the uid and domain. This is backwards.
my $hrn = $OURDOMAIN . "." . $user->uid();
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::RegisterUser", "CH::RegisterUser",
{ "hrn" => $hrn, { "hrn" => $hrn,
# Optional, prefered local login id. "uuid" => $uuid,
"uid" => $user->uid(), "name" => $name,
"uuid" => $user->uuid(), "email" => $email,
"name" => $user->name(),
"email" => $user->email(),
"cert" => $cert}); "cert" => $cert});
return -1 return -1
...@@ -117,20 +104,17 @@ sub RegisterUser($) ...@@ -117,20 +104,17 @@ sub RegisterUser($)
# #
# Register a local Emulab experiment at the Clearinghouse, as a slice. # Register a local Emulab experiment at the Clearinghouse, as a slice.
# #
sub RegisterSlice($) sub RegisterSlice($$$$)
{ {
my ($experiment) = @_; my ($hrn, $uuid, $creator_uuid, $cert) = @_;
my $user = $experiment->GetCreator();
# XXX Form hrn from the uid and domain. This is backwards.
my $hrn = $OURDOMAIN . "." . $experiment->pid() . "." . $experiment->eid();
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::CreateSliceName", "CH::CreateSliceName",
{ "hrn" => $hrn, { "hrn" => $hrn,
"uuid" => $experiment->uuid(), "uuid" => $uuid,
"creator_uuid" => $user->uuid()}); "creator_uuid" => $creator_uuid,
"cert" => $cert });
return -1 return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
...@@ -143,12 +127,12 @@ sub RegisterSlice($) ...@@ -143,12 +127,12 @@ sub RegisterSlice($)
# #
sub DeleteSlice($) sub DeleteSlice($)
{ {
my ($experiment) = @_; my ($uuid) = @_;
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::FreeSliceName", "CH::FreeSliceName",
{ "uuid" => $experiment->uuid()}); { "uuid" => $uuid });
return -1 return -1
if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS);
...@@ -165,21 +149,12 @@ sub DeleteSlice($) ...@@ -165,21 +149,12 @@ sub DeleteSlice($)
# #
sub DiscoverResources($$) sub DiscoverResources($$)
{ {
my ($experiment, $pref) = @_; my ($slice, $pref) = @_;
#
# XXX
#
my $this_user = User->LookupByUnixId($UID);
if (! defined($this_user)) {
print STDERR "You ($UID) do not exist!\n";
return -1;
}
my $response = my $response =
Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef,
"CH::DiscoverResources", "CH::DiscoverResources",
{ "slice_uuid" => $experiment->uuid() }); { "slice" => $slice->cert() });
return -1 return -1
if (!defined($response)); if (!defined($response));
...@@ -188,7 +163,7 @@ sub DiscoverResources($$) ...@@ -188,7 +163,7 @@ sub DiscoverResources($$)
if ($response->code() != GENIRESPONSE_SUCCESS); if ($response->code() != GENIRESPONSE_SUCCESS);
# #
# We get back a list of components right now, whic we cache locally. # We get back a list of components right now, which we cache locally.
# #
my @result = (); my @result = ();
...@@ -196,10 +171,11 @@ sub DiscoverResources($$) ...@@ -196,10 +171,11 @@ sub DiscoverResources($$)
my $uuid = $ref->{'uuid'}; my $uuid = $ref->{'uuid'};
my $url = $ref->{'url'}; my $url = $ref->{'url'};
my $hrn = $ref->{'hrn'}; my $hrn = $ref->{'hrn'};
my $cert = $ref->{'cert'};
my $component = GeniComponent->Lookup($uuid); my $component = GeniComponent->Lookup($uuid);
if (!defined($component)) { if (!defined($component)) {
$component = GeniComponent->Create($uuid, $hrn, $url); $component = GeniComponent->Create($uuid, $hrn, $url, $cert);
if (!defined($component)) { if (!defined($component)) {
return GeniResponse->Create(GENIRESPONSE_DBERROR); return GeniResponse->Create(GENIRESPONSE_DBERROR);
} }
......
...@@ -24,6 +24,7 @@ use Genixmlrpc; ...@@ -24,6 +24,7 @@ use Genixmlrpc;
use GeniResponse; use GeniResponse;
use GeniTicket; use GeniTicket;
use GeniCredential; use GeniCredential;
use GeniSlice;
use GeniSliver; use GeniSliver;
use GeniUser; use GeniUser;
use libtestbed; use libtestbed;
...@@ -33,6 +34,7 @@ use User; ...@@ -33,6 +34,7 @@ use User;
use Node; use Node;
use English; use English;
use Data::Dumper; use Data::Dumper;
use XML::Simple;
use Experiment; use Experiment;
# Configure variables # Configure variables
...@@ -52,11 +54,12 @@ my $AVAIL = "$TB/sbin/avail"; ...@@ -52,11 +54,12 @@ my $AVAIL = "$TB/sbin/avail";
sub DiscoverResources($) sub DiscoverResources($)
{ {
my ($argref) = @_; my ($argref) = @_;
my $slice_uuid = $argref->{'slice_uuid'}; my $slice = $argref->{'slice'};
my $credential = $argref->{'credential'}; my $credential = $argref->{'credential'};
my $user_uuid = $ENV{'GENIUSER'}; my $user_uuid = $ENV{'GENIUSER'};
my $slice_uuid;
if (! (defined($slice_uuid) && ($slice_uuid =~ /^[-\w]+$/))) { if (! defined($slice)) {
return GeniResponse->MalformedArgsResponse(); return GeniResponse->MalformedArgsResponse();
} }
...@@ -65,6 +68,10 @@ sub DiscoverResources($) ...@@ -65,6 +68,10 @@ sub DiscoverResources($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not create GeniCredential object"); "Could not create GeniCredential object");
} }
GeniCredential->CertificateInfo($slice, \$slice_uuid) == 0 or
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not get uuid from Certificate");
# The credential owner/slice has to match what was provided. # The credential owner/slice has to match what was provided.
if (! ($user_uuid eq $credential->owner_uuid() && if (! ($user_uuid eq $credential->owner_uuid() &&
$slice_uuid eq $credential->this_uuid())) { $slice_uuid eq $credential->this_uuid())) {
...@@ -90,7 +97,7 @@ sub DiscoverResources($) ...@@ -90,7 +97,7 @@ sub DiscoverResources($)
} }
close(AVAIL); close(AVAIL);
my $xml = "<rspec xmlns:\"http://protogeni.net/resources/rspec/0.1\">\n"; my $xml = "<rspec xmlns=\"http://protogeni.net/resources/rspec/0.1\">\n";
foreach my $node (@nodelist) { foreach my $node (@nodelist) {
my $uuid = $node->uuid(); my $uuid = $node->uuid();
my $nodeid = $node->node_id(); my $nodeid = $node->node_id();
...@@ -104,9 +111,7 @@ sub DiscoverResources($) ...@@ -104,9 +111,7 @@ sub DiscoverResources($)
} }
# #
# Respond to a GetTicket request. No worries about credentials yet; we # Respond to a GetTicket request.
# trust the caller cause it got past the SSL client verify checks in the
# web server.
# #
sub GetTicket($) sub GetTicket($)
{ {
...@@ -118,11 +123,16 @@ sub GetTicket($) ...@@ -118,11 +123,16 @@ sub GetTicket($)
my $owner_uuid = $ENV{'GENIUSER'}; my $owner_uuid = $ENV{'GENIUSER'};
if (! (defined($slice_uuid) && ($slice_uuid =~ /^[-\w]+$/))) { if (! (defined($slice_uuid) && ($slice_uuid =~ /^[-\w]+$/))) {
return GeniResponse->MalformedArgsResponse(); GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper slice uuid");
} }
if (! defined($rspec)) { if (! (defined($rspec) && ($rspec =~ /^[-\w]+$/))) {
return GeniResponse->MalformedArgsResponse(); GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper rspec");
} }
# Convert the rspec back to a structure.
$rspec = XMLin($rspec, ForceArray => ["node"]);
$impotent = 0 $impotent = 0
if (!defined($impotent)); if (!defined($impotent));
...@@ -138,6 +148,18 @@ sub GetTicket($) ...@@ -138,6 +148,18 @@ sub GetTicket($)
"Invalid credentials for operation"); "Invalid credentials for operation");
} }
#
# See if we have a record of this slice in the DB. If not, then we have
# to go to the ClearingHouse to find its record, so that we can find out
# who the SA for it is.
#
my $slice = GeniSlice->Lookup($slice_uuid);
if (!defined($slice)) {
}
# #
# XXX Should we create a local geni_slices record in the DB? # XXX Should we create a local geni_slices record in the DB?
# #
...@@ -164,20 +186,23 @@ sub GetTicket($) ...@@ -164,20 +186,23 @@ sub GetTicket($)
} }
# #
# An rspec is a structure that requests a specific node. If that node # An rspec is a structure that requests specific nodes. If those
# is available, then reserve it. Otherwise the ticket cannot be # nodes are available, then reserve it. Otherwise the ticket
# granted. # cannot be granted.
# #
my $node_id = $rspec->{'node_id'}; my @nodeids = ();
my $pid = $experiment->pid(); my $pid = $experiment->pid();
my $eid = $experiment->eid(); my $eid = $experiment->eid();
if (defined($node_id) && $node_id =~ /^(\w*)$/) { foreach my $node_id (keys(%{$rspec->{'node'}})) {
$node_id = $1; if ($node_id =~ /^(\w*)$/) {
} $node_id = $1;
else { }
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef, else {
"Improper node id"); return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper node id: $node_id");
}
push(@nodeids, $node_id);
} }
# #
...@@ -190,7 +215,7 @@ sub GetTicket($) ...@@ -190,7 +215,7 @@ sub GetTicket($)
} }
# Nalloc might fail if the node gets picked up by someone else. # Nalloc might fail if the node gets picked up by someone else.
if (!$impotent) { if (!$impotent) {
system("$NALLOC $pid $eid $node_id"); system("$NALLOC $pid $eid @nodeids");
if (($? >> 8) < 0) { if (($? >> 8) < 0) {
$ticket->Delete(); $ticket->Delete();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
...@@ -203,7 +228,7 @@ sub GetTicket($) ...@@ -203,7 +228,7 @@ sub GetTicket($)
} }
} }
if ($ticket->Sign() != 0) { if ($ticket->Sign() != 0) {
# Release will free the node. # Release will free the nodes.
$ticket->Release(); $ticket->Release();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not sign Ticket"); "Could not sign Ticket");
...@@ -215,8 +240,6 @@ sub GetTicket($) ...@@ -215,8 +240,6 @@ sub GetTicket($)
# #
# Create a sliver. # Create a sliver.
# #
# XXX Credentials stuff.
#
sub CreateSliver($) sub CreateSliver($)
{ {
my ($argref) = @_; my ($argref) = @_;
......
...@@ -41,46 +41,6 @@ my $OURDOMAIN = "@OURDOMAIN@"; ...@@ -41,46 +41,6 @@ my $OURDOMAIN = "@OURDOMAIN@";
my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net"; my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net";
my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc"; my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc";
#
# Discover resources on components, for this experiment.
#
sub DiscoverResources($@)
{
my ($experiment, @resources) = @_;
my $rspec;
#
# XXX
#
my $this_user = User->LookupByUnixId($UID);
if (! defined($this_user)) {
print STDERR "You ($UID) do not exist!\n";
return -1;
}
# Need to construct a credential.
my $credential = GeniCredential->Create($experiment->uuid(),
$this_user->uuid());
if (!defined($credential)) {
print STDERR "Could not create a slice credential for $experiment!\n";
return -1;
}
if ($credential->AddCapability("createslice", 0)) {
print STDERR "Could not add capability to slice credential!\n";
return -1;
}
if ($credential->Sign()) {
print STDERR "Could not sign slice credential!\n";
return -1;
}
foreach my $component (@resources) {
$component->DiscoverResources($this_user, $credential,
$experiment->uuid(), \$rspec);
}