All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit d302bf98 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Checkpoint

parent 434ad9ae
...@@ -123,10 +123,10 @@ CREATE TABLE `geni_slivers` ( ...@@ -123,10 +123,10 @@ CREATE TABLE `geni_slivers` (
`resource_type` varchar(40) NOT NULL default '', `resource_type` varchar(40) NOT NULL default '',
`created` datetime default NULL, `created` datetime default NULL,
`credential_idx` int(10) unsigned default NULL, `credential_idx` int(10) unsigned default NULL,
`ticket_idx` int(10) unsigned default NULL, `component_uuid` varchar(40) default NULL,
`component_idx` int(10) unsigned NOT NULL default '0', `aggregate_uuid` varchar(40) default NULL,
`aggregate_idx` int(10) unsigned default NULL,
`status` enum('ready','broken') NOT NULL default 'ready', `status` enum('ready','broken') NOT NULL default 'ready',
`rspec_string` text,
PRIMARY KEY (`idx`), PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`), UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`) INDEX `slice_uuid` (`slice_uuid`)
...@@ -221,13 +221,11 @@ CREATE TABLE `geni_userkeys` ( ...@@ -221,13 +221,11 @@ CREATE TABLE `geni_userkeys` (
# #
DROP TABLE IF EXISTS `geni_resources`; DROP TABLE IF EXISTS `geni_resources`;
CREATE TABLE `geni_resources` ( CREATE TABLE `geni_resources` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`resource_uuid` varchar(40) NOT NULL default '', `resource_uuid` varchar(40) NOT NULL default '',
`resource_type` varchar(40) NOT NULL default '', `resource_type` varchar(40) NOT NULL default '',
`created` datetime default NULL, `created` datetime default NULL,
`component_idx` int(10) unsigned NOT NULL default '0', `component_uuid` varchar(40) NOT NULL default '',
PRIMARY KEY (`idx`), PRIMARY KEY (`resource_uuid`)
UNIQUE KEY `resource_uuid` (`resource_uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
# #
......
...@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm GeniSAClient.pm \ ...@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm GeniSAClient.pm \
GeniComponent.pm GeniCH.pm GeniCHClient.pm GeniEmulab.pm \ GeniComponent.pm GeniCH.pm GeniCHClient.pm GeniEmulab.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm
SCRIPTS = test.pl node.pl test2.pl addauthority SCRIPTS = test.pl addnode.pl test2.pl addauthority
OPS_LIBS = GeniCMClient.pm GeniSAClient.pm GeniCHClient.pm OPS_LIBS = GeniCMClient.pm GeniSAClient.pm GeniCHClient.pm
# #
......
...@@ -178,6 +178,8 @@ sub PrefixMatch($$) ...@@ -178,6 +178,8 @@ sub PrefixMatch($$)
my $uuid_prefix = $self->uuid_prefix(); my $uuid_prefix = $self->uuid_prefix();
print "$uuid, $uuid_prefix, $self\n";
if ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/) { if ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/) {
return 1 return 1
if ("$uuid_prefix" eq "$1"); if ("$uuid_prefix" eq "$1");
......
...@@ -325,7 +325,12 @@ sub Register($) ...@@ -325,7 +325,12 @@ sub Register($)
# #
# Need to verify the UUID is permitted for the SA making the request. # Need to verify the UUID is permitted for the SA making the request.
# #
if (! $authority->PrefixMatch($uuid)) { my $slice_authority = GeniAuthority->Lookup($ENV{'GENIUUID'});
if (!defined($slice_authority)) {
print STDERR "Could not find authority object for caller.\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
if (! $slice_authority->PrefixMatch($uuid)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef, return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"uuid: Prefix mismatch"); "uuid: Prefix mismatch");
} }
...@@ -355,7 +360,7 @@ sub Register($) ...@@ -355,7 +360,7 @@ sub Register($)
"uid: ". TBFieldErrorString()); "uid: ". TBFieldErrorString());
} }
my $newuser = GeniUser->Create($hrn, $uid, $uuid, my $newuser = GeniUser->Create($hrn, $uid, $uuid,
$name, $email, $cert, $authority, $name, $email, $cert, $slice_authority,
$keys); $keys);
if (!defined($newuser)) { if (!defined($newuser)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
...@@ -397,10 +402,16 @@ sub Register($) ...@@ -397,10 +402,16 @@ sub Register($)
# #
# Need to verify the UUID is permitted for the SA making the request. # Need to verify the UUID is permitted for the SA making the request.
# #
if (! $authority->PrefixMatch($uuid)) { my $slice_authority = GeniAuthority->Lookup($ENV{'GENIUUID'});
if (!defined($slice_authority)) {
print STDERR "Could not find authority object for caller.\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
if (! $slice_authority->PrefixMatch($uuid)) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef, return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"uuid: Prefix mismatch"); "uuid: Prefix mismatch");
} }
# #
# Make sure slice hrn and uuid are unique. # Make sure slice hrn and uuid are unique.
# #
...@@ -410,7 +421,7 @@ sub Register($) ...@@ -410,7 +421,7 @@ sub Register($)
} }
my $newslice = GeniSlice->Create($hrn, $uuid, $creator_uuid, my $newslice = GeniSlice->Create($hrn, $uuid, $creator_uuid,
$cert, $authority); $cert, $slice_authority);
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");
......
...@@ -54,6 +54,106 @@ my $AVAIL = "$TB/sbin/avail"; ...@@ -54,6 +54,106 @@ my $AVAIL = "$TB/sbin/avail";
my $TBSWAP = "$TB/bin/tbswap"; my $TBSWAP = "$TB/bin/tbswap";
my $SWAPEXP = "$TB/bin/swapexp"; my $SWAPEXP = "$TB/bin/swapexp";
#
# Respond to a GetTicket request.
#
sub Resolve($)
{
my ($argref) = @_;
my $uuid = $argref->{'uuid'};
my $hrn = $argref->{'hrn'};
my $cred = $argref->{'credential'};
my $type = $argref->{'type'};
if (! defined($cred)) {
return GeniResponse->MalformedArgsResponse();
}
if (! (defined($type) && ($type =~ /^(Node)$/))) {
return GeniResponse->MalformedArgsResponse();
}
# Allow lookup by uuid or hrn.
if (! (defined($uuid) || defined($hrn))) {
return GeniResponse->MalformedArgsResponse();
}
if (defined($uuid) && !($uuid =~ /^[-\w]*$/)) {
return GeniResponse->MalformedArgsResponse();
}
if (defined($hrn) && !($hrn =~ /^[-\w\.]*$/)) {
return GeniResponse->MalformedArgsResponse();
}
my $credential = GeniCredential->CreateFromSigned($cred);
if (!defined($credential)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not create GeniCredential object");
}
#
# Make sure the credential was issued to the caller, but no special
# permission required to resolve component resources.
#
if ($credential->owner_uuid() ne $ENV{'GENIUUID'}) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"This is not your credential!");
}
if ($type eq "Node") {
my $node;
if (defined($uuid)) {
$node= Node->Lookup($uuid);
}
else {
#
# We only want the last token for node lookup.
#
if ($hrn =~ /\./) {
($hrn) = ($hrn =~ /\.(\w*)$/);
}
$node= Node->Lookup($hrn);
}
if (!defined($node)) {
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED,
undef, "Nothing here by that name");
}
# Return a blob.
my $blob = { "hrn" => "${OURDOMAIN}." . $node->node_id(),
"uuid" => $node->uuid(),
};
#
# Get the list of interfaces for the node.
#
my @interfaces;
if ($node->AllInterfaces(\@interfaces) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not get interfaces for $uuid");
}
my @iblobs = ();
foreach my $interface (@interfaces) {
my $iblob = { "uuid" => $interface->uuid(),
"iface" => $interface->iface(),
"type" => $interface->type(),
"card" => $interface->card(),
"port" => $interface->port(),
"role" => $interface->role(),
"IP" => $interface->IP(),
"mask" => $interface->mask(),
"MAC" => $interface->mac(),
};
push(@iblobs, $iblob);
}
$blob->{'interfaces'} = \@iblobs
if (@iblobs);
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
return GeniResponse->Create(GENIRESPONSE_UNSUPPORTED);
}
# #
# Discover resources on this component, returning a resource availablity spec # Discover resources on this component, returning a resource availablity spec
# #
...@@ -111,7 +211,11 @@ sub DiscoverResources($) ...@@ -111,7 +211,11 @@ sub DiscoverResources($)
$xml .= "<node uuid=\"$uuid\" name=\"$nodeid\">". $xml .= "<node uuid=\"$uuid\" name=\"$nodeid\">".
"<available>true</available></node>\n"; "<available>true</available></node>\n";
my @interfaces = Interface->LookupAll($node); my @interfaces;
if ($node->AllInterfaces(\@interfaces) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not get interfaces for $uuid");
}
foreach my $interface (@interfaces) { foreach my $interface (@interfaces) {
my $iface_uuid = $interface->uuid(); my $iface_uuid = $interface->uuid();
my $iface = $interface->iface(); my $iface = $interface->iface();
...@@ -369,7 +473,7 @@ sub RedeemTicket($) ...@@ -369,7 +473,7 @@ sub RedeemTicket($)
next; next;
} }
} }
if (!$otheruser->BindToSlice($slice) != 0) { if ($otheruser->BindToSlice($slice) != 0) {
print STDERR "Could not bind $otheruser to $slice\n"; print STDERR "Could not bind $otheruser to $slice\n";
} }
} }
...@@ -393,13 +497,17 @@ sub RedeemTicket($) ...@@ -393,13 +497,17 @@ sub RedeemTicket($)
# #
my %slivers = (); my %slivers = ();
foreach my $ref (@{$ticket->rspec()->{'node'}}) { foreach my $ref (@{$ticket->rspec()->{'node'}}) {
my $virtualization_type = $ref->{'virtualization_type'};
my $resource_uuid = $ref->{'uuid'}; my $resource_uuid = $ref->{'uuid'};
my $node = Node->Lookup($resource_uuid); my $node = Node->Lookup($resource_uuid);
if (!defined($node)) { if (!defined($node)) {
$message = "Unknown resource_uuid in ticket: $resource_uuid"; $message = "Unknown resource_uuid in ticket: $resource_uuid";
goto bad; goto bad;
} }
my $sliver = GeniSliver::Node->Create($slice, $owner, $resource_uuid); my $sliver = GeniSliver::Node->Create($slice,
$owner->uuid(),
$resource_uuid,
$ref);
if (!defined($sliver)) { if (!defined($sliver)) {
$message = "Could not create GeniSliver object for $resource_uuid"; $message = "Could not create GeniSliver object for $resource_uuid";
goto bad; goto bad;
...@@ -451,8 +559,10 @@ sub RedeemTicket($) ...@@ -451,8 +559,10 @@ sub RedeemTicket($)
$message = "No such interface $iface on node $nodeobject"; $message = "No such interface $iface on node $nodeobject";
goto bad; goto bad;
} }
my $sliver = GeniSliver::Interface->Create($slice, $owner, my $sliver = GeniSliver::Interface->Create($slice,
$interface->uuid()); $owner->uuid(),
$interface->uuid(),
$ticket->rspec()->{'link'}->{$linkname});
if (!defined($sliver)) { if (!defined($sliver)) {
$message = "Could not create GeniSliver ". $message = "Could not create GeniSliver ".
"$interface in $linkname"; "$interface in $linkname";
......
...@@ -168,7 +168,7 @@ sub LookupByResource($$) ...@@ -168,7 +168,7 @@ sub LookupByResource($$)
if (! ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)); if (! ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/));
my $query_result = my $query_result =
DBQueryWarn("select component_idx from geni_resources ". DBQueryWarn("select component_uuid from geni_resources ".
"where resource_uuid='$uuid'"); "where resource_uuid='$uuid'");
return undef return undef
...@@ -189,15 +189,15 @@ sub NewResource($$) ...@@ -189,15 +189,15 @@ sub NewResource($$)
return -1 return -1
if (! ref($self)); if (! ref($self));
my $idx = TBGetUniqueIndex('next_resource', 1); my $component_uuid = $self->uuid();
my $component_idx = $self->idx();
$uuid = DBQuoteSpecial("$uuid"); $uuid = DBQuoteSpecial("$uuid");
return -1 return -1
if (! DBQueryWarn("replace into geni_resources set ". if (! DBQueryWarn("replace into geni_resources set ".
" idx=$idx, resource_uuid=$uuid, ". " resource_uuid=$uuid, ".
" resource_type='node', ". " resource_type='node', ".
" created=now(), component_idx=$component_idx")); " created=now(), ".
" component_uuid='$component_uuid'"));
return 0; return 0;
} }
...@@ -312,17 +312,12 @@ sub DiscoverResources($$$$$) ...@@ -312,17 +312,12 @@ sub DiscoverResources($$$$$)
# #
sub GetTicket($$$$$;$) sub GetTicket($$$$$;$)
{ {
my ($self, $slice, $rspec, $user, $credential, $vtopo) = @_; my ($self, $slice, $rspec_xml, $context, $credential, $vtopo) = @_;
my $rspec_xml = $rspec;
# Must be a real reference. # Must be a real reference.
return undef return undef
if (! ref($self)); if (! ref($self));
# The rspec is passed as XML. If we get a ref, convert it.
if (ref($rspec_xml)) {
$rspec_xml = XMLout($rspec_xml, RootName => "rspec");
}
my $args = { "credential" => $credential->asString(), my $args = { "credential" => $credential->asString(),
"impotent" => $impotent, "impotent" => $impotent,
"rspec" => $rspec_xml }; "rspec" => $rspec_xml };
...@@ -330,8 +325,7 @@ sub GetTicket($$$$$;$) ...@@ -330,8 +325,7 @@ sub GetTicket($$$$$;$)
if (defined($vtopo)); if (defined($vtopo));
my $response = my $response =
Genixmlrpc::CallMethodHTTP($self->url(), Genixmlrpc::CallMethod($self->url(), $context, "GetTicket", $args);
$user, "GetTicket", $args);
return undef return undef
if (!defined($response)); if (!defined($response));
...@@ -350,17 +344,17 @@ sub GetTicket($$$$$;$) ...@@ -350,17 +344,17 @@ sub GetTicket($$$$$;$)
# #
sub CreateSliver($$$$) sub CreateSliver($$$$)
{ {
my ($self, $slice, $ticket, $user) = @_; my ($self, $slice, $ticket, $context) = @_;
# Must be a real reference. # Must be a real reference.
return undef return undef
if (! ref($self)); if (! ref($self));
my $response = my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user, Genixmlrpc::CallMethod($self->url(), $context,
"RedeemTicket", "RedeemTicket",
{ "ticket" => $ticket->asString(), { "ticket" => $ticket->asString(),
"impotent" => $impotent }); "impotent" => $impotent });
return undef return undef
if (!defined($response)); if (!defined($response));
...@@ -377,8 +371,10 @@ sub CreateSliver($$$$) ...@@ -377,8 +371,10 @@ sub CreateSliver($$$$)
return undef; return undef;
} }
my $sliver = GeniSliver->Create($slice, $user, undef, undef, my $sliver = GeniSliver::Client->Create($slice, $ticket->owner_uuid(),
$credential, $self); $ticket->rspec(),
$credential, $self);
if (!defined($sliver)) { if (!defined($sliver)) {
print STDERR "Could not create local sliver object.\n"; print STDERR "Could not create local sliver object.\n";
return undef; return undef;
...@@ -391,7 +387,7 @@ sub CreateSliver($$$$) ...@@ -391,7 +387,7 @@ sub CreateSliver($$$$)
# #
sub DestroySliver($$$) sub DestroySliver($$$)
{ {
my ($self, $sliver, $user) = @_; my ($self, $sliver, $context) = @_;
# Must be a real reference. # Must be a real reference.
return -1 return -1
...@@ -402,11 +398,10 @@ sub DestroySliver($$$) ...@@ -402,11 +398,10 @@ sub DestroySliver($$$)
if (!defined($credential)); if (!defined($credential));
my $response = my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user, Genixmlrpc::CallMethod($self->url(), $context,
"DeleteSliver", "DeleteSliver",
{ "impotent" => $impotent, { "impotent" => $impotent,
"credential" => "credential" => $credential->asString() });
$credential->asString() });
if ($response->code() != GENIRESPONSE_SUCCESS) { if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not destroy sliver $sliver\n"; print STDERR "Could not destroy sliver $sliver\n";
...@@ -420,7 +415,7 @@ sub DestroySliver($$$) ...@@ -420,7 +415,7 @@ sub DestroySliver($$$)
# #
sub StartSliver($$$) sub StartSliver($$$)
{ {
my ($self, $sliver, $user) = @_; my ($self, $sliver, $context) = @_;
# Must be a real reference. # Must be a real reference.
return -1 return -1
...@@ -431,11 +426,10 @@ sub StartSliver($$$) ...@@ -431,11 +426,10 @@ sub StartSliver($$$)
if (!defined($credential)); if (!defined($credential));
my $response = my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user, Genixmlrpc::CallMethod($self->url(), $context,
"StartSliver", "StartSliver",
{ "impotent" => $impotent, { "impotent" => $impotent,
"credential" => "credential" => $credential->asString() });
$credential->asString() });
if ($response->code() != GENIRESPONSE_SUCCESS) { if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not start sliver $sliver\n"; print STDERR "Could not start sliver $sliver\n";
......
...@@ -54,6 +54,16 @@ sub AllocateSlivers($$$) ...@@ -54,6 +54,16 @@ sub AllocateSlivers($$$)
my ($class, $experiment, $nodelist) = @_; my ($class, $experiment, $nodelist) = @_;
my $thisuser = User->ThisUser(); my $thisuser = User->ThisUser();
#
# The RPC context for this test script is mostly as an SA.
#
Genixmlrpc->SetContext(Genixmlrpc->Context("@prefix@/etc/genisa.pem"));
#
# except when it has to be as the user.
#
my $context = Genixmlrpc->UserContext($thisuser);
# #
# Create a Geni user from current user doing the operation. # Create a Geni user from current user doing the operation.
# #
...@@ -105,7 +115,7 @@ sub AllocateSlivers($$$) ...@@ -105,7 +115,7 @@ sub AllocateSlivers($$$)
print STDERR "Could not sign slice credential $credential!\n"; print STDERR "Could not sign slice credential $credential!\n";
return -1; return -1;
} }
if ($credential->Store() == 0) { if ($credential->Store() != 0) {
print STDERR "Could not store slice credential $credential!\n"; print STDERR "Could not store slice credential $credential!\n";
return -1; return -1;
} }
...@@ -120,13 +130,28 @@ sub AllocateSlivers($$$) ...@@ -120,13 +130,28 @@ sub AllocateSlivers($$$)
# XXX We are still not using rspecs anywhere. # XXX We are still not using rspecs anywhere.
# #
foreach my $node (@{ $nodelist }) { foreach my $node (@{ $nodelist }) {
my $sliver_idx;
return -1
if ($node->GetGeniSliverInfo(\$sliver_idx) != 0);
next next
if ($node->genisliver_idx()); if ($sliver_idx);
#
# The node is a virtnode, but we want a ticket for the physnode.
#
my $physnode = Node->Lookup($node->phys_nodeid());
return -1
if (!defined($physnode));
my $node_uuid = $node->uuid(); my $node_uuid = $physnode->uuid();
my $rspec = {'node' => {$node_uuid =>
{"uuid" => $node_uuid}}};
my $rspec =
"<rspec xmlns=\"http://protogeni.net/resources/rspec/0.1\"> " .
" <node uuid=\"$node_uuid\" ".
" virtualization_type=\"emulab-vnode\"> " .
" </node>" .
"</rspec>";
# #
# XXX The component is stored in the geni_resources table. Not sure # XXX The component is stored in the geni_resources table. Not sure
# how that will work out. # how that will work out.
...@@ -141,7 +166,7 @@ sub AllocateSlivers($$$) ...@@ -141,7 +166,7 @@ sub AllocateSlivers($$$)
# Get ticket from component. # Get ticket from component.
# #
my $ticket = $component->GetTicket($slice, $rspec, my $ticket = $component->GetTicket($slice, $rspec,
$thisuser, $credential); $context, $credential);
if (!defined($ticket)) { if (!defined($ticket)) {
print STDERR "Could not get ticket from CM for $node\n"; print STDERR "Could not get ticket from CM for $node\n";
...@@ -165,7 +190,7 @@ sub AllocateSlivers($$$) ...@@ -165,7 +190,7 @@ sub AllocateSlivers($$$)
# since an rspec can have multiple resources (nodes, links), # since an rspec can have multiple resources (nodes, links),
# and I have not figured out what to do for that yet. # and I have not figured out what to do for that yet.
# #
if ($node->SetGeniSliverIDX($ticket->idx()) != 0) { if ($node->SetGeniSliverInfo($ticket->idx()) != 0) {
print STDERR "Could not set sliver (ticket) idx for $node\n"; print STDERR "Could not set sliver (ticket) idx for $node\n";
if ($ticket->Delete() != 0) { if ($ticket->Delete() != 0) {
print STDERR "Could not destroy $ticket\n"; print STDERR "Could not destroy $ticket\n";
...@@ -185,6 +210,16 @@ sub InstantiateSlivers($$$) ...@@ -185,6 +210,16 @@ sub InstantiateSlivers($$$)
my ($class, $experiment, $nodelist) = @_; my ($class, $experiment, $nodelist) = @_;
my $thisuser = User->ThisUser(); my $thisuser = User->ThisUser();