Commit beff6c7c authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents 6d546757 4a355379
......@@ -1348,6 +1348,9 @@ ScriptAlias /protogeni/xmlrpc/ch @prefix@/protogeni/xmlrpc/protogeni-ch.pl
ScriptAlias /protogeni/xmlrpc/cm @prefix@/protogeni/xmlrpc/protogeni-cm.pl
ScriptAlias /protogeni/xmlrpc/sa @prefix@/protogeni/xmlrpc/protogeni-sa.pl
ScriptAlias /protogeni/xmlrpc/ses @prefix@/protogeni/xmlrpc/protogeni-ses.pl
<IfDefine GENI_AM>
ScriptAlias /protogeni/xmlrpc/am @prefix@/protogeni/xmlrpc/geni-am.pl
</IfDefine>
<Directory "@prefix@/www/protogeni">
SSLRequireSSL
Order deny,allow
......
......@@ -17,7 +17,7 @@ LIB_SCRIPTS = GeniDB.pm GeniUser.pm \
GeniComponent.pm GeniCH.pm GeniEmulab.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \
GeniUtil.pm GeniRegistry.pm GeniUsage.pm GeniHRN.pm \
GeniSES.pm GeniResource.pm GeniXML.pm
GeniSES.pm GeniResource.pm GeniXML.pm GeniAM.pm
SBIN_SCRIPTS = plabnodewrapper plabslicewrapper
SCRIPTS = genischemacheck.pl
......
#!/usr/bin/perl -wT
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
package GeniAM;
#
# The server side of the CM interface on remote sites. Also communicates
# with the GMC interface at Geni Central as a client.
#
use strict;
use Exporter;
use vars qw(@ISA @EXPORT);
@ISA = "Exporter";
@EXPORT = qw ( );
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniCMV2;
use GeniResponse;
my $API_VERSION = 1;
#
# Tell the client what API revision we support. The correspondence
# between revision numbers and API features is to be specified elsewhere.
# No credentials are required.
#
sub GetVersion()
{
my $blob = {
"geni_api" => $API_VERSION
};
return GeniResponse->Create( GENIRESPONSE_SUCCESS, $blob );
}
# List this aggregates resources. Invokes DiscoverResources.
# XXX Still need to handle the slice urn code path.
sub ListResources()
{
# my ($argref) = @_;
# my $credentials = $argref->{'credentials'};
# my $options = $argref->{'options'};
my ($credentials, $options) = @_;
my $available = $options->{'geni_available'} || 0;
my $compress = $options->{'geni_compress'} || 0;
my $slice_urn = $options->{'geni_slice_urn'};
# If $slice_urn is defined, this turns into a Resolve call. We
# need to resolve twice: once to get the sliver urn from the
# slice, then to get the resources associated with the sliver (a
# manifest rspec).
my $discover_args = {
'credentials' => $credentials,
'available' => $available,
'compress' => $compress
};
return GeniCMV2::DiscoverResources($discover_args);
}
# Create a sliver by allocating and starting resources.
sub CreateSliver()
{
my ($slice_urn, $credentials, $rspec) = @_;
# Invoke CreateSliver
my $create_args = {
'slice_urn' => $slice_urn,
'rspec' => $rspec,
'credentials' => $credentials
# Omit keys, we expect them to be in the rspec
};
my $response = GeniCMV2::CreateSliver($create_args);
if (GeniResponse::IsError($response)) {
# The create failed, so return the response.
return $response
}
# The create succeeded so gather the response info
my $listref = GeniResponse::value($response);
my ($sliver_credential, $manifest_rspec) = @{$listref};
return GeniResponse->Create( GENIRESPONSE_SUCCESS, $manifest_rspec );
}
sub DeleteSliver()
{
my ($slice_urn, $credentials) = @_;
# Invoke StopSliver
my $stop_args = {
'slice_urn' => $slice_urn,
'credentials' => $credentials
};
my $response = GeniCMV2::StopSliver($stop_args);
# Ignore refused error, it means the sliver was not started yet.
# A better way to go might be to check the sliver state and only
# invoke stop sliver if the sliver is started.
if (GeniResponse::IsError($response)
&& GeniResponse::code($response) != GENIRESPONSE_REFUSED()) {
# The stop failed, so return the response.
return $response
}
# The sliver is stopped, now delete it.
my $delete_args = {
'slice_urn' => $slice_urn,
'credentials' => $credentials
};
# XXX Open question: Call "DeleteSlice" or "DeleteSliver"?
$response = GeniCMV2::DeleteSlice($delete_args);
if (GeniResponse::IsError($response)) {
return $response
}
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
}
# Get the status of the sliver associated with the given slice. This
# just passes on to the CM SliverStatus operation.
sub SliverStatus()
{
my ($slice_urn, $credentials) = @_;
my $status_args = {
'slice_urn' => $slice_urn,
'credentials' => $credentials,
};
my $response = GeniCMV2::SliverStatus($status_args);
if (GeniResponse::IsError($response)) {
return $response
}
# $status is a hash ref
my $pgstatus = GeniResponse::value($response);
my $status = {};
# How do we determine the sliver URN? Is there one for the whole
# sliver, or just for each individual sliver?
$status->{'geni_urn'} = 'Unknown';
# Determine geni_status. XXX how to determine 'configuring'?
if ($pgstatus->{'status'} == 'ready') {
$status->{'geni_status'} = 'ready';
} elsif ($pgstatus->{'status'} == 'failed') {
$status->{'geni_status'} = 'failed';
} else {
$status->{'geni_status'} = 'unknown';
}
my $details = $pgstatus->{'details'};
my @children = ();
while ( my ($pgurn, $pgrstat) = each(%$details) ) {
my $child = {
'geni_urn' => $pgurn,
# XXX Need to massage status to one of the AM status values
'geni_status' => $pgrstat->{'status'},
'geni_error' => $pgrstat->{'error'},
};
push @children, $child;
}
$status->{'geni_resources'} = \@children;
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $status);
}
sub RenewSliver()
{
my ($slice_urn, $credentials, $expiration_time) = @_;
my $renew_args = {
'slice_urn' => $slice_urn,
'expiration' => $expiration_time,
'credentials' => $credentials
};
my $response = GeniCMV2::RenewSlice($renew_args);
if (GeniResponse::IsError($response)) {
return $response
}
# Well this is ugly. We want to return True, so we must encode it
# as an XMLRPC Boolean via an encoder.
my $coder = Frontier::RPC2->new();
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $coder->boolean(1));
}
sub Shutdown()
{
my ($slice_urn, $credentials) = @_;
return GeniResponse->Create( GENIRESPONSE_UNSUPPORTED );
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -266,9 +266,16 @@ sub LoadFromString($$)
print STDERR "Could not create tempfile for cert string\n";
return undef;
}
print $tempfile "-----BEGIN CERTIFICATE-----\n";
print $tempfile $string;
print $tempfile "-----END CERTIFICATE-----\n";
# The certificate might already have the header and footer
# so only add them if needed.
if ($string =~ /^-----BEGIN CERTIFICATE-----/) {
print $tempfile $string;
} else {
print $tempfile "-----BEGIN CERTIFICATE-----\n";
print $tempfile $string;
print $tempfile "-----END CERTIFICATE-----\n";
}
my $certificate = GeniCertificate->LoadFromFile($filename);
unlink($filename);
......@@ -325,7 +332,7 @@ sub LoadFromFile($$)
} elsif( $line =~ /^\s+Authority Information Access:\s*$/ ) {
$accessinfo = 1;
} elsif( $altname ) {
m'^\s*URI:([-!#$%()*+,./0-9:;=?@A-Z_a-z~]+)\s*$' and $alturi = $1
m'^\s*URI:(urn:publicid:[-!#$%()*+,./0-9:;=?@A-Z_a-z~]+)\s*$' and $alturi = $1
foreach split( /, /, $line );
$altname = 0;
} elsif( $accessinfo ) {
......
......@@ -33,7 +33,7 @@ use Time::Local;
use overload ('""' => 'Stringify');
# Exported variables
use vars qw(@EXPORT_OK $LOCALSA_FLAG $LOCALCM_FLAG $LOCALMA_FLAG);
use vars qw(@EXPORT_OK $LOCALSA_FLAG $LOCALCM_FLAG $LOCALMA_FLAG $CHECK_UUID);
# Configure variables
my $TB = "@prefix@";
......@@ -51,7 +51,8 @@ my $OPENSSL = "/usr/bin/openssl";
$LOCALSA_FLAG = 1;
$LOCALCM_FLAG = 2;
$LOCALMA_FLAG = 3;
@EXPORT_OK = qw($LOCALSA_FLAG $LOCALCM_FLAG $LOCALMA_FLAG);
$CHECK_UUID = 1; # Default to true, enabling uuid checks
@EXPORT_OK = qw($LOCALSA_FLAG $LOCALCM_FLAG $LOCALMA_FLAG $CHECK_UUID);
# Capability Flags.
......@@ -291,9 +292,9 @@ sub CreateFromSigned($$;$)
if (!defined($uuid_node));
my $this_uuid = $uuid_node->to_literal();
if (! ($this_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
print STDERR "Invalid this_uuid in credential\n";
return undef;
if (! ($this_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/) && $CHECK_UUID) {
print STDERR "Invalid this_uuid in credential\n";
return undef;
}
# Expiration
......@@ -325,9 +326,10 @@ sub CreateFromSigned($$;$)
return undef
if (!defined($target_certificate));
if (!($target_certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
print STDERR "Invalid target_uuid in credential\n";
return undef;
if (!($target_certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)
&& $CHECK_UUID) {
print STDERR "Invalid target_uuid in credential\n";
return undef;
}
if (!($target_certificate->hrn() =~ /^[-\w\.]+$/)) {
my $hrn = $target_certificate->hrn();
......@@ -349,9 +351,10 @@ sub CreateFromSigned($$;$)
return undef
if (!defined($owner_certificate));
if (!($owner_certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
print STDERR "Invalid target_uuid in credential\n";
return undef;
if (!($owner_certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)
&& $CHECK_UUID) {
print STDERR "Invalid target_uuid in credential\n";
return undef;
}
if (!($owner_certificate->hrn() =~ /^[-\w\.]+$/)) {
my $hrn = $owner_certificate->hrn();
......
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import time
import re
ACCEPTSLICENAME=1
debug = 0
impotent = 1
execfile( "test-common.py" )
if len(REQARGS) > 1:
Usage()
sys.exit( 1 )
elif len(REQARGS) == 1:
try:
rspecfile = open(REQARGS[0])
rspec = rspecfile.read()
rspecfile.close()
except IOError, e:
print >> sys.stderr, args[ 0 ] + ": " + e.strerror
sys.exit( 1 )
else:
rspec = "<rspec xmlns=\"http://protogeni.net/resources/rspec/0.1\"> " +\
" <node virtual_id=\"geni1\" "+\
" virtualization_type=\"emulab-vnode\" " +\
" startup_command=\"/bin/ls > /tmp/foo\"> " +\
" </node>" +\
"</rspec>"
#
# Get a credential for myself, that allows me to do things at the SA.
#
mycredential = get_self_credential()
print "Got my SA credential"
#
# Lookup my ssh keys.
#
params = {}
params["credential"] = mycredential
rval,response = do_method("sa", "GetKeys", params)
if rval:
Fatal("Could not get my keys")
pass
mykeys = response["value"]
if debug: print str(mykeys)
#
# Lookup slice.
#
params = {}
params["credential"] = mycredential
params["type"] = "Slice"
params["hrn"] = SLICENAME
rval,response = do_method("sa", "Resolve", params)
if rval:
#
# Create a slice.
#
print "Creating new slice called " + SLICENAME
params = {}
params["credential"] = mycredential
params["type"] = "Slice"
params["hrn"] = SLICENAME
rval,response = do_method("sa", "Register", params)
if rval:
Fatal("Could not create new slice")
pass
myslice = response["value"]
print "New slice created"
pass
else:
#
# Get the slice credential.
#
print "Asking for slice credential for " + SLICENAME
myslice = response["value"]
myslice = get_slice_credential( myslice, mycredential )
print "Got the slice credential"
pass
#
# Create the sliver.
#
print "Creating the Sliver ..."
params = [SLICEURN, [myslice], rspec]
try:
response = do_method("am", "CreateSliver", params,
response_handler=geni_am_response_handler)
print "Created the sliver"
print str(response)
except xmlrpclib.Fault, e:
Fatal("Could not create sliver: %s" % (str(e)))
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import re
ACCEPTSLICENAME=1
execfile( "test-common.py" )
#
# Get a credential for myself, that allows me to do things at the SA.
#
mycredential = get_self_credential()
print "Got my SA credential. Looking for slice %s..." % (SLICENAME)
#
# Lookup slice, delete before proceeding.
#
myslice = resolve_slice( SLICENAME, mycredential )
print "Found the slice, asking for a credential ..."
#
# Get the slice credential.
#
slicecred = get_slice_credential( myslice, mycredential )
print "Got the slice credential, deleting the sliver..."
#
# Delete the sliver.
#
params = [myslice["urn"], [slicecred]]
try:
response = do_method("am", "DeleteSliver", params,
response_handler=geni_am_response_handler)
print "Sliver %s has been deleted." % (SLICENAME)
print "value = %s" % (response)
except xmlrpclib.Fault, e:
Fatal("Could not delete sliver: %s" % (str(e)))
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2009 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import re
import xmlrpclib
from M2Crypto import X509
def Usage():
print "usage: " + sys.argv[ 0 ] + " [option...] [authority]"
print """Options:
-d, --debug be verbose about XML methods invoked
-h, --help show options and usage
-r file, --read-commands=file specify additional configuration file"""
execfile( "test-common.py" )
if len( args ) > 1:
Usage()
sys.exit( 1 )
elif len( args ) == 1:
authority = args[ 0 ]
else:
authority = "am"
try:
response = do_method(authority, "GetVersion", [],
response_handler=geni_am_response_handler)
print response
except xmlrpclib.Fault, e:
Fatal("Could not obtain the API version: %s" % (str(e)))
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import re
execfile( "test-common.py" )
available_key = "geni_available"
compress_key = "geni_compress"
#
# Get a credential for myself, that allows me to do things at the SA.
#
mycredential = get_self_credential()
#
# Ask manager for its list.
#
options = {}
options[available_key] = True
options[compress_key] = True
params = [[mycredential], options]
try:
response = do_method("am", "ListResources", params,
response_handler=geni_am_response_handler)
if compress_key in options and options[compress_key]:
# decompress the result
import zlib
print zlib.decompress(response.data)
else:
print response
except xmlrpclib.Fault, e:
Fatal("Could not get a list of resources: %s" % (str(e)))
#! /usr/bin/env python
#
# GENIPUBLIC-COPYRIGHT
# Copyright (c) 2008-2010 University of Utah and the Flux Group.
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software is hereby
# granted provided that (1) source code retains these copyright, permission,
# and disclaimer notices, and (2) redistributions including binaries
# reproduce the notices in supporting documentation.
#
# THE UNIVERSITY OF UTAH ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
# CONDITION. THE UNIVERSITY OF UTAH DISCLAIMS ANY LIABILITY OF ANY KIND
# FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
#
#
#
import sys
import pwd
import getopt
import os
import time