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 39956369 authored by Leigh B Stoller's avatar Leigh B Stoller

Checkpoint SFA support. Not fully working. Also some cleanup

to the GeniRegistry file; move the slice part back into GeniSlice
where it belongs.
parent 5b9b03a7
This diff is collapsed.
......@@ -66,9 +66,8 @@ sub Lookup($$)
$uuid = $token;
}
elsif ($token =~ /^P([\w]+)$/) {
# Only SAs are looked up this way.
# This will be flushed after URNs are fully pushed out.
return GeniAuthority->LookupByPrefix($1);
print STDERR "Deprecated authority lookup by prefix\n";
return undef;
}
elsif ($token =~ /^[\w\.]*$/) {
$query_result =
......@@ -94,9 +93,7 @@ sub Lookup($$)
my $self = {};
$self->{'AUTHORITY'} = $query_result->fetchrow_hashref();
$self->{'version'} = undef;
$self->{'apilevel'} = undef;
$self->{'api'} = undef;
$self->{'_version_info'} = undef;
bless($self, $class);
#
......@@ -180,9 +177,12 @@ 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 $_[0]->{"version"}; }
sub apilevel($) { return $_[0]->{"apilevel"}; }
sub api($) { return $_[0]->{"api"}; }
sub _version_info($) { return $_[0]->{"_version_info"}; }
sub version($) { return $_[0]->VersionInfo()->{"version"}; }
sub apilevel($) { return $_[0]->VersionInfo()->{"apilevel"}; }
sub api($) { return $_[0]->VersionInfo()->{"api"}; }
sub issfa($) { return $_[0]->VersionInfo()->{"issfa"}; }
sub versiondata($) { return $_[0]->VersionInfo()->{"versiondata"}; }
sub cert($) { return $_[0]->{'CERT'}->cert(); }
sub GetCertificate($) { return $_[0]->{'CERT'}; }
......@@ -266,6 +266,8 @@ sub CheckExisting($$)
#
# Create authority from the ClearingHouse, by looking up the info.
# All authorities are currently stored in the Utah Emulab ClearingHouse,
# at least until we can deal with multiple clearinghouses/registries.
#
sub CreateFromRegistry($$$)
{
......@@ -310,12 +312,12 @@ sub CreateFromRegistry($$$)
#
# Get Version. Ask the Authority what version it is running.
#
sub Version($)
sub VersionInfo($)
{
my ($self) = @_;
return $self->version()
if (defined($self->version()));
return $self->_version_info()
if (defined($self->_version_info()));
#
# The caller had to set up the xmlrpc context.
......@@ -332,38 +334,49 @@ sub Version($)
print STDERR " " . $response->output() . "\n";
return undef;
}
my $ref = {"versiondata" => $response->value() };
if (ref($response->value())) {
# Look for the AM interface.
if (exists($response->value()->{'geni_api'})) {
$self->{'version'} = $response->value()->{'geni_api'};
$ref->{'version'} = $response->value()->{'geni_api'};
# This was wrong; it should be 2.0 not 1.0
$self->{'version'} = 2.0 if ($self->{'version'} == 1.0);
$self->{'apilevel'} = 0;
$self->{'api'} = "AM";
$ref->{'version'} = 2.0 if ($ref->{'version'} == 1.0);
$ref->{'apilevel'} = 0;
$ref->{'api'} = "AM";
$ref->{'issfa'} = exists($response->value()->{'sfa'});
}
else {
$self->{'version'} = $response->value()->{'api'};
$self->{'apilevel'} = $response->value()->{'level'};
$self->{'api'} = "CM";
$ref->{'version'} = $response->value()->{'api'};
$ref->{'apilevel'} = $response->value()->{'level'};
$ref->{'api'} = "CM";
$ref->{'issfa'} = 0;
}
}
else {
$self->{'version'} = $response->value();
$self->{'apilevel'} = 1;
$self->{'api'} = "CM";
$ref->{'version'} = $response->value();
$ref->{'apilevel'} = 1;
$ref->{'api'} = "CM";
$ref->{'issfa'} = 0;
}
return $self->{'version'};
$self->{'_version_info'} = $ref;
return $ref;
}
# Ditto for the API level
sub ApiLevel($)
sub Version($)
{
my ($self) = @_;
return $self->apilevel()
if (defined($self->apilevel()));
return undef
if (!defined($self->VersionInfo()));
return $self->version();
}
sub ApiLevel($)
{
my ($self) = @_;
return undef
if (!defined($self->Version()));
if (!defined($self->VersionInfo()));
return $self->apilevel();
}
......@@ -371,14 +384,20 @@ sub Api($)
{
my ($self) = @_;
return $self->api()
if (defined($self->api()));
return undef
if (!defined($self->Version()));
if (!defined($self->VersionInfo()));
return $self->api();
}
sub IsSFA($)
{
my ($self) = @_;
return undef
if (!defined($self->VersionInfo()));
return $self->issfa();
}
#
# Check that the authority is the issuer of the given certificate.
......@@ -460,6 +479,21 @@ sub LookupByPrefix($$)
return GeniAuthority->Lookup($uuid);
}
#
# Set the disabled bit.
#
sub Disable($)
{
my ($self) = @_;
my $urn = $self->urn();
DBQueryWarn("update geni_authorities set disabled=1 ".
"where urn='$urn'")
or return -1;
return 0;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -19,7 +19,7 @@ use vars qw(@ISA @EXPORT);
#use Devel::TraceUse;
use GeniDB;
use Genixmlrpc;
use GeniRegistry;
use GeniSlice;
use GeniResponse;
use GeniUser;
use GeniComponent;
......@@ -268,21 +268,7 @@ sub Resolve($)
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
if ($type eq "sa") {
my $authority = GeniAuthority->Lookup($lookup_token);
if (!defined($authority)) {
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such authority $lookup_token");
}
# Return a blob.
my $blob = { "gid" => $authority->cert(),
"url" => $authority->url(),
"urn" => $authority->urn(),
"type" => $authority->type(),
};
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
if ($type eq "cm" || $type eq "am") {
if ($type eq "cm" || $type eq "am" || $type eq "sa") {
my $manager = GeniAuthority->Lookup($lookup_token);
if (!defined($manager)) {
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
......@@ -309,7 +295,7 @@ sub Resolve($)
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
if ($type eq "slice") {
my $slice = GeniRegistry::GeniSlice->Lookup($lookup_token);
my $slice = GeniSlice->Lookup($lookup_token);
if (!defined($slice)) {
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such slice $lookup_token");
......@@ -702,7 +688,7 @@ sub Remove($)
"$token has been unregistered");
}
if ($type eq "Slice") {
my $slice = GeniRegistry::GeniSlice->Lookup($token);
my $slice = GeniSlice->Lookup($token);
if (!defined($slice)) {
return GeniResponse->Create(GENIRESPONSE_SUCCESS, undef,
"No such slice $token");
......@@ -762,7 +748,7 @@ sub Shutdown($)
return GeniResponse->Create( GENIRESPONSE_FORBIDDEN, undef,
"Insufficient privilege" );
my $slice = GeniRegistry::GeniSlice->Lookup($uuid || $urn);
my $slice = GeniSlice->Lookup($uuid || $urn);
if (!defined($slice)) {
if (!defined($urn)) {
return GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
......@@ -925,7 +911,7 @@ sub List($)
if ($type eq "slices") {
my @slices;
if (GeniRegistry::GeniSlice->ListAll(\@slices) != 0) {
if (GeniSlice->ListAll(\@slices) != 0) {
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
foreach my $slice (@slices) {
......
......@@ -184,6 +184,7 @@ sub DiscoverResources($)
my $credstr = $argref->{'credential'};
my $available = $argref->{'available'} || 0;
my $compress = $argref->{'compress'} || 0;
my $version = $argref->{'rspec_version'} || undef;
my $credential = CheckCredential($credstr);
return $credential
......@@ -192,10 +193,18 @@ sub DiscoverResources($)
return DiscoverResourcesAux($available, $compress, [$credential]);
}
# Helper function for V2.
sub DiscoverResourcesAux($$$)
sub DiscoverResourcesAux($$$;$)
{
my ($available, $compress, $credentials) = @_;
my ($available, $compress, $credentials, $version) = @_;
my $user_urn = $ENV{'GENIRN'};
$version = "0.2"
if (!defined($version));
# Sanity check since this can come from client.
if (! ($version eq "0.1" || $version eq "0.2" ||$version eq "2.0")) {
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Improper version request");
}
# Oh, for $*%(s sake. Frontier::RPC2 insists on representing a
# Boolean as its own object type -- which Perl always interprets as
......@@ -259,7 +268,7 @@ sub DiscoverResourcesAux($$$)
#
# Acquire the advertisement from ptopgen and compress it if requested.
#
my $xml = GetAdvertisement($available, undef, "0.2", $experiment);
my $xml = GetAdvertisement($available, undef, $version, $experiment);
if (! defined($xml)) {
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not start avail");
......
......@@ -24,6 +24,7 @@ use GeniResponse;
use GeniTicket;
use GeniCredential;
use GeniCertificate;
use GeniComponent;
use GeniSlice;
use GeniAggregate;
use GeniSliver;
......@@ -127,21 +128,58 @@ sub Resolve($)
my $node = $object;
my $rspec = GeniCM::GetAdvertisement(0, $node->node_id(), "0.1", undef);
if (! defined($rspec)) {
print STDERR "Could not get advertisement for $node!\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Error getting advertisement");
}
my $me = GeniAuthority->Lookup($ENV{'MYURN'});
if (!defined($me)) {
print STDERR
"Could not find local authority object for $ENV{'MYURN'}\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Error getting advertisement");
}
my $myurn = GeniHRN::Generate($OURDOMAIN, "node", $node->node_id());
my $myhrn = "${PGENIDOMAIN}." . $node->node_id();
#
# See if the component object exists; if not create it.
#
my $component = GeniComponent->Lookup($node->uuid());
if (!defined($component)) {
my $certificate = GeniCertificate->Lookup($node->uuid());
if (!defined($certificate)) {
$certificate =
GeniCertificate->Create({'urn' => $myurn,
'hrn' => $myhrn,
'email'=> $TBOPS,
'uuid' => $node->uuid(),
'url' => $me->url()});
if (!defined($certificate)) {
print STDERR "Could not generate certificate for $node\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Error getting advertisement");
}
}
$component = GeniComponent->Create($certificate, $me);
if (!defined($component)) {
print STDERR "Could not create component for $node\n";
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Error getting advertisement");
}
}
# Return a blob.
my $blob = { "hrn" => "${PGENIDOMAIN}." . $node->node_id(),
my $blob = { "hrn" => $myhrn,
"uuid" => $node->uuid(),
"role" => $node->role(),
"hostname" =>
GeniUtil::FindHostname($node->node_id()),
"physctrl" =>
Interface->LookupControl($node->phys_nodeid())->IP(),
"urn" => GeniHRN::Generate($OURDOMAIN,
"node",
$node->node_id()),
"rspec" => $rspec
"urn" => $myurn,
"rspec" => $rspec,
"url" => $me->url(),
"gid" => $component->cert(),
};
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
......@@ -228,6 +266,7 @@ sub DiscoverResources($)
my $credentials = $argref->{'credentials'};
my $available = $argref->{'available'} || 0;
my $compress = $argref->{'compress'} || 0;
my $version = $argref->{'rspec_version'} || undef;
if (! (defined($credentials))) {
return GeniResponse->MalformedArgsResponse("Missing arguments");
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniComponent;
......@@ -146,7 +146,21 @@ sub Create($$;$)
my $safe_hrn = DBQuoteSpecial($certificate->hrn());
my $safe_uuid = DBQuoteSpecial($certificate->uuid());
my $safe_url = DBQuoteSpecial($certificate->URL());
my $safe_url = "NULL";
# If there is a URL in the certificate, use that. If not, there had
# better be a manager supplied or else we will not be able to talk
# to it.
if (defined($certificate->URL())) {
$safe_url = DBQuoteSpecial($certificate->URL());
}
elsif (defined($manager)) {
$safe_url = DBQuoteSpecial($manager->url());
}
else {
print STDERR "GeniComponent::Create: No URL or authority supplied.\n";
return undef;
}
# Now tack on other stuff we need.
push(@insert_data, "created=now()");
......@@ -305,24 +319,21 @@ sub CreateFromRegistry($$)
if (defined($component) &&
$component->urn() && $component->manager_uuid());
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
my $registry = GeniRegistry->Create($token);
return undef
if (!defined($clearinghouse));
if (!defined($registry));
my $blob;
return undef
if ($clearinghouse->Resolve($token, "Component", \$blob) != 0);
if ($registry->Resolve($token, "Component", \$blob) != 0);
# Why does PLC Resolve return an array of length one?
$blob = $blob->[0];
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
if (!defined($certificate));
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.
#
......@@ -336,16 +347,48 @@ sub CreateFromRegistry($$)
#
# 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_urn;
if (exists($blob->{'manager_gid'})) {
my $manager_certificate =
GeniCertificate->LoadFromString($blob->{'manager_gid'});
if (!defined($certificate)) {
goto bad;
}
$manager_urn = $manager_certificate->urn();
$manager_certificate->Delete();
if (!defined($manager_urn)) {
print STDERR "GeniComponent::CreateFromRegistry: ".
"$manager_certificate does not have a urn.\n";
goto bad;
}
}
else {
#
# Only able to deal with PLC for now. The blob says that the "site"
# is the authority, but that is not true since we have to go all
# the way up to plc.sa to do anything.
#
my ($auth,$type,$id) = GeniHRN::Parse($urn);
return undef
if (!defined($auth));
if ($auth =~ /^plc:/) {
$manager_urn = GeniHRN::Generate("plc", "authority", "sa");
}
else {
print STDERR "Unsupported PLC component: $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";
goto bad;
}
$component = GeniComponent->Create($certificate, $manager);
......@@ -359,8 +402,6 @@ sub CreateFromRegistry($$)
bad:
$certificate->Delete()
if (defined($certificate));
$manager_certificate->Delete()
if (defined($manager_certificate));
return undef;
}
......@@ -398,6 +439,23 @@ sub Resolve($)
return undef
if (!defined($manager_version));
#
# XXX: The SFA stores all records in the central registry, not at
# the CM like we do.
#
if ($authority->IsSFA()) {
my $registry = GeniRegistry->Create($self->urn());
return undef
if (!defined($registry));
my $blob;
return undef
if ($registry->Resolve($self->urn(), "Component", \$blob) != 0);
# Why does PLC resolve return an array of length one?
return $blob->[0];
}
#
# Need a credential to make this call. Seems kinda silly.
#
......
#!/usr/bin/perl -w
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# Copyright (c) 2008-2011 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniEmulab;
......@@ -44,6 +44,7 @@ use Experiment;
use libdb qw(TBDB_IFACEROLE_CONTROL TBDB_IFACEROLE_EXPERIMENT);
use POSIX qw(strftime);
use Carp;
use Socket;
# Configure variables
my $TB = "@prefix@";
......@@ -184,7 +185,7 @@ sub UnRegisterExperiment($)
return -1;
}
# Needs to move.
GeniRegistry::ClientSliver->SliceDelete($slice);
GeniSlice::ClientSliver->SliceDelete($slice);
if ($slice->Delete()) {
print STDERR "Could not delete $slice for $experiment\n";
......@@ -196,9 +197,9 @@ sub UnRegisterExperiment($)
#
# Create a physical node on the fly.
#
sub CreatePhysNode($)
sub CreatePhysNode($$)
{
my ($node_urn) = @_;
my ($manager_urn, $node_urn) = @_;
my @ifaces;
my $ctrliface;
......@@ -206,10 +207,13 @@ sub CreatePhysNode($)
carp("Not a proper node urn: $node_urn\n");
return -1;
}
print STDERR "$node_urn\n";
if (!defined($manager_urn) || ! GeniHRN::IsValid($manager_urn)) {
carp("Not a proper manager urn: $manager_urn\n");
return -1;
}
print STDERR "$node_urn, $manager_urn\n";
my ($auth,$type,$node_id) = GeniHRN::Parse($node_urn);
my $manager_urn = GeniHRN::Generate($auth, "authority", "cm");
#
# Load the SA cert to act as caller context.
......@@ -240,7 +244,7 @@ sub CreatePhysNode($)
my $component = GeniComponent->CreateFromRegistry($node_urn);
if (!defined($component)) {
print STDERR "Could not lookup $node_urn at ClearingHouse\n";
print STDERR "Could not lookup $node_urn at its registry\n";
return undef;
}
my $node = Node->LookupWideArea($node_urn);
......@@ -256,9 +260,7 @@ sub CreatePhysNode($)
my $hrn = $blob->{'hrn'};
my $IP = $blob->{'physctrl'};
my $hostname = $blob->{'hostname'};
my $uuid = $blob->{'uuid'};
if (! (defined($hrn) && defined($IP) && defined($hostname) &&
defined($uuid))) {
if (! (defined($hrn) && defined($hostname))) {
print STDERR "Missing stuff in blob from CM for $node_urn\n";
goto bad;
}
......@@ -266,10 +268,6 @@ sub CreatePhysNode($)
print STDERR "Invalid hrn '$hrn' in blob from CM for $node_urn\n";
goto bad;
}
if (! ($uuid =~ /^[-\w\.]*$/)) {
print STDERR "Invalid uuid '$uuid' in blob from CM for $node_urn\n";
goto bad;
}
if (! ($hostname =~ /^[-\w\.]*$/)) {
print STDERR
"Invalid hostname '$hostname' in blob from CM for $node_urn\n";
......@@ -286,7 +284,34 @@ sub CreatePhysNode($)
#
# Find control network.
#
if (exists($blob->{'interfaces'})) {
if ($authority->IsSFA()) {
#
# Generate a suitable node_id.
#
my ($pl) = ($blob->{'hrn'} =~ /^([^.]*)\./);
$node_id = "$pl" . "-" . $blob->{'node_id'};
#
# Find the IP from the hostname and generate a stub iface entry.
#
my ($name,undef,undef,undef,@ipaddrs) = gethostbyname($hostname);
if (!defined($name)) {
print STDERR "Cannot resolve $hostname for $node_urn:\n";
goto bad;
}
$IP = inet_ntoa($ipaddrs[0]);
my $ifaceargs = {
"card" => 0,
"role" => TBDB_IFACEROLE_CONTROL(),
"MAC" => '000000000000',
"IP" => $IP,
"type" => "generic",
};
push(@ifaces, $ifaceargs);
$ctrliface = $ifaceargs;
}
elsif (exists($blob->{'interfaces'})) {
foreach my $ref (@{ $blob->{'interfaces'} }) {
my $role = $ref->{'role'};
......
This diff is collapsed.
......@@ -24,6 +24,7 @@ use GeniTicket;
use GeniCredential;
use GeniAuthority;
use GeniComponent;
use GeniSlice;