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` (
`resource_type` varchar(40) NOT NULL default '',
`created` datetime default NULL,
`credential_idx` int(10) unsigned default NULL,
`ticket_idx` int(10) unsigned default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
`aggregate_idx` int(10) unsigned default NULL,
`component_uuid` varchar(40) default NULL,
`aggregate_uuid` varchar(40) default NULL,
`status` enum('ready','broken') NOT NULL default 'ready',
`rspec_string` text,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
......@@ -221,13 +221,11 @@ CREATE TABLE `geni_userkeys` (
#
DROP TABLE IF EXISTS `geni_resources`;
CREATE TABLE `geni_resources` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`resource_uuid` varchar(40) NOT NULL default '',
`resource_type` varchar(40) NOT NULL default '',
`created` datetime default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`idx`),
UNIQUE KEY `resource_uuid` (`resource_uuid`)
`component_uuid` varchar(40) NOT NULL default '',
PRIMARY KEY (`resource_uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
#
......
......@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm GeniSAClient.pm \
GeniComponent.pm GeniCH.pm GeniCHClient.pm GeniEmulab.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
#
......
......@@ -178,6 +178,8 @@ sub PrefixMatch($$)
my $uuid_prefix = $self->uuid_prefix();
print "$uuid, $uuid_prefix, $self\n";
if ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/) {
return 1
if ("$uuid_prefix" eq "$1");
......
......@@ -325,7 +325,12 @@ sub Register($)
#
# 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,
"uuid: Prefix mismatch");
}
......@@ -355,7 +360,7 @@ sub Register($)
"uid: ". TBFieldErrorString());
}
my $newuser = GeniUser->Create($hrn, $uid, $uuid,
$name, $email, $cert, $authority,
$name, $email, $cert, $slice_authority,
$keys);
if (!defined($newuser)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
......@@ -397,10 +402,16 @@ sub Register($)
#
# 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,
"uuid: Prefix mismatch");
}
#
# Make sure slice hrn and uuid are unique.
#
......@@ -410,7 +421,7 @@ sub Register($)
}
my $newslice = GeniSlice->Create($hrn, $uuid, $creator_uuid,
$cert, $authority);
$cert, $slice_authority);
if (!defined($newslice)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"$hrn/$uuid could not be registered");
......
......@@ -54,6 +54,106 @@ my $AVAIL = "$TB/sbin/avail";
my $TBSWAP = "$TB/bin/tbswap";
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
#
......@@ -111,7 +211,11 @@ sub DiscoverResources($)
$xml .= "<node uuid=\"$uuid\" name=\"$nodeid\">".
"<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) {
my $iface_uuid = $interface->uuid();
my $iface = $interface->iface();
......@@ -369,7 +473,7 @@ sub RedeemTicket($)
next;
}
}
if (!$otheruser->BindToSlice($slice) != 0) {
if ($otheruser->BindToSlice($slice) != 0) {
print STDERR "Could not bind $otheruser to $slice\n";
}
}
......@@ -393,13 +497,17 @@ sub RedeemTicket($)
#
my %slivers = ();
foreach my $ref (@{$ticket->rspec()->{'node'}}) {
my $virtualization_type = $ref->{'virtualization_type'};
my $resource_uuid = $ref->{'uuid'};
my $node = Node->Lookup($resource_uuid);
if (!defined($node)) {
$message = "Unknown resource_uuid in ticket: $resource_uuid";
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)) {
$message = "Could not create GeniSliver object for $resource_uuid";
goto bad;
......@@ -451,8 +559,10 @@ sub RedeemTicket($)
$message = "No such interface $iface on node $nodeobject";
goto bad;
}
my $sliver = GeniSliver::Interface->Create($slice, $owner,
$interface->uuid());
my $sliver = GeniSliver::Interface->Create($slice,
$owner->uuid(),
$interface->uuid(),
$ticket->rspec()->{'link'}->{$linkname});
if (!defined($sliver)) {
$message = "Could not create GeniSliver ".
"$interface in $linkname";
......
......@@ -168,7 +168,7 @@ sub LookupByResource($$)
if (! ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/));
my $query_result =
DBQueryWarn("select component_idx from geni_resources ".
DBQueryWarn("select component_uuid from geni_resources ".
"where resource_uuid='$uuid'");
return undef
......@@ -189,15 +189,15 @@ sub NewResource($$)
return -1
if (! ref($self));
my $idx = TBGetUniqueIndex('next_resource', 1);
my $component_idx = $self->idx();
my $component_uuid = $self->uuid();
$uuid = DBQuoteSpecial("$uuid");
return -1
if (! DBQueryWarn("replace into geni_resources set ".
" idx=$idx, resource_uuid=$uuid, ".
" resource_uuid=$uuid, ".
" resource_type='node', ".
" created=now(), component_idx=$component_idx"));
" created=now(), ".
" component_uuid='$component_uuid'"));
return 0;
}
......@@ -312,17 +312,12 @@ sub DiscoverResources($$$$$)
#
sub GetTicket($$$$$;$)
{
my ($self, $slice, $rspec, $user, $credential, $vtopo) = @_;
my $rspec_xml = $rspec;
my ($self, $slice, $rspec_xml, $context, $credential, $vtopo) = @_;
# Must be a real reference.
return undef
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(),
"impotent" => $impotent,
"rspec" => $rspec_xml };
......@@ -330,8 +325,7 @@ sub GetTicket($$$$$;$)
if (defined($vtopo));
my $response =
Genixmlrpc::CallMethodHTTP($self->url(),
$user, "GetTicket", $args);
Genixmlrpc::CallMethod($self->url(), $context, "GetTicket", $args);
return undef
if (!defined($response));
......@@ -350,17 +344,17 @@ sub GetTicket($$$$$;$)
#
sub CreateSliver($$$$)
{
my ($self, $slice, $ticket, $user) = @_;
my ($self, $slice, $ticket, $context) = @_;
# Must be a real reference.
return undef
if (! ref($self));
my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user,
"RedeemTicket",
{ "ticket" => $ticket->asString(),
"impotent" => $impotent });
Genixmlrpc::CallMethod($self->url(), $context,
"RedeemTicket",
{ "ticket" => $ticket->asString(),
"impotent" => $impotent });
return undef
if (!defined($response));
......@@ -377,8 +371,10 @@ sub CreateSliver($$$$)
return undef;
}
my $sliver = GeniSliver->Create($slice, $user, undef, undef,
$credential, $self);
my $sliver = GeniSliver::Client->Create($slice, $ticket->owner_uuid(),
$ticket->rspec(),
$credential, $self);
if (!defined($sliver)) {
print STDERR "Could not create local sliver object.\n";
return undef;
......@@ -391,7 +387,7 @@ sub CreateSliver($$$$)
#
sub DestroySliver($$$)
{
my ($self, $sliver, $user) = @_;
my ($self, $sliver, $context) = @_;
# Must be a real reference.
return -1
......@@ -402,11 +398,10 @@ sub DestroySliver($$$)
if (!defined($credential));
my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user,
"DeleteSliver",
{ "impotent" => $impotent,
"credential" =>
$credential->asString() });
Genixmlrpc::CallMethod($self->url(), $context,
"DeleteSliver",
{ "impotent" => $impotent,
"credential" => $credential->asString() });
if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not destroy sliver $sliver\n";
......@@ -420,7 +415,7 @@ sub DestroySliver($$$)
#
sub StartSliver($$$)
{
my ($self, $sliver, $user) = @_;
my ($self, $sliver, $context) = @_;
# Must be a real reference.
return -1
......@@ -431,11 +426,10 @@ sub StartSliver($$$)
if (!defined($credential));
my $response =
Genixmlrpc::CallMethodHTTP($self->url(), $user,
"StartSliver",
{ "impotent" => $impotent,
"credential" =>
$credential->asString() });
Genixmlrpc::CallMethod($self->url(), $context,
"StartSliver",
{ "impotent" => $impotent,
"credential" => $credential->asString() });
if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not start sliver $sliver\n";
......
......@@ -54,6 +54,16 @@ sub AllocateSlivers($$$)
my ($class, $experiment, $nodelist) = @_;
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.
#
......@@ -105,7 +115,7 @@ sub AllocateSlivers($$$)
print STDERR "Could not sign slice credential $credential!\n";
return -1;
}
if ($credential->Store() == 0) {
if ($credential->Store() != 0) {
print STDERR "Could not store slice credential $credential!\n";
return -1;
}
......@@ -120,13 +130,28 @@ sub AllocateSlivers($$$)
# XXX We are still not using rspecs anywhere.
#
foreach my $node (@{ $nodelist }) {
my $sliver_idx;
return -1
if ($node->GetGeniSliverInfo(\$sliver_idx) != 0);
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 $rspec = {'node' => {$node_uuid =>
{"uuid" => $node_uuid}}};
my $node_uuid = $physnode->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
# how that will work out.
......@@ -141,7 +166,7 @@ sub AllocateSlivers($$$)
# Get ticket from component.
#
my $ticket = $component->GetTicket($slice, $rspec,
$thisuser, $credential);
$context, $credential);
if (!defined($ticket)) {
print STDERR "Could not get ticket from CM for $node\n";
......@@ -165,7 +190,7 @@ sub AllocateSlivers($$$)
# 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) {
if ($node->SetGeniSliverInfo($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";
......@@ -185,6 +210,16 @@ sub InstantiateSlivers($$$)
my ($class, $experiment, $nodelist) = @_;
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);
my $slice = GeniSlice->Lookup($experiment->uuid());
if (!defined($slice)) {
print STDERR "No slice exists for $experiment. \n";
......@@ -200,9 +235,13 @@ sub InstantiateSlivers($$$)
# XXX We are still not using rspecs anywhere.
#
foreach my $node (@{ $nodelist }) {
$sliver_idx = $node->genisliver_idx();
my $sliver_idx;
return -1
if ($node->GetGeniSliverInfo(\$sliver_idx) != 0);
next
if (! $sliver_idx);
my $sliver = GeniSliver->Lookup($sliver_idx);
my $sliver = GeniSliver->Lookup($sliver_idx);
next
if (defined($sliver));
......@@ -217,18 +256,18 @@ sub InstantiateSlivers($$$)
#
# Create sliver on component using the ticket.
#
my $sliver = $component->CreateSliver($slice, $ticket, $thisuser);
$sliver = $component->CreateSliver($slice, $ticket, $context);
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) {
if ($node->SetGeniSliverInfo(0) != 0) {
print STDERR "Could not clear sliver idx for $node\n";
}
return -1;
}
if ($node->SetGeniSliverIDX($sliver->idx()) != 0) {
if ($node->SetGeniSliverInfo($sliver->idx()) != 0) {
print STDERR "Could not set sliver idx for $node\n";
if ($ticket->Delete() != 0) {
print STDERR "Could not delete $ticket\n";
......@@ -246,6 +285,55 @@ sub InstantiateSlivers($$$)
return 0;
}
#
# Start the slivers.
#
sub StartSlivers($$$)
{
my ($class, $experiment, $nodelist) = @_;
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);
my $slice = GeniSlice->Lookup($experiment->uuid());
if (!defined($slice)) {
print STDERR "No slice exists for $experiment. \n";
return -1;
}
foreach my $node (@{ $nodelist }) {
my $sliver_idx;
return -1
if ($node->GetGeniSliverInfo(\$sliver_idx) != 0);
next
if (! $sliver_idx);
my $sliver = GeniSliver->Lookup($sliver_idx);
if (!defined($sliver)) {
print STDERR "Could not find sliver for $node in $experiment\n";
return -1;
}
my $component = $sliver->GetComponent();
#
# Create sliver on component using the ticket.
#
if ($component->StartSliver($slice, $sliver, $context) != 0) {
print STDERR "Could not start $sliver on $component for $node\n";
return -1;
}
}
return 0;
}
#
# XXX Need to deal with links between nodes.
#
......@@ -255,6 +343,16 @@ sub DestroySlivers($$$)
my $thisuser = User->ThisUser();
my $errors = 0;
#
# 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);
my $slice = GeniSlice->Lookup($experiment->uuid());
if (!defined($slice)) {
print STDERR "No local slice record for $experiment\n";
......@@ -267,10 +365,11 @@ sub DestroySlivers($$$)
# XXX We are still not using rspecs anywhere.
#
foreach my $node (@{ $nodelist }) {
my $sliver_idx;
return -1
if ($node->GetGeniSliverInfo(\$sliver_idx) != 0);
next
if (! $node->genisliver_idx());
$sliver_idx = $node->genisliver_idx();
if (! $sliver_idx);
my $sliver = GeniSliver->Lookup($sliver_idx);
if (!defined($sliver)) {
......@@ -287,12 +386,12 @@ sub DestroySlivers($$$)
}
next;
}
if ($sliver->Destroy != 0) {
if ($sliver->Destroy() != 0) {
print STDERR "Could not destroy $sliver for $node\n";
$errors++;
next;
}
if ($node->SetGeniSliverIDX(0) != 0) {
if ($node->SetGeniSliverInfo(0) != 0) {
print STDERR "Could not clear sliver idx for $node\n";
$errors++;
next;
......
This diff is collapsed.
......@@ -321,8 +321,10 @@ sub Store($)
# another component, we have to generate a locally unique idx for
# the DB insertion.
#
$idx = TBGetUniqueIndex('next_ticket', 1)
if (