diff --git a/protogeni/lib/GNUmakefile.in b/protogeni/lib/GNUmakefile.in index 3f7d6162ebd3ba03798957d82d3db19d43f0ecea..9576efd61de99a61b5dd0a7719c06ee539bef971 100644 --- a/protogeni/lib/GNUmakefile.in +++ b/protogeni/lib/GNUmakefile.in @@ -14,8 +14,9 @@ include $(OBJDIR)/Makeconf LIB_SCRIPTS = GeniDB.pm GeniUser.pm GeniSAClient.pm \ GeniSlice.pm GeniSA.pm GeniCM.pm GeniCMClient.pm \ test.pl GeniTicket.pm GeniSliver.pm GeniCredential.pm \ - GeniComponent.pm GeniCH.pm GeniCHClient.pm \ - GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm + GeniComponent.pm GeniCH.pm GeniCHClient.pm GeniEmulab.pm \ + GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \ + node.pl # # Force dependencies on the scripts so that they will be rerun through diff --git a/protogeni/lib/GeniCH.pm.in b/protogeni/lib/GeniCH.pm.in index 619080d410aafd5f3708d1f01fa47addaf81fa6c..b9e83ff151f61f6f41f14a549ba5dcc90cc27d6f 100644 --- a/protogeni/lib/GeniCH.pm.in +++ b/protogeni/lib/GeniCH.pm.in @@ -110,6 +110,13 @@ sub LookupSlice($) "No slice authority found for slice"); } + # User bindings too. + my @userbindings = (); + if ($slice->UserBindings(\@userbindings) != 0) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "Error getting user bindings for slice"); + } + # Return a blob. my $blob = { "hrn" => $slice->hrn(), "uuid" => $slice->uuid(), @@ -119,7 +126,8 @@ sub LookupSlice($) "uuid" => $authority->uuid(), "cert" => $authority->cert(), "uuid_prefix" => $authority->uuid_prefix(), - "url" => $authority->url() } + "url" => $authority->url() }, + "userbindings" => \@userbindings, }; return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob); @@ -342,3 +350,126 @@ sub DiscoverResources($) return GeniResponse->Create(GENIRESPONSE_SUCCESS, \@results); } +# +# Bind user to slice +# +sub BindUser($) +{ + my ($argref) = @_; + my $slice_uuid = $argref->{'slice_uuid'}; + my $user_uuid = $argref->{'user_uuid'}; + + + if (! (defined($slice_uuid) && defined($user_uuid))) { + return GeniResponse->MalformedArgsResponse(); + } + + # + # Use the Emulab checkslot routines. + # + if (! ($slice_uuid =~ /^[-\w]*$/)) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "uuid: Invalid characters"); + } + if (! ($user_uuid =~ /^[-\w]*$/)) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "uuid: Invalid characters"); + } + + # + # The SA UUID comes from the SSL environment (certificate). Verify it + # and the prefix match for the uuid. + # + # Need to verify the UUID is permitted for the SA making the request. + # + my $sa_uuid = $ENV{'GENIUUID'}; + my $query_result = + DBQueryWarn("select idx, uuid_prefix from geni_sliceauthorities ". + "where uuid='$sa_uuid'"); + return GeniResponse->Create(GENIRESPONSE_DBERROR) + if (!defined($query_result)); + + return GeniResponse->Create(GENIRESPONSE_REFUSED, undef, "Who are You?") + if (!$query_result->numrows); + + my $slice = GeniSlice->Lookup($slice_uuid); + if (!defined($slice)) { + return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, + "No such slice $slice_uuid"); + } + my $user = GeniUser->Lookup($user_uuid); + if (!defined($slice)) { + return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, + "No such user $user_uuid"); + } + DBQueryWarn("replace into geni_bindings set ". + " slice_uuid='$slice_uuid', user_uuid='$user_uuid', ". + " created=now()") + or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "Error binding user to slice"); + + return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, + "$user_uuid has been bound to slice"); +} + +# +# UnBind user from slice +# +sub UnBindUser($) +{ + my ($argref) = @_; + my $slice_uuid = $argref->{'slice_uuid'}; + my $user_uuid = $argref->{'user_uuid'}; + + + if (! (defined($slice_uuid) && defined($user_uuid))) { + return GeniResponse->MalformedArgsResponse(); + } + + # + # Use the Emulab checkslot routines. + # + if (! ($slice_uuid =~ /^[-\w]*$/)) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "uuid: Invalid characters"); + } + if (! ($user_uuid =~ /^[-\w]*$/)) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "uuid: Invalid characters"); + } + + # + # The SA UUID comes from the SSL environment (certificate). Verify it + # and the prefix match for the uuid. + # + # Need to verify the UUID is permitted for the SA making the request. + # + my $sa_uuid = $ENV{'GENIUUID'}; + my $query_result = + DBQueryWarn("select idx, uuid_prefix from geni_sliceauthorities ". + "where uuid='$sa_uuid'"); + return GeniResponse->Create(GENIRESPONSE_DBERROR) + if (!defined($query_result)); + + return GeniResponse->Create(GENIRESPONSE_REFUSED, undef, "Who are You?") + if (!$query_result->numrows); + + my $slice = GeniSlice->Lookup($slice_uuid); + if (!defined($slice)) { + return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, + "No such slice $slice_uuid"); + } + my $user = GeniUser->Lookup($user_uuid); + if (!defined($slice)) { + return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, + "No such user $user_uuid"); + } + DBQueryWarn("delete from geni_bindings ". + "where slice_uuid='$slice_uuid' and user_uuid='$user_uuid'") + or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "Error unbinding user from slice"); + + return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, + "$user_uuid has been unbound from slice"); +} + diff --git a/protogeni/lib/GeniCHClient.pm.in b/protogeni/lib/GeniCHClient.pm.in index ca474bc719aa6103338f739ceeecd8a5888a4de7..d0f6202fc96bd573eea08b27a9904e5f1a1d0d21 100644 --- a/protogeni/lib/GeniCHClient.pm.in +++ b/protogeni/lib/GeniCHClient.pm.in @@ -35,7 +35,7 @@ my $TBAPPROVAL = "@TBAPPROVALEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@"; my $BOSSNODE = "@BOSSNODE@"; my $OURDOMAIN = "@OURDOMAIN@"; -my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net"; +my $GENICENTRAL = "myboss.myelab.testbed.emulab.net"; my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc/ch"; # @@ -194,3 +194,39 @@ sub DiscoverResources($$) return 0; } +# +# Bind and unbind users to/from slices +# +sub BindUser($$) +{ + my ($slice_uuid, $user_uuid) = @_; + + my $args = { "slice_uuid" => $slice_uuid, + "user_uuid" => $user_uuid }; + + my $response = + Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, + "CH::BindUser", $args); + + return -1 + if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); + + return 0; +} +sub UnBindUser($$) +{ + my ($slice_uuid, $user_uuid) = @_; + + my $args = { "slice_uuid" => $slice_uuid, + "user_uuid" => $user_uuid }; + + my $response = + Genixmlrpc::CallMethodHTTP($GENICENTRALURL, undef, + "CH::UnBindUser", $args); + + return -1 + if (!defined($response) || $response->code() != GENIRESPONSE_SUCCESS); + + return 0; +} + diff --git a/protogeni/lib/GeniCM.pm.in b/protogeni/lib/GeniCM.pm.in index 49e411cf182d3370ba8ed0c26c0d3e4bad8206d2..a036387362541e5c3b401da4cb77219baee2875e 100644 --- a/protogeni/lib/GeniCM.pm.in +++ b/protogeni/lib/GeniCM.pm.in @@ -186,6 +186,11 @@ sub GetTicket($) "Could not get slice info from ClearingHouse"); } } + else { + $slice->UpdateFromRegistry() == 0 or + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "Could not update slice info from ClearingHouse"); + } # # Ditto the user. @@ -345,6 +350,20 @@ sub CreateSliver($) or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, "Error binding user to slice"); + # Bind the other users too. + my @userbindings; + if ($slice->UserBindings(\@userbindings) != 0) { + return GeniResponse->Create(GENIRESPONSE_ERROR, undef, + "Error binding users to slice"); + } + foreach my $otheruuid (@userbindings) { + my $otheruser = GeniUser->Lookup($otheruuid); + + if (!$otheruser->BindToSlice($slice) != 0) { + print STDERR "Could not bind $otheruser to $slice\n"; + } + } + # # We are actually an Aggregate, so return an aggregate of slivers, # unless there is just one node. @@ -453,21 +472,6 @@ sub CreateSliver($) } } - # - # This stuff needs to be moved elsewhere. - # - # XXX What if we have multiple slivers for this slice? We are going - # to need some locking or management at the slice level so that we run - # tbswap only once, or at least no more then one at a time. - # - if (0 && !$impotent) { - system("$SWAPEXP -s modify -g $pid $eid"); - if ($?) { - $message = "Failed to tbswap $pid,$eid"; - goto bad; - } - } - # # The API states we return a credential to control the sliver/aggregate. # @@ -602,213 +606,3 @@ sub DestroySliver($) return GeniResponse->Create(GENIRESPONSE_SUCCESS); } -# -# Bind a user to a slice. -# -sub BindUser($) -{ - my ($argref) = @_; - my $sliver = $argref->{'sliver'}; - my $hrn = $argref->{'userinfo'}->{'hrn'}; - my $uuid = $argref->{'userinfo'}->{'uuid'}; - my $name = $argref->{'userinfo'}->{'name'}; - my $email = $argref->{'userinfo'}->{'email'}; - my $cert = $argref->{'userinfo'}->{'cert'}; - my $sshkey = $argref->{'userinfo'}->{'sshkey'}; - my $sliver_uuid; - - if (! (defined($hrn) && defined($name) && defined($sliver) && - defined($email) && defined($cert) && defined($uuid))) { - return GeniResponse->MalformedArgsResponse(); - } - - GeniCertificate->CertificateInfo($sliver, \$sliver_uuid) == 0 or - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Could not get uuid from Certificate"); - - # - # See if we have a record of this sliver 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. - # - $sliver = GeniSliver->Lookup($sliver_uuid); - if (!defined($sliver)) { - # Might be an aggregate instead. - $sliver = GeniAggregate->Lookup($sliver_uuid); - if (!defined($sliver)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "No such sliver $sliver_uuid"); - } - } - my $slice = $sliver->GetSlice(); - - # - # Use the Emulab checkslot routines. - # - if (! ($hrn =~ /^[-\w\.]*$/)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "hrn: Invalid characters"); - } - if (! ($uuid =~ /^[-\w]*$/)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "uuid: Invalid characters"); - } - if (! TBcheck_dbslot($name, "users", "usr_name", TBDB_CHECKDBSLOT_ERROR)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "name: ". TBFieldErrorString()); - } - if (! TBcheck_dbslot($email, "users", "usr_email",TBDB_CHECKDBSLOT_ERROR)){ - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "email: ". TBFieldErrorString()); - } - if (! ($cert =~ /^[\012\015\040-\176]*$/)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "cert: Invalid characters"); - } - if (defined($sshkey) && ! ($sshkey =~ /^[\012\015\040-\176]*$/)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "sshkey: Invalid characters"); - } - - # - # The SA UUID comes from the SSL environment (certificate). Verify it - # and the prefix match for the uuid. - # - my $sa_uuid = $ENV{'GENIUUID'}; - my $authority = GeniAuthority->Lookup($sa_uuid); - if (!defined($authority)) { - return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, - "No slice authority record for $sa_uuid"); - } - if (! $authority->PrefixMatch($uuid)) { - return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef, - "uuid: Prefix mismatch"); - } - - # - # Verify that this is the SA for the slice. - # - if (! $slice->IsSliceAuthority($authority)) { - return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef, - "Must be the SA for the slice"); - } - - # Might already exist. Not an error, Just check binding and return. - my $user = GeniUser->Lookup($uuid); - if (defined($user)) { - $user->BindToSlice($slice) == 0 - or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Error binding user to slice"); - - return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, - "$hrn/$email has been bound to slice"); - } - - # - # XXX - # - # What kind of uniquess requirements do we need? No one else with this - # email address? Of course, we have to allow hrn reuse, but should we - # require that for a given SA, that hrn is unique, at least to avoid - # lots of confusion? - # - if (GeniUser->CheckExisting($hrn, $email)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "$hrn/$email already registered"); - } - - # The local uid we will use is the last part of the hrn. - my ($uid) = ($hrn =~ /^.*\.(\w*)$/); - if (!defined($uid)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "uid: cannot parse hrn to get uid"); - } - elsif (! TBcheck_dbslot($uid, "users", "uid", TBDB_CHECKDBSLOT_ERROR)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "uid: ". TBFieldErrorString()); - } - my $newuser = GeniUser->Create($hrn, $uid, $uuid, - $name, $email, $cert, - $authority->idx(), $sshkey); - if (!defined($newuser)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "$hrn/$email could not be registered"); - } - $newuser->BindToSlice($slice) == 0 - or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Error binding user to sliver"); - - return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, - "$hrn/$email has been bound to $sliver_uuid"); -} - -# -# Unbind user from sliver. -# -sub UnBindUser($) -{ - my ($argref) = @_; - my $sliver = $argref->{'sliver'}; - my $user = $argref->{'user'}; - my $sliver_uuid; - my $user_uuid; - - if (! (defined($sliver) && defined($user))) { - return GeniResponse->MalformedArgsResponse(); - } - - GeniCertificate->CertificateInfo($sliver, \$sliver_uuid) == 0 or - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Could not get uuid from Certificate"); - - GeniCertificate->CertificateInfo($user, \$user_uuid) == 0 or - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Could not get uuid from Certificate"); - - # - # See if we have a record of this sliver 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. - # - $sliver = GeniSliver->Lookup($sliver_uuid); - if (!defined($sliver)) { - # Might be an aggregate instead. - $sliver = GeniAggregate->Lookup($sliver_uuid); - if (!defined($sliver)) { - return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "No such sliver $sliver_uuid"); - } - } - # Does not exist? Not an error. - $user = GeniUser->Lookup($user_uuid); - if (! defined($user)) { - return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, - "$user_uuid is not bound to $sliver_uuid"); - } - my $slice = $sliver->GetSlice(); - - # - # The SA UUID comes from the SSL environment (certificate). - # - my $sa_uuid = $ENV{'GENIUUID'}; - my $authority = GeniAuthority->Lookup($sa_uuid); - if (!defined($authority)) { - return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef, - "No slice authority record for $sa_uuid"); - } - # - # Verify that this is the SA for the slice. - # - if (! $slice->IsSliceAuthority($authority)) { - return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef, - "Must be the SA for the slice"); - } - - $user->UnBindFromSlice($slice) == 0 - or return GeniResponse->Create(GENIRESPONSE_ERROR, undef, - "Error unbinding user from sliver"); - - return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef, - "$user_uuid has been unbound from sliver"); -} - diff --git a/protogeni/lib/GeniCMClient.pm.in b/protogeni/lib/GeniCMClient.pm.in index 5e0190ab117a8aca43fe728337301b60c44aec69..69fe4ef135be9c19cf70f65c8d41bc6f4eb39d9b 100644 --- a/protogeni/lib/GeniCMClient.pm.in +++ b/protogeni/lib/GeniCMClient.pm.in @@ -38,8 +38,6 @@ my $TBAPPROVAL = "@TBAPPROVALEMAIL@"; my $TBAUDIT = "@TBAUDITEMAIL@"; my $BOSSNODE = "@BOSSNODE@"; my $OURDOMAIN = "@OURDOMAIN@"; -my $GENICENTRAL = "myboss.little-emulab-bsd61.testbed.emulab.net"; -my $GENICENTRALURL = "https://$GENICENTRAL/protogeni/xmlrpc"; # _Always_ make sure that this 1 is at the end of the file... 1; diff --git a/protogeni/lib/GeniComponent.pm.in b/protogeni/lib/GeniComponent.pm.in index 85e36916f3c5b71ecb9c14782da14b9f7c50be42..ba84cc5e519ae6b32b347cf46b82e65049572d6d 100644 --- a/protogeni/lib/GeniComponent.pm.in +++ b/protogeni/lib/GeniComponent.pm.in @@ -159,6 +159,52 @@ sub url($) { return field($_[0], "url"); } sub hrn($) { return field($_[0], "hrn"); } sub cert($) { return field($_[0], "cert"); } +# +# Class method to lookup the component for a given resource (uuid) by +# looking in the resources table. +# +sub LookupByResource($$) +{ + my ($class, $uuid) = @_; + + return undef + if (! ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)); + + my $query_result = + DBQueryWarn("select component_idx from geni_resources ". + "where resource_uuid='$uuid'"); + + return undef + if (! $query_result || !$query_result->numrows); + + my ($idx) = $query_result->fetchrow_array(); + + return GeniComponent->Lookup($idx); +} + +# +# Method to insert a new geni_resources record for the component. +# +sub NewResource($$) +{ + my ($self, $uuid) = @_; + + return -1 + if (! ref($self)); + + my $idx = TBGetUniqueIndex('next_resource', 1); + my $component_idx = $self->idx(); + $uuid = DBQuoteSpecial("$uuid"); + + return -1 + if (! DBQueryWarn("replace into geni_resources set ". + " idx=$idx, resource_uuid=$uuid, ". + " resource_type='node', ". + " created=now(), component_idx=$component_idx")); + + return 0; +} + # # Refresh a class instance by reloading from the DB. # @@ -248,64 +294,6 @@ sub DiscoverResources($$$$$) return 0; } -# -# Bind and UnBind users to/from slivers. -# -# We do this with the local SA as the credential, not the sliver credential. -# -sub BindUser($$$$) -{ - my ($self, $sliver, $target_user) = @_; - - # Must be a real reference. - return -1 - if (! (ref($self) && ref($sliver) && ref($target_user))); - - my $sshkey; - $target_user->GetSSHKey(\$sshkey); - - my $userinfo = { "hrn" => $target_user->hrn(), - "uuid" => $target_user->uuid(), - "name" => $target_user->name(), - "email" => $target_user->email(), - "cert" => $target_user->cert(), - "sshkey" => $sshkey - }; - - my $response = - Genixmlrpc::CallMethodHTTP($self->url(), undef, - "CM::BindUser", - { "sliver" => $sliver->cert(), - "userinfo" => $userinfo }); - - if ($response->code() != GENIRESPONSE_SUCCESS) { - print STDERR "Could not bind $target_user to sliver $sliver\n"; - return -1; - } - return 0; -} - -sub UnBindUser($$$$) -{ - my ($self, $sliver, $target_user) = @_; - - # Must be a real reference. - return -1 - if (! (ref($self) && ref($sliver) && ref($target_user))); - - my $response = - Genixmlrpc::CallMethodHTTP($self->url(), undef, - "CM::UnBindUser", - { "sliver" => $sliver->cert(), - "user" => $target_user->cert() }); - - if ($response->code() != GENIRESPONSE_SUCCESS) { - print STDERR "Could not unbind $target_user to sliver $sliver\n"; - return -1; - } - return 0; -} - # # Get a Ticket from a component; # diff --git a/protogeni/lib/GeniCredential.pm.in b/protogeni/lib/GeniCredential.pm.in index d3cfbf894e6944055c2d329951ddc69b0d9766a0..98d1c0e80ad59d9bda7a9fa5774b8f75bfaaae33 100644 --- a/protogeni/lib/GeniCredential.pm.in +++ b/protogeni/lib/GeniCredential.pm.in @@ -49,6 +49,39 @@ $LOCALSA_FLAG = 1; $LOCALCM_FLAG = 2; @EXPORT_OK = qw(LOCALSA_FLAG LOCALCM_FLAG); +# +# Look for a signed credential in the DB. At present, we store a credential +# by user/object (uuid/uuid), not worrying about different flavors of creds +# with different permissions. This is basically a cache on the client side of +# credentials in use so that they do not need to be regenerated. +# +sub Lookup($$$) +{ + my ($class, $this, $owner) = @_; + + return undef + if (! (ref($this) && ref($owner))); + + my $this_uuid = $this->uuid(); + my $owner_uuid = $owner->uuid(); + + my $query_result = + DBQueryWarn("select * from geni_credentials ". + "where owner_uuid='$owner_uuid' and ". + " this_uuid='$this_uuid'"); + return undef + if (!defined($query_result) || !$query_result->numrows); + + my $credential = GeniCredential->Create($this, $owner); + return undef + if (!defined($credential)); + + my $row = $query_result->fetchrow_hashref(); + $credential->{'idx'} = $row->{'idx'}; + $credential->{'string'} = $row->{'credential_string'}; + return $credential; +} + # # Create an empty credential object. # diff --git a/protogeni/lib/GeniEmulab.pm.in b/protogeni/lib/GeniEmulab.pm.in new file mode 100644 index 0000000000000000000000000000000000000000..dd1b97bf05ac3ef7d5f629132e8677a1f09c2e66 --- /dev/null +++ b/protogeni/lib/GeniEmulab.pm.in @@ -0,0 +1,308 @@ +#!/usr/bin/perl -w +# +# EMULAB-COPYRIGHT +# Copyright (c) 2008 University of Utah and the Flux Group. +# All rights reserved. +# +package GeniEmulab; + +# +# Stuff to interface between Emulab core and Geni nodes. +# +use strict; +use Exporter; +use vars qw(@ISA @EXPORT); + +@ISA = "Exporter"; +@EXPORT = qw ( ); + +# Must come after package declaration! +use lib '@prefix@/lib'; +use GeniDB; +use Genixmlrpc; +use GeniResponse; +use GeniTicket; +use GeniCredential; +use GeniCertificate; +use GeniSlice; +use GeniSliver; +use GeniUser; +use libtestbed; +use User; +use Node; +use Interface; +use English; +use Data::Dumper; +use Experiment; + +# Configure variables +my $TB = "@prefix@"; +my $TBOPS = "@TBOPSEMAIL@"; +my $TBAPPROVAL = "@TBAPPROVALEMAIL@"; +my $TBAUDIT = "@TBAUDITEMAIL@"; +my $BOSSNODE = "@BOSSNODE@"; +my $OURDOMAIN = "@OURDOMAIN@"; + +# +# Allocate the GENI slivers for an Emulab experiment. The nodes to be created +# are passed in, otherwise lookup the nodes for the experiment. +# +# XXX Need to deal with links between nodes. +# +sub AllocateSlivers($$$) +{ + my ($class, $experiment, $nodelist) = @_; + my $thisuser = User->ThisUser(); + + # + # Create a Geni user from current user doing the operation. + # + my $geniuser = GeniUser->CreateFromLocal($thisuser); + if (!defined($geniuser)) { + print STDERR + "Could not create a geni user from current user $thisuser\n"; + return -1; + } + # Register user at the ClearingHouse. + if ($geniuser->Register() != 0) { + print STDERR "Could not register $geniuser at the ClearingHouse.\n"; + return -1; + } + + # + # The slice should already be registered by this point, but it does + # not hurt anything to make sure. + # + my $slice = GeniSlice->Lookup($experiment->uuid()); + if (!defined($slice)) { + $slice = GeniSlice->CreateFromLocal($experiment, $thisuser); + if (!defined($slice)) { + print STDERR + "Could not create a local slice record for $experiment\n"; + return -1; + } + if ($slice->Register() != 0) { + $slice->Delete(); + print STDERR + "Could not register slice for $experiment at ClearingHouse.\n"; + return -1; + } + } + + # + # Look for a credential. Should already exist, but if not, create one + # and store it in the DB for later. + # + my $credential = GeniCredential->Lookup($slice, $geniuser); + if (!defined($credential)) { + $credential = GeniCredential->Create($slice, $geniuser); + if (!defined($credential)) { + print STDERR + "Could not create a slice credential for $slice/$geniuser!\n"; + return -1; + } + if ($credential->Sign($GeniCredential::LOCALSA_FLAG) != 0) { + print STDERR "Could not sign slice credential $credential!\n"; + return -1; + } + if ($credential->Store() == 0) { + print STDERR "Could not store slice credential $credential!\n"; + return -1; + } + } + + # + # Loop through each node and grab a ticket for it. The nodes table + # stores the uuid of the node as told to us in resource discovery. + # Use this to create a simple rspec. This will need to get fancier + # later. + # + # XXX We are still not using rspecs anywhere. + # + foreach my $node (@{ $nodelist }) { + next + if ($node->genisliver_idx()); + + my $node_uuid = $node->uuid(); + my $rspec = {'node' => {$node_uuid => + {"uuid" => $node_uuid}}}; + + # + # XXX The component is stored in the geni_resources table. Not sure + # how that will work out. + # + my $component = GeniComponent->LookupByResource($node_uuid); + if (!defined($component)) { + print STDERR "Could not find CM for $node\n"; + return -1; + } + + # + # Get ticket from component. + # + my $ticket = $component->GetTicket($slice, $rspec, + $thisuser, $credential); + + if (!defined($ticket)) { + print STDERR "Could not get ticket from CM for $node\n"; + return -1; + } + + # + # Must store the ticket since the sliver will not be created + # (ticket redeemed) until later. + # + if ($ticket->Store() != 0) { + $ticket->Delete(); + print STDERR "Could not store $ticket on $component for $node\n"; + return -1; + + } + # + # Bogus; store the ticket into the sliver index of the node. I + # need to store it someplace until the ticket is redeemed. + # Generally though, there might not be a ticket per node, + # since an rspec can have multiple resources (nodes, links), + # and I have not figured out what to do for that yet. + # + if ($node->SetGeniSliverIDX($ticket->idx()) != 0) { + print STDERR "Could not set sliver (ticket) idx for $node\n"; + if ($ticket->Delete() != 0) { + print STDERR "Could not destroy $ticket\n"; + } + return -1; + } + } + + return 0; +} + +# +# Instantiate the slivers (from tickets) +# +sub InstantiateSlivers($$$) +{ + my ($class, $experiment, $nodelist) = @_; + my $thisuser = User->ThisUser(); + + my $slice = GeniSlice->Lookup($experiment->uuid()); + if (!defined($slice)) { + print STDERR "No slice exists for $experiment. \n"; + return -1; + } + + # + # Loop through each node and grab a ticket for it. The nodes table + # stores the uuid of the node as told to us in resource discovery. + # Use this to create a simple rspec. This will need to get fancier + # later. + # + # XXX We are still not using rspecs anywhere. + # + foreach my $node (@{ $nodelist }) { + $sliver_idx = $node->genisliver_idx(); + + my $sliver = GeniSliver->Lookup($sliver_idx); + next + if (defined($sliver)); + + # See if its still a ticket. + my $ticket = GeniTicket->Lookup($sliver_idx); + if (!defined($ticket)) { + print STDERR "Could not find ticket for $node in $experiment\n"; + return -1; + } + my $component = $ticket->component(); + + # + # Create sliver on component using the ticket. + # + my $sliver = $component->CreateSliver($slice, $ticket, $thisuser); + if (!defined($sliver)) { + print STDERR "Could not create sliver on $component for $node\n"; + if ($ticket->Delete() != 0) { + print STDERR "Could not delete $ticket\n"; + } + if ($node->SetGeniSliverIDX(0) != 0) { + print STDERR "Could not clear sliver idx for $node\n"; + } + return -1; + } + if ($node->SetGeniSliverIDX($sliver->idx()) != 0) { + print STDERR "Could not set sliver idx for $node\n"; + if ($ticket->Delete() != 0) { + print STDERR "Could not delete $ticket\n"; + } + if ($sliver->Destroy() != 0) { + print STDERR "Could not destroy $sliver\n"; + } + return -1; + } + # No longer need the ticket. + if ($ticket->Delete() != 0) { + print STDERR "Could not delete $ticket\n"; + } + } + return 0; +} + +# +# XXX Need to deal with links between nodes. +# +sub DestroySlivers($$$) +{ + my ($class, $experiment, $nodelist) = @_; + my $thisuser = User->ThisUser(); + my $errors = 0; + + my $slice = GeniSlice->Lookup($experiment->uuid()); + if (!defined($slice)) { + print STDERR "No local slice record for $experiment\n"; + return -1; + } + + # + # Loop through each node and do the sliver thing. + # + # XXX We are still not using rspecs anywhere. + # + foreach my $node (@{ $nodelist }) { + next + if (! $node->genisliver_idx()); + + $sliver_idx = $node->genisliver_idx(); + + my $sliver = GeniSliver->Lookup($sliver_idx); + if (!defined($sliver)) { + # See if its still a ticket. + my $ticket = GeniTicket->Lookup($sliver_idx); + if (!defined($ticket)) { + print STDERR + "Could not find ticket for $node in $experiment\n"; + $errors++; + } + elsif ($ticket->Delete() != 0) { + print STDERR "Could not delete $ticket\n"; + $errors++; + } + next; + } + if ($sliver->Destroy != 0) { + print STDERR "Could not destroy $sliver for $node\n"; + $errors++; + next; + } + if ($node->SetGeniSliverIDX(0) != 0) { + print STDERR "Could not clear sliver idx for $node\n"; + $errors++; + next; + } + } + + return $errors; +} + + +# _Always_ make sure that this 1 is at the end of the file... +1; + diff --git a/protogeni/lib/GeniSlice.pm.in b/protogeni/lib/GeniSlice.pm.in index 194904952eb939ac09da60ba03e982b5952a6898..5b7d6fc8029290eb1bb141b595af73046815a63d 100644 --- a/protogeni/lib/GeniSlice.pm.in +++ b/protogeni/lib/GeniSlice.pm.in @@ -26,6 +26,7 @@ use libdb qw(TBGetUniqueIndex); use Experiment; use English; use overload ('""' => 'Stringify'); +use Data::Dumper; use vars qw(); # Configure variables @@ -98,10 +99,11 @@ sub Lookup($$) print STDERR "Could not find certificate for slice $idx ($uuid)\n"; return undef; } - $self->{'CERT'} = $certificate; + $self->{'CERT'} = $certificate; + $self->{'USERS'} = undef; # Add to cache. - $slices{$self->{'SLICE'}->{'idx'}} = $self; + $slices{$self->{'SLICE'}->{'idx'}} = $self; return $self; } @@ -226,6 +228,10 @@ sub Register($) return -1 if (! ref($self)); + my $blob; + return 0 + if (GeniCHClient::LookupSlice($self->uuid(), \$blob) == 0); + GeniCHClient::RegisterSlice($self->hrn(), $self->uuid(), $self->creator_uuid(), $self->cert()) == 0 or return -1; @@ -256,10 +262,70 @@ sub CreateFromRegistry($$) return undef; } } - return GeniSlice->Create($blob->{'hrn'}, - $blob->{'uuid'}, - $blob->{'creator_uuid'}, - $blob->{'cert'}, $authority->idx()); + my $slice = GeniSlice->Create($blob->{'hrn'}, + $blob->{'uuid'}, + $blob->{'creator_uuid'}, + $blob->{'cert'}, $authority->idx()); + return undef + if (!defined($slice)); + + print STDERR Dumper($blob); + + # Add the user bindings. + foreach my $uuid (@{ $blob->{'userbindings'} }) { + my $user = GeniUser->Lookup($uuid); + if (!defined($user)) { + $user = GeniUser->CreateFromRegistry($uuid); + if (!defined($user)) { + print STDERR "No user $uuid in the ClearingHouse\n"; + next; + } + } + DBQueryWarn("replace into geni_bindings set ". + " created=now(), slice_uuid='$slice_uuid', ". + " user_uuid='$uuid'") + or print STDERR + "Could not insert user binding for $uuid to slice $slice_uuid\n"; + } + return $slice; +} + +# +# Update slice from the ClearingHouse, by looking up the info. +# +sub UpdateFromRegistry($) +{ + my ($self) = @_; + my $slice_uuid = $self->uuid(); + + my $blob; + return -1 + if (GeniCHClient::LookupSlice($slice_uuid, \$blob) != 0); + + print STDERR Dumper($blob); + + DBQueryWarn("delete from geni_bindings ". + "where slice_uuid='$slice_uuid'") + or print STDERR + "Could not delete user bindings from slice $slice_uuid\n"; + + # Add the user bindings. + foreach my $uuid (@{ $blob->{'userbindings'} }) { + my $user = GeniUser->Lookup($uuid); + if (!defined($user)) { + $user = GeniUser->CreateFromRegistry($uuid); + if (!defined($user)) { + print STDERR "No user $uuid in the ClearingHouse\n"; + next; + } + } + DBQueryWarn("replace into geni_bindings set ". + " created=now(), slice_uuid='$slice_uuid', ". + " user_uuid='$uuid'") + or print STDERR + "Could not insert user binding for $uuid to slice $slice_uuid\n"; + } + return 0; } # @@ -334,5 +400,72 @@ sub IsSliceAuthority($$) return 0; } +# +# Client side methods to bind and unbind users from slices +# +# XXX We issue this using the local SA as the authority, but need to allow +# the slice/owner credentials to do this. +# +sub BindUser($$) +{ + my ($self, $target_user) = @_; + + return -1 + if (! (ref($self) && ref($target_user))); + + GeniCHClient::BindUser($self->uuid(), $target_user->uuid()) + == 0 or return -1; + + return 0; +} + +sub UnBindUser($$) +{ + my ($self, $target_user) = @_; + + return -1 + if (! (ref($self) && ref($target_user))); + + GeniCHClient::UnBindUser($self->uuid(), $target_user->uuid()) + == 0 or return -1; + + return 0; +} + +# +# Return the user bindings for a slice, as a list. Used on client and server +# to get the geni_bindings table entries for a slice. +# +sub UserBindings($$) +{ + my ($self, $pref) = @_; + + return -1 + if (! (ref($self) && ref($pref))); + + my $uuid = $self->uuid(); + + if (!defined($self->{'USERS'})) { + my $query_result = + DBQueryWarn("select user_uuid from geni_bindings ". + "where slice_uuid='$uuid'"); + return -1 + if (!$query_result); + + $self->{'USERS'} = {}; + + while (my ($user_uuid) = $query_result->fetchrow_array()) { + my $user = GeniUser->Lookup($user_uuid); + if (!defined($user)) { + print STDERR "Bindings: No mapping for user $user_uuid\n"; + next; + } + $self->{'USERS'}->{$user_uuid} = $user; + } + } + @$pref = keys(%{ $self->{'USERS'} }); + return 0; +} + # _Always_ make sure that this 1 is at the end of the file... 1; diff --git a/protogeni/lib/GeniSliver.pm.in b/protogeni/lib/GeniSliver.pm.in index 8c859a813adfba87b8abbdf02ae6c15defca3ac1..95f0b27101f6bf9a3cc30749e2fa9a79120b6be0 100644 --- a/protogeni/lib/GeniSliver.pm.in +++ b/protogeni/lib/GeniSliver.pm.in @@ -445,46 +445,6 @@ sub Start($$) return 0; } -# -# Client side methods to bind and unbind users from slivers. -# -# XXX We issue this using the local SA as the authority, but need to allow -# the slice/sliver owner to do this. -# -sub BindUser($$) -{ - my ($self, $target_user) = @_; - - return -1 - if (! (ref($self) && ref($target_user))); - - my $component = $self->GetComponent(); - return -1 - if (!defined($component)); - - return -1 - if ($component->BindUser($self, $target_user) != 0); - - return 0; -} - -sub UnBindUser($$) -{ - my ($self, $target_user) = @_; - - return -1 - if (! (ref($self) && ref($target_user))); - - my $component = $self->GetComponent(); - return -1 - if (!defined($component)); - - return -1 - if ($component->UnBindUser($self, $target_user) != 0); - - return 0; -} - # # Create a signed credential for this sliver, issued to the provided user. # The credential will grant all permissions for now. diff --git a/protogeni/lib/GeniTicket.pm.in b/protogeni/lib/GeniTicket.pm.in index 4c572148eeb1c5ddddce8479125f28d6e24a1c10..7c5fba8f862b543f93f96f090ba99a4d5dcdc5f6 100644 --- a/protogeni/lib/GeniTicket.pm.in +++ b/protogeni/lib/GeniTicket.pm.in @@ -29,6 +29,7 @@ use XML::Simple; use XML::LibXML; use Data::Dumper; use File::Temp qw(tempfile); +use overload ('""' => 'Stringify'); # Configure variables my $TB = "@prefix@"; @@ -42,6 +43,45 @@ my $VERIFYCRED = "$TB/sbin/verifygenicred"; my $NFREE = "$TB/bin/nfree"; my $CMCERT = "$TB/etc/genicm.pem"; +# Cache of tickets. +my %tickets = (); + +# +# Lookup by local idx. +# +sub Lookup($$) +{ + my ($class, $idx) = @_; + + return undef + if (! ($idx =~ /^\d*$/)); + return $tickets{"$idx"} + if (exists($tickets{"$idx"})); + + my $query_result = + DBQueryWarn("select * from geni_tickets where idx='$idx'"); + + return undef + if (!defined($query_result) || !$query_result->numrows); + + my $row = $query_result->fetchrow_hashref(); + + # Map the component + my $component; + if ($row->{'component_idx'}) { + $component = GeniComponent->Lookup($row->{'component_idx'}); + return undef + if (!defined($component)); + } + my $ticket = GeniTicket->CreateFromSignedTicket($row->{'ticket_string'}, + $component, 1); + return undef + if (!defined($ticket)); + + $tickets{"$idx"} = $ticket; + return $ticket; +} + # # Create an unsigned ticket object, to be populated and signed and returned. # @@ -49,15 +89,28 @@ sub Create($$$$) { my ($class, $slice, $owner, $rspec) = @_; + # Every Ticket gets a new unique index (sequence number). + my $seqno = TBGetUniqueIndex('next_ticket', 1); + my $self = {}; $self->{'rspec'} = $rspec; $self->{'slice_uuid'} = $slice->uuid(); $self->{'owner_uuid'} = $owner->uuid(); $self->{'slice_cert'} = $slice->cert(); $self->{'owner_cert'} = $owner->cert(); + $self->{'seqno'} = $seqno; $self->{'ticket_string'} = undef; - $self->{'idx'} = undef; # Only set when in DB. $self->{'component'} = undef; + $self->{'stored'} = 0; # Stored to the DB. + + # + # Locally generated tickets need a local DB index, which can be the + # same as the sequence number. A ticket from a remote component will + # have it own seqno, and so we will generate a locally valid idx for + # those when when(if) we store them in the DB. + # + $self->{'idx'} = $seqno; + bless($self, $class); return $self; @@ -65,6 +118,7 @@ sub Create($$$$) # accessors sub field($$) { return ($_[0]->{$_[1]}); } sub idx($) { return field($_[0], "idx"); } +sub seqno($) { return field($_[0], "seqno"); } sub rspec($) { return field($_[0], "rspec"); } sub uuid($) { return field($_[0], "slice_uuid"); } sub slice_uuid($) { return field($_[0], "slice_uuid"); } @@ -75,6 +129,22 @@ sub ticket($) { return field($_[0], "ticket"); } sub asString($) { return field($_[0], "ticket_string"); } sub ticket_string($) { return field($_[0], "ticket_string"); } sub component($) { return field($_[0], "component"); } +sub stored($) { return field($_[0], "stored"); } + +# +# Stringify for output. +# +sub Stringify($) +{ + my ($self) = @_; + + my $idx = $self->idx(); + if (!defined($idx)) { + my $seqno = $self->seqno(); + $idx = "S$seqno"; + } + return "[GeniTicket: $idx]"; +} # # Create a ticket object from a signed ticket string. @@ -146,31 +216,18 @@ sub CreateFromSignedTicket($$;$$) return undef; } - # - # We save copies of the tickets we hand out; lets find that record - # in the DB, just to verify. - # - my $serial; - - if (!$nosig) { - my ($serial_node) = $doc->getElementsByTagName("serial"); - return undef - if (!defined($serial_node)); - $serial = $serial_node->to_literal(); + my ($seqno_node) = $doc->getElementsByTagName("serial"); + return undef + if (!defined($seqno_node)); + my $seqno = $seqno_node->to_literal(); - if (! ($serial =~ /^\w+$/)) { - print STDERR "Invalid serial in ticket\n"; - return undef; - } - my $query_result = - DBQueryWarn("select * from geni_tickets where idx='$serial'"); - if (!$query_result || !$query_result->numrows) { - print STDERR "Could not find the ticket in te DB\n"; - return undef; - } + if (! ($seqno =~ /^\w+$/)) { + print STDERR "Invalid sequence number in ticket\n"; + return undef; } my $self = {}; + $self->{'idx'} = undef; $self->{'rspec'} = $rspec; $self->{'slice_uuid'} = $slice_uuid; $self->{'owner_uuid'} = $owner_uuid; @@ -179,14 +236,31 @@ sub CreateFromSignedTicket($$;$$) $self->{'ticket_string'} = $ticket_string; $self->{'xmlref'} = $doc; $self->{'component'} = $component; - $self->{'idx'} = $serial; + $self->{'seqno'} = $seqno; + $self->{'stored'} = 0; + + # + # We save copies of the tickets we hand out; lets find that record + # in the DB, just to verify. + # + if (! $nosig) { + my $query_result = + DBQueryWarn("select * from geni_tickets where idx='$seqno'"); + if (!$query_result || !$query_result->numrows) { + print STDERR "Could not find the ticket $seqno in the DB\n"; + return undef; + } + $self->{'idx'} = $seqno; + $self->{'stored'} = 1; + } bless($self, $class); return $self; } # -# Might have to delete this fron the DB, as with an error handing out a ticket. +# Might have to delete this from the DB, as with an error handing out +# a ticket. # sub Delete($) { @@ -195,11 +269,13 @@ sub Delete($) return -1 if (! ref($self)); - if (defined($self->idx())) { + if ($self->stored()) { my $idx = $self->idx(); DBQueryWarn("delete from geni_tickets where idx='$idx'") or return -1; + + delete($tickets{"$idx"}); } return 0; } @@ -224,17 +300,31 @@ sub Grant($$) # so we have a record of them. We store them on the server and the client # side. # -sub Store($$) +sub Store($) { - my ($self, $idx) = @_; + my ($self) = @_; my @insert_data = (); + my $idx = $self->idx(); + my $seqno = $self->seqno(); my $slice_uuid = $self->slice_uuid(); my $owner_uuid = $self->owner_uuid(); + # + # For a locally created/signed ticket, seqno=idx. For a ticket from + # another component, we have to generate a locally unique idx for + # the DB insertion. + # + $idx = TBGetUniqueIndex('next_ticket', 1) + if (!defined($idx)); + # A locally generated ticket will not have a component. Might change that. + push(@insert_data, "component_idx=" . $self->component()->idx()) + if (defined($self->component())); + # Now tack on other stuff we need. push(@insert_data, "created=now()"); push(@insert_data, "idx='$idx'"); + push(@insert_data, "seqno='$seqno'"); push(@insert_data, "slice_uuid='$slice_uuid'"); push(@insert_data, "owner_uuid='$owner_uuid'"); @@ -245,15 +335,14 @@ sub Store($$) DBQueryWarn("insert into geni_tickets set " . join(",", @insert_data)) or return -1; - # If sucessfully stored, set the idx field so we know. - $self->{'idx'} = $idx; - + $tickets{"$idx"} = $self; + $self->{'stored'} = 1; return 0; } # # Sign the ticket before returning it. We capture the output, which is -# in XML. +# in XML. # sub Sign($) { @@ -262,10 +351,7 @@ sub Sign($) return -1 if (!ref($self)); - # Every Ticket gets a new unique index, which is used in the xml:id below. - # Also used for the DB insertion below. - my $idx = TBGetUniqueIndex('next_ticket', 1); - + my $idx = $self->seqno(); my $slice_cert = $self->slice_cert(); my $owner_cert = $self->owner_cert(); my $rspec_xml = XMLout($self->rspec(), "NoAttr" => 1); @@ -312,7 +398,7 @@ sub Sign($) } $self->{'ticket_string'} = $ticket; - $self->Store($idx) == 0 + $self->Store() == 0 or return -1; unlink($filename); @@ -343,17 +429,23 @@ sub Release($) if (! ref($self)); my $experiment = Experiment->Lookup($self->slice_uuid()); - my $node_id = $self->rspec()->{'node_id'}; - my $node = Node->Lookup($node_id); - return -1 - if (!defined($node)); - my $reservation = Node->Reservation(); - - if (defined($reservation) && $reservation->SameExperiment($experiment)) { - my $pid = $experiment->pid(); - my $eid = $experiment->eid(); - - system("$NFREE $pid $eid $node_id"); + my $pid = $experiment->pid(); + my $eid = $experiment->eid(); + my @nodeids = (); + + foreach my $resource_uuid (keys(%{$self->rspec()->{'node'}})) { + my $node = Node->Lookup($resource_uuid); + next + if (!defined($node)); + + my $reservation = $node->Reservation(); + if (defined($reservation) && + $reservation->SameExperiment($experiment)) { + push(@nodeids, $node->node_id()); + } + } + if (@nodeids) { + system("$NFREE $pid $eid @nodeids"); } $self->Delete(); return 0; diff --git a/protogeni/lib/test.pl.in b/protogeni/lib/test.pl.in index e4130f9ac82e61c096e8053c526c63fb95807c63..81a220df87d97e0cda40fc8cd13488eca443cea7 100644 --- a/protogeni/lib/test.pl.in +++ b/protogeni/lib/test.pl.in @@ -44,10 +44,13 @@ $geniuser->Register() == 0 # # Another user, for testing binding users to slices. # -my $rricci = GeniUser->CreateFromLocal(User->Lookup("rricci")); -if (!defined($rricci)) { - die("Could not create a geni user from local user rricci\n"); +my $geniuser2 = GeniUser->CreateFromLocal(User->Lookup("leebee")); +if (!defined($geniuser2)) { + die("Could not create a geni user from local user leebee\n"); } +# Register at the ClearingHouse. +$geniuser2->Register() == 0 + or die("Could not register $geniuser2 at the Geni ClearingHouse.\n"); # # See if there is a local slice record. If not, create one, then @@ -59,20 +62,14 @@ if (!defined($slice)) { if (!defined($slice)) { die("Could not create a local slice record for $experiment\n"); } - if ($slice->Register() != 0) { - $slice->Delete(); - die("Could not register slice at Geni ClearingHouse.\n"); - } } - -# -# Discover resources appropriate for the slice (experiment). This is -# due to change when there is a discovery service at the clearing house. -# For now, we get back a list of components. -# -$slice->DiscoverResources(\@components) == 0 or - die("Could not discover resources for $slice\n"); -print Dumper(@components); +if ($slice->Register() != 0) { + $slice->Delete(); + die("Could not register slice at Geni ClearingHouse.\n"); +} +if ($slice->BindUser($geniuser2) != 0) { + die("Could not bind $geniuser2 to slice at Geni ClearingHouse.\n"); +} # # Generate a credential for resource discovery on components. The credential @@ -87,6 +84,15 @@ if ($credential->Sign($GeniCredential::LOCALSA_FLAG)) { die("Could not sign slice credential!\n"); } +# +# Discover resources appropriate for the slice (experiment). This is +# due to change when there is a discovery service at the clearing house. +# For now, we get back a list of components. +# +$slice->DiscoverResources(\@components) == 0 or + die("Could not discover resources for $slice\n"); +print Dumper(@components); + # # Discover resources on each component. This stuff is just a placeholder # for something else later. For now, we just pass the rspec right back @@ -100,7 +106,6 @@ foreach my $component (@components) { die("Could not discover resources on $component\n"); } push(@resources, $rspec); - print Dumper($rspec); } my $rspec = $resources[0]; print Dumper($rspec); @@ -160,14 +165,12 @@ if (!defined($sliver)) { if (defined($sliver)) { print Dumper($sliver); - $sliver->BindUser($rricci); # Wait for input before proceeding. $_ = ; $sliver->Start($this_user); $_ = ; - $sliver->UnBindUser($rricci); $sliver->Destroy($this_user); } diff --git a/protogeni/xmlrpc/Genixmlrpc.pm.in b/protogeni/xmlrpc/Genixmlrpc.pm.in index 2db4ad88ec5492a3adc32ee24c40641f63f7dfbf..7d8fdc79579cdd1cb43ebd832bba3599ffa066f9 100644 --- a/protogeni/xmlrpc/Genixmlrpc.pm.in +++ b/protogeni/xmlrpc/Genixmlrpc.pm.in @@ -84,7 +84,7 @@ sub CallMethodHTTP($$$@) my $request = new RPC::XML::request($method, @args); if ($debug > 1) { - print STDERR "xml request: " . $request->as_string(); + print STDERR "xml request: $httpURL:" . $request->as_string(); print STDERR "\n"; } diff --git a/protogeni/xmlrpc/protogeni-ch.pl.in b/protogeni/xmlrpc/protogeni-ch.pl.in index fd6f50b024fe8808fbdec52c64f798a776853206..53ac06e20a055d4b6e53cdedc0fd15135f93cf08 100755 --- a/protogeni/xmlrpc/protogeni-ch.pl.in +++ b/protogeni/xmlrpc/protogeni-ch.pl.in @@ -13,6 +13,7 @@ use strict; use English; use Frontier::Responder; +use Data::Dumper; # Do this early so that we talk to the right DB. use vars qw($GENI_DBNAME); @@ -77,6 +78,14 @@ else { print $decoder->encode_fault(-1, "Invalid certificate; no UUID"); exit(0); } +# +# Reaching into the Frontier code so I can debug this crap. +# +my $request = Frontier::Responder::get_cgi_request(); +if (!defined($request)) { + print "Content-Type: text/txt\n\n"; + exit(0); +} # # Use libaudit to capture any output from libraries and programs. @@ -84,8 +93,13 @@ else { # LogStart(0); +# Add stuff for log message if sent. +AddAuditInfo("message", $request . "\n\n" . Dumper(%ENV)); + my $responder = Frontier::Responder->new( "methods" => { "CH::LookupUser" => \&GeniCH::LookupUser, + "CH::BindUser" => \&GeniCH::BindUser, + "CH::UnBindUser" => \&GeniCH::UnBindUser, "CH::RegisterUser" => \&GeniCH::RegisterUser, "CH::LookupSlice" => \&GeniCH::LookupSlice, "CH::CreateSliceName" => \&GeniCH::RegisterSlice, @@ -93,13 +107,18 @@ my $responder = Frontier::Responder->new( "methods" => { }, ); -my $response = $responder->answer(); +my $response = $responder->{'_decode'}->serve($request, + $responder->{'methods'}); # # Terminate the log capture so that we can print the response to STDOUT # for the web server. # +print STDERR "\n\n" . $response; + LogEnd(); -print $response; +print "Content-Type: text/xml \n\n" . $response; + + diff --git a/protogeni/xmlrpc/protogeni-cm.pl.in b/protogeni/xmlrpc/protogeni-cm.pl.in index be6d25b3adee18b6c50c0130370118fa64e3cda3..997a737aca5f3477a8e052982be26deedc4e9cbf 100644 --- a/protogeni/xmlrpc/protogeni-cm.pl.in +++ b/protogeni/xmlrpc/protogeni-cm.pl.in @@ -13,6 +13,7 @@ use strict; use English; use Frontier::Responder; +use Data::Dumper; # Do this early so that we talk to the right DB. use vars qw($GENI_DBNAME); @@ -78,6 +79,14 @@ else { print $decoder->encode_fault(-1, "Invalid certificate; no UUID"); exit(0); } +# +# Reaching into the Frontier code so I can debug this crap. +# +my $request = Frontier::Responder::get_cgi_request(); +if (!defined($request)) { + print "Content-Type: text/txt\n\n"; + exit(0); +} # # Use libaudit to capture any output from libraries and programs. @@ -85,6 +94,9 @@ else { # LogStart(0); +# Add stuff for log message if sent. +AddAuditInfo("message", $request . "\n\n" . Dumper(%ENV)); + my $responder = Frontier::Responder->new( "methods" => { "CM::DiscoverResources" => \&GeniCM::DiscoverResources, "CM::GetTicket" => \&GeniCM::GetTicket, @@ -96,7 +108,8 @@ my $responder = Frontier::Responder->new( "methods" => { }, ); -my $response = $responder->answer(); +my $response = $responder->{'_decode'}->serve($request, + $responder->{'methods'}); # # Terminate the log capture so that we can print the response to STDOUT @@ -104,5 +117,4 @@ my $response = $responder->answer(); # LogEnd(); -print $response; - +print "Content-Type: text/xml \n\n" . $response;