Commit b63cb055 authored by Leigh Stoller's avatar Leigh Stoller

Big cleanup of GeniComponent stuff. Moved Resolve() into GeniComponent

since it has to be aware of the CM version. Add a Version() call to
GeniAuthority with goes asks the CM what version it is exporting.
Based on that, we know how to do a resolve of a component. Refactored
the code that was used in GeniAggregate when creating tunnels, since
that is where we have to Resolve components. This also turns up in
cooked mode.

Continuine moving towards a urn-only world. If a GeniAuthority or a
GeniComponent does not have the URN set locally in the DB, go back to
the clearinghouse and get it. Error if it is not known, and go bang on
the remote site to update and rerun register_resources.
parent 277f4a62
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniAggregate;
......@@ -25,6 +25,7 @@ use GeniSlice;
use GeniRegistry;
use GeniUtil;
use GeniUser;
use GeniComponent;
use GeniHRN;
use emutil;
use Lan;
......@@ -1295,52 +1296,23 @@ sub Create($$$$$$)
}
}
else {
my $component = GeniComponent->Lookup($node1rspec->{'component_uuid'});
my $blob;
my $node_uuid = $node1rspec->{'component_uuid'};
my $component = GeniComponent->CreateFromRegistry($node_uuid);
if (!defined($component)) {
#
# Need to ask the clearinghouse where this node comes from.
#
$clearinghouse = GeniRegistry::ClearingHouse->Create();
if ($clearinghouse->Resolve($node1rspec->{'component_uuid'},
"Component", \$blob) != 0) {
print STDERR "Could not lookup node at clearinghouse\n";
print STDERR Dumper($node1rspec);
goto bad;
}
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
goto bad
if (!defined($certificate));
$component = GeniComponent->CreateFromCertificate($certificate);
if (!defined($component)) {
print STDERR "Could not create component from $certificate\n";
goto bad;
}
}
my $credential = GeniRegistry::Client->CreateCredential($component);
if (!defined($credential)) {
print STDERR "Could not create a credential for $component\n";
print STDERR "Could not create component for $node_uuid\n";
goto bad;
}
my $registry = GeniRegistry::Client->Create($component, undef,
$credential);
if (!defined($registry)) {
print STDERR "Could not create a registry client for $component\n";
my $blob = $component->Resolve();
if (!defined($blob)) {
print STDERR "Could not Resolve $component\n";
goto bad;
}
$registry->Resolve($node1rspec->{'component_uuid'}, "Node", \$blob);
$ctrlip1 = $blob->{'physctrl'}
if (defined($blob) && exists($blob->{'physctrl'}));
if (!defined($ctrlip1)) {
print STDERR "Could not get control IP for ".
"$node1rspec->{'component_uuid'} at $component\n";
if (!exists($blob->{'physctrl'}) || !defined($blob->{'physctrl'})) {
print STDERR "Could not get control IP for $component\n";
goto bad;
}
$ctrlip1 = $blob->{'physctrl'};
}
if (defined($node2sliver)) {
my $node2 = Node->Lookup($node2sliver->resource_uuid());
......@@ -1359,51 +1331,23 @@ sub Create($$$$$$)
}
}
else {
my $blob;
my $component = GeniComponent->Lookup($node2rspec->{'component_uuid'});
if (!defined($component)) {
#
# Need to ask the clearinghouse where this node comes from.
#
$clearinghouse = GeniRegistry::ClearingHouse->Create();
my $node_uuid = $node2rspec->{'component_uuid'};
my $component = GeniComponent->CreateFromRegistry($node_uuid);
if ($clearinghouse->Resolve($node2rspec->{'component_uuid'},
"Component", \$blob) != 0) {
print STDERR "Could not lookup node at clearinghouse\n";
print STDERR Dumper($node2rspec);
goto bad;
}
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
goto bad
if (!defined($certificate));
$component = GeniComponent->CreateFromCertificate($certificate);
if (!defined($component)) {
print STDERR "Could not create component from $certificate\n";
goto bad;
}
}
my $credential = GeniRegistry::Client->CreateCredential($component);
if (!defined($credential)) {
print STDERR "Could not create a credential for $component\n";
if (!defined($component)) {
print STDERR "Could not create component for $node_uuid\n";
goto bad;
}
my $registry = GeniRegistry::Client->Create($component, undef,
$credential);
if (!defined($registry)) {
print STDERR "Could not create a registry client for $component\n";
my $blob = $component->Resolve();
if (!defined($blob)) {
print STDERR "Could not Resolve $component\n";
goto bad;
}
$registry->Resolve($node2rspec->{'component_uuid'}, "Node", \$blob);
$ctrlip2 = $blob->{'physctrl'}
if (defined($blob) && exists($blob->{'physctrl'}));
if (!defined($ctrlip2)) {
print STDERR "Could not get control IP for ".
"$node2rspec->{'component_uuid'} at $component\n";
if (!exists($blob->{'physctrl'}) || !defined($blob->{'physctrl'})) {
print STDERR "Could not get control IP for $component\n";
goto bad;
}
$ctrlip2 = $blob->{'physctrl'};
}
# print STDERR "$ip1, $ip2, $ctrlip1, $ctrlip2\n";
......
......@@ -20,6 +20,8 @@ use vars qw(@ISA @EXPORT);
use GeniDB;
use GeniRegistry;
use GeniHRN;
use Genixmlrpc;
use GeniResponse;
use emutil qw(TBGetUniqueIndex);
use English;
use overload ('""' => 'Stringify');
......@@ -52,26 +54,11 @@ sub Lookup($$)
$query_result =
DBQueryWarn("select uuid from geni_authorities ".
"where urn='$token'");
if( $query_result && $query_result->numrows ) {
($uuid) = $query_result->fetchrow_array();
} else {
# Fallback for backward compatibility (hunt for an
# authority in the database that was never registered with
# a URN). This is ugly and fragile and needs to go away
# as soon as all authorities have re-registered with URNs.
my ($auth,$t,$id) = GeniHRN::Parse($token);
my $regexp = "/.[-[:alnum:]]+.${auth}";
$regexp =~ s/\./\\\./g;
$query_result =
DBQueryWarn("select uuid from geni_authorities ".
"where url regexp '$regexp' and ".
" type='$id'");
return undef
if (! $query_result || !$query_result->numrows);
($uuid) = $query_result->fetchrow_array();
}
return undef
if (! $query_result || !$query_result->numrows);
($uuid) = $query_result->fetchrow_array();
}
elsif ($token =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/) {
$uuid = $token;
......@@ -105,6 +92,7 @@ sub Lookup($$)
my $self = {};
$self->{'AUTHORITY'} = $query_result->fetchrow_hashref();
$self->{'version'} = undef;
bless($self, $class);
#
......@@ -188,6 +176,7 @@ sub url($) { return field($_[0], "url"); }
sub hrn($) { return field($_[0], "hrn"); }
sub type($) { return field($_[0], "type"); }
sub disabled($) { return field($_[0], "disabled"); }
sub version($) { return field($_[0], "version"); }
sub cert($) { return $_[0]->{'CERT'}->cert(); }
sub GetCertificate($) { return $_[0]->{'CERT'}; }
......@@ -257,6 +246,10 @@ sub CreateFromRegistry($$$)
{
my ($class, $type, $name) = @_;
my $authority = GeniAuthority->Lookup($name);
return $authority
if (defined($authority) && $authority->urn());
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
if (!defined($clearinghouse));
......@@ -269,15 +262,55 @@ sub CreateFromRegistry($$$)
return undef
if (!defined($certificate));
my $authority = GeniAuthority->Create($certificate,
$blob->{'url'},
$blob->{'type'});
#
# At this point, we do not support non-urn sites. They must re-register.
#
my $urn = $certificate->urn();
if (!defined($urn)) {
print STDERR "GeniAuthority::CreateFromRegistry: ".
"$certificate does not have a urn.\n";
$certificate->Delete();
return undef;
}
$authority = GeniAuthority->Create($certificate,
$blob->{'url'},
$blob->{'type'});
$certificate->Delete()
if (!defined($authority));
return $authority;
}
#
# Get Version. Ask the Authority what version it is running.
#
sub Version($)
{
my ($self) = @_;
return $self->version()
if (defined($self->version()));
#
# The caller had to set up the xmlrpc context.
#
my $response =
Genixmlrpc::CallMethod($self->url(), undef, "GetVersion");
if (!defined($response)) {
print STDERR "*** Internal error getting version for $self\n";
return undef;
}
if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not get version for $self Error: ";
print STDERR " " . $response->output() . "\n";
return undef;
}
$self->{'version'} = $response->value();
return $response->value();
}
#
# Does the uuid prefix match.
#
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniComponent;
......@@ -23,6 +23,7 @@ use GeniRegistry;
use GeniTicket;
use GeniCredential;
use GeniAuthority;
use GeniHRN;
use emutil qw(TBGetUniqueIndex);
use English;
use overload ('""' => 'Stringify');
......@@ -54,7 +55,16 @@ sub Lookup($$)
my $query_result;
my $uuid;
if ($token =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/) {
if (GeniHRN::IsValid($token)) {
$query_result =
DBQueryWarn("select uuid from geni_certificates ".
"where urn='$token'");
return undef
if (!$query_result || !$query_result->numrows);
($uuid) = $query_result->fetchrow_array();
}
elsif ($token =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/) {
$uuid = $token;
}
elsif ($token =~ /^[-\w\.]*$/) {
......@@ -120,9 +130,9 @@ sub Stringify($)
{
my ($self) = @_;
my $uuid = $self->uuid();
my $urn = $self->urn();
return "[GeniComponent: $uuid]";
return "[GeniComponent: $urn]";
}
#
......@@ -168,6 +178,19 @@ sub cert($) { return $_[0]->{'CERT'}->cert(); }
sub GetCertificate($) { return $_[0]->{'CERT'}; }
sub GetManager($) { return $_[0]->{'MANAGER'}; }
#
# Return the URN. This is complicated by the fact that the DB does not
# store the urn, but is in the certificate. Further, it might be a
# Component from a CM not doing URNs yet, in which case set it to the
# uuid and hope for the best.
#
sub urn($)
{
my ($self) = @_;
return $self->GetCertificate()->urn();
}
#
# Delete a component from the DB.
#
......@@ -258,7 +281,13 @@ sub Update($$)
#
sub CreateFromRegistry($$)
{
my ($class, $uuid) = @_;
my ($class, $token) = @_;
my $component = GeniComponent->Lookup($token);
# We want to reload if urn/uuid not set properly
return $component
if (defined($component) &&
$component->urn() && $component->manager_uuid());
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
......@@ -266,17 +295,57 @@ sub CreateFromRegistry($$)
my $blob;
return undef
if ($clearinghouse->Resolve($uuid, "Component", \$blob) != 0);
if ($clearinghouse->Resolve($token, "Component", \$blob) != 0);
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
if (!defined($certificate));
my $component = GeniComponent->Create($certificate);
$certificate->Delete()
if (!defined($component));
my $manager_certificate =
GeniCertificate->LoadFromString($blob->{'manager_gid'});
if (!defined($certificate)) {
goto bad;
}
#
# At this point, we do not support non-urn sites. They must re-register.
#
my $urn = $certificate->urn();
if (!defined($urn)) {
print STDERR "GeniComponent::CreateFromRegistry: ".
"$certificate does not have a urn.\n";
goto bad;
}
#
# Create the manager authority as well.
#
my $manager_urn = $manager_certificate->urn();
if (!defined($manager_urn)) {
print STDERR "GeniComponent::CreateFromRegistry: ".
"$manager_certificate does not have a urn.\n";
goto bad;
}
my $manager = GeniAuthority->CreateFromRegistry("CM", $manager_urn);
if (!defined($manager)) {
print STDERR "GeniComponent::CreateFromRegistry: ".
"could not create authority $manager_urn\n";
}
$component = GeniComponent->Create($certificate, $manager);
if (!defined($component)) {
print STDERR "GeniComponent::CreateFromRegistry: ".
"could not create component from $certificate\n";
goto bad;
}
return $component;
bad:
$certificate->Delete()
if (defined($certificate));
$manager_certificate->Delete()
if (defined($manager_certificate));
return undef;
}
#
......@@ -293,6 +362,61 @@ sub CreateFromCertificate($$;$)
return $component;
}
#
# Resolve a component (at its CM).
#
sub Resolve($)
{
my ($self) = @_;
my $authority = GeniAuthority->Lookup($self->manager_uuid());
if (!defined($authority)) {
$authority =
GeniAuthority->CreateFromRegistry("CM", $self->manager_uuid());
if (!defined($authority)) {
print STDERR "Could not create registry credential for $self\n";
return undef;
}
}
my $manager_version = $authority->Version();
return undef
if (!defined($manager_version));
my $credential = GeniRegistry::Client->CreateCredential($self);
if (!defined($credential)) {
print STDERR "Could not create registry credential for $self\n";
return undef;
}
my $method_args;
if ($manager_version == 1.0) {
$method_args->{'credential'} = $credential->asString();
$method_args->{'uuid'} = $self->uuid();
$method_args->{'type'} = "node";
}
elsif ($manager_version == 2.0) {
$method_args->{'credentials'} = [$credential->asString()];
$method_args->{'urn'} = $self->urn();
}
else {
print STDERR "GeniComponent::Resolve: Unknown version at $authority\n";
return undef;
}
my $response =
Genixmlrpc::CallMethod($authority->url(),
undef, "Resolve", $method_args);
if (!defined($response)) {
print STDERR "*** Internal error Resolving $self at $authority\n";
return undef;
}
if ($response->code() != GENIRESPONSE_SUCCESS) {
print STDERR "Could not resolve $self at $authority Error:";
print STDERR " " . $response->output() . "\n";
return undef;
}
return $response->value();
}
#
# Delete all components for a CM.
#
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniEmulab;
......@@ -185,13 +185,10 @@ sub CreatePhysNode($)
#
Genixmlrpc->SetContext($context);
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("CM", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "Could not lookup $manager_urn at ClearingHouse\n";
return undef;
}
print STDERR "Could not lookup $manager_urn at ClearingHouse\n";
return undef;
}
#
......@@ -202,19 +199,14 @@ sub CreatePhysNode($)
# print STDERR "$node_hrn\n";
my $component = GeniComponent->Lookup($node_hrn);
if (defined($component)) {
my $node = Node->Lookup($component->uuid());
return $node
if (defined($node));
}
else {
$component = GeniComponent->CreateFromRegistry($node_urn);
if (!defined($component)) {
print STDERR "Could not lookup $node_urn at ClearingHouse\n";
return undef;
}
my $component = GeniComponent->CreateFromRegistry($node_urn);
if (!defined($component)) {
print STDERR "Could not lookup $node_urn at ClearingHouse\n";
return undef;
}
my $node = Node->Lookup($component->uuid());
return $node
if (defined($node));
print STDERR "Creating local node for $node_urn\n";
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2009 University of Utah and the Flux Group.
# Copyright (c) 2009-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniHRN;
use strict;
use Exporter;
use Carp;
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
......@@ -53,6 +54,11 @@ sub IsValid($)
{
my ($hrn) = @_;
if (!defined($hrn)) {
carp("GeniHRN::IsValid: hrn is undefined");
return 0;
}
# Reject %00 sequences (see RFC 3986, section 7.3).
return undef if $hrn =~ /%00/;
......@@ -146,6 +152,10 @@ sub Parse($)
{
my ($hrn) = @_;
if (!defined($hrn)) {
carp("GeniHRN::Parse: hrn is undefined");
return 0;
}
return undef if !IsValid( $hrn );
$hrn = Unescape( $hrn );
......@@ -238,6 +248,10 @@ sub ParseInterface($)
{
my ($urn) = @_;
if (!defined($urn)) {
carp("GeniHRN::ParseInterface: urn is undefined");
return 0;
}
my ($authority,$type,$id) = Parse( $urn );
return undef if $type ne "interface";
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniResource;
......@@ -388,13 +388,10 @@ sub GetTicket($$$$)
#
Genixmlrpc->SetContext($context);
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -534,13 +531,10 @@ sub RedeemTicket($$)
#
Genixmlrpc->SetContext($context);
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -726,13 +720,10 @@ sub Clear($$)
#
Genixmlrpc->SetContext($context);
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -862,13 +853,10 @@ sub Purge($$)
return -1;
}
my $manager_urn = $self->manager_urn();
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -980,13 +968,10 @@ sub StartSliver($$$)
return -1;
}
my $manager_urn = $self->manager_urn();
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -1071,13 +1056,10 @@ sub SliverStatus($$$$)
return -1;
}
my $manager_urn = $self->manager_urn();
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......@@ -1132,13 +1114,10 @@ sub Discover($$$)
return -1;
}
my $manager_urn = $self->manager_urn();
my $authority = GeniAuthority->Lookup($manager_urn);
my $authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
$authority = GeniAuthority->CreateFromRegistry("cm", $manager_urn);
if (!defined($authority)) {
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
print STDERR "*** Could not find $manager_urn at ClearingHouse\n";
return -1;
}
#
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use lib '@prefix@/lib';
use Genixmlrpc;
use GeniResponse;
use GeniUser;
use GeniCredential;
use GeniComponent;
use English;
# Hate to import all this crap; need a utility library.
use libdb qw(TBGetUniqueIndex);
use Node;
use Interface;
use Experiment;
use Data::Dumper;
if (@ARGV != 2) {
die("Bad arguments\n");
}
my $remote_node_id = $ARGV[0];
my $local_node_id = $ARGV[1];