From: Thierry Parmentelat Date: Tue, 13 Mar 2012 14:34:25 +0000 (-0700) Subject: Merge branch 'upstreammaster' X-Git-Tag: sfa-2.1-24~21 X-Git-Url: http://git.onelab.eu/?p=sfa.git;a=commitdiff_plain;h=c900832bcc4f4dddceeac1978d56e5f10e0e2bb5;hp=1b114ae60d1d0caba61145877c06aed1a29773ca Merge branch 'upstreammaster' --- diff --git a/setup.py b/setup.py index 4c20ceeb..5512d998 100755 --- a/setup.py +++ b/setup.py @@ -13,9 +13,6 @@ scripts = glob("sfa/clientbin/*.py") + \ [ 'config/sfa-config-tty', 'config/gen-sfa-cm-config.py', - 'sfa/importer/sfa-import.py', - 'sfa/importer/sfa-nuke.py', - 'sfa/server/sfa-ca.py', 'sfa/server/sfa-start.py', 'sfa/server/sfa_component_setup.py', 'sfatables/sfatables', diff --git a/sfa/clientbin/sfaadmin.py b/sfa/clientbin/sfaadmin.py index 90c3f745..9a62511d 100755 --- a/sfa/clientbin/sfaadmin.py +++ b/sfa/clientbin/sfaadmin.py @@ -1,4 +1,5 @@ #!/usr/bin/python +import os import sys import copy from pprint import pformat @@ -8,8 +9,10 @@ from pprint import PrettyPrinter from sfa.util.xrn import Xrn from sfa.storage.record import Record from sfa.client.sfi import save_records_to_file -pprinter = PrettyPrinter(indent=4) +from sfa.trust.hierarchy import Hierarchy +from sfa.trust.gid import GID +pprinter = PrettyPrinter(indent=4) def args(*args, **kwargs): def _decorator(func): @@ -26,8 +29,8 @@ class Commands(object): available_methods.append(attrib) return available_methods -class RegistryCommands(Commands): +class RegistryCommands(Commands): def __init__(self, *args, **kwds): self.api= Generic.the_flavour().make_api(interface='registry') @@ -76,21 +79,95 @@ class RegistryCommands(Commands): def credential(self, xrn, type=None): cred = self.api.manager.GetCredential(self.api, xrn, type, self.api.hrn) print cred + + + def import_registry(self): + from sfa.importer import Importer + importer = Importer() + importer.run() + @args('-a', '--all', dest='all', metavar='', action='store_true', default=False, + help='Remove all registry records and all files in %s area' % Hierarchy().basedir) + @args('-c', '--certs', dest='certs', metavar='', action='store_true', default=False, + help='Remove all cached certs/gids found in %s' % Hierarchy().basedir ) + @args('-0', '--no-reinit', dest='reinit', metavar='', action='store_false', default=True, + help='Prevents new DB schema from being installed after cleanup') + def nuke(self, all=False, certs=False, reinit=True): + from sfa.storage.dbschema import DBSchema + from sfa.util.sfalogging import _SfaLogger + logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog') + logger.setLevelFromOptVerbose(self.api.config.SFA_API_LOGLEVEL) + logger.info("Purging SFA records from database") + dbschema=DBSchema() + dbschema.nuke() + + # for convenience we re-create the schema here, so there's no need for an explicit + # service sfa restart + # however in some (upgrade) scenarios this might be wrong + if reinit: + logger.info("re-creating empty schema") + dbschema.init_or_upgrade() + + # remove the server certificate and all gids found in /var/lib/sfa/authorities + if certs: + logger.info("Purging cached certificates") + for (dir, _, files) in os.walk('/var/lib/sfa/authorities'): + for file in files: + if file.endswith('.gid') or file == 'server.cert': + path=dir+os.sep+file + os.unlink(path) + + # just remove all files that do not match 'server.key' or 'server.cert' + if all: + logger.info("Purging registry filesystem cache") + preserved_files = [ 'server.key', 'server.cert'] + for (dir,_,files) in os.walk(Hierarchy().basedir): + for file in files: + if file in preserved_files: continue + path=dir+os.sep+file + os.unlink(path) + -class CerficiateCommands(Commands): +class CertCommands(Commands): - def import_records(self, xrn): + def import_gid(self, xrn): pass - def export(self, xrn): - pass - - def display(self, xrn): - pass - - def nuke(self): - pass + @args('-x', '--xrn', dest='xrn', metavar='', help='object hrn/urn') + @args('-t', '--type', dest='type', metavar='', help='object type', default=None) + @args('-o', '--outfile', dest='outfile', metavar='', help='output file', default=None) + def export(self, xrn, type=None, outfile=None): + from sfa.storage.alchemy import dbsession + from sfa.storage.model import RegRecord + hrn = Xrn(xrn).get_hrn() + request=dbsession.query(RegRecord).filter_by(hrn=hrn) + if type: request = request.filter_by(type=type) + record=request.first() + if record: + gid = GID(string=record.gid) + else: + # check the authorities hierarchy + hierarchy = Hierarchy() + try: + auth_info = hierarchy.get_auth_info(hrn) + gid = auth_info.gid_object + except: + print "Record: %s not found" % hrn + sys.exit(1) + # save to file + if not outfile: + outfile = os.path.abspath('./%s.gid' % gid.get_hrn()) + gid.save_to_file(outfile, save_parents=True) + + @args('-g', '--gidfile', dest='gid', metavar='', help='path of gid file to display') + def display(self, gidfile): + gid_path = os.path.abspath(gidfile) + if not gid_path or not os.path.isfile(gid_path): + print "No such gid file: %s" % gidfile + sys.exit(1) + gid = GID(filename=gid_path) + gid.dump(dump_parents=True) + class AggregateCommands(Commands): @@ -122,8 +199,19 @@ class AggregateCommands(Commands): @args('-x', '--xrn', dest='xrn', metavar='', help='object hrn/urn', default=None) @args('-r', '--rspec', dest='rspec', metavar='', help='rspec file') - def create(self, xrn, rspec): - pass + @args('-u', '--user', dest='user', metavar='', help='hrn/urn of slice user') + @args('-k', '--key', dest='key', metavar='', help="path to user's public key file") + def create(self, xrn, rspec, user, key): + xrn = Xrn(xrn) + slice_urn=xrn.get_urn() + slice_hrn=xrn.get_hrn() + rspec_string = open(rspec).read() + user_xrn = Xrn(user, 'user') + user_urn = user_xrn.get_urn() + user_key_string = open(key).read() + users = [{'urn': user_urn, 'keys': [user_key_string]}] + options={} + self.api.manager.CreateSliver(self, slice_urn, slice_hrn, [], rspec_string, users, options) @args('-x', '--xrn', dest='xrn', metavar='', help='object hrn/urn', default=None) def delete(self, xrn): @@ -148,46 +236,60 @@ class AggregateCommands(Commands): pass + class SliceManagerCommands(AggregateCommands): def __init__(self, *args, **kwds): self.api= Generic.the_flavour().make_api(interface='slicemgr') -CATEGORIES = {'registry': RegistryCommands, +CATEGORIES = {'cert': CertCommands, + 'registry': RegistryCommands, 'aggregate': AggregateCommands, 'slicemgr': SliceManagerCommands} +def category_usage(): + print "Available categories:" + for k in CATEGORIES: + print "\t%s" % k + def main(): argv = copy.deepcopy(sys.argv) script_name = argv.pop(0) + # ensure category is specified if len(argv) < 1: print script_name + " category action []" - print "Available categories:" - for k in CATEGORIES: - print "\t%s" % k + category_usage() sys.exit(2) + # ensure category is valid category = argv.pop(0) usage = "%%prog %s action [options]" % (category) parser = OptionParser(usage=usage) - command_class = CATEGORIES[category] + command_class = CATEGORIES.get(category, None) + if not command_class: + print "no such category %s " % category + category_usage() + sys.exit(2) + + # ensure command is valid command_instance = command_class() actions = command_instance._get_commands() if len(argv) < 1: - if hasattr(command_instance, '__call__'): - action = '' - command = command_instance.__call__ - else: - print script_name + " category action []" - print "Available actions for %s category:" % category - for k in actions: - print "\t%s" % k - sys.exit(2) + action = '__call__' else: action = argv.pop(0) + + if hasattr(command_instance, action): command = getattr(command_instance, action) + else: + print script_name + " category action []" + print "Available actions for %s category:" % category + for k in actions: + print "\t%s" % k + sys.exit(2) + # ensure options are valid options = getattr(command, 'options', []) usage = "%%prog %s %s [options]" % (category, action) parser = OptionParser(usage=usage) @@ -201,6 +303,7 @@ def main(): if v is None: del cmd_kwds[k] + # execute commadn try: command(*cmd_args, **cmd_kwds) sys.exit(0) diff --git a/sfa/importer/__init__.py b/sfa/importer/__init__.py index e69de29b..20ef19da 100644 --- a/sfa/importer/__init__.py +++ b/sfa/importer/__init__.py @@ -0,0 +1,115 @@ +#!/usr/bin/python + +import sys + +from sfa.util.xrn import get_authority, hrn_to_urn +from sfa.util.plxrn import email_to_hrn +from sfa.generic import Generic +from sfa.util.config import Config +from sfa.util.sfalogging import _SfaLogger +from sfa.trust.hierarchy import Hierarchy +from sfa.trust.trustedroots import TrustedRoots +from sfa.trust.gid import create_uuid +from sfa.storage.alchemy import dbsession +from sfa.storage.model import RegRecord, RegAuthority, RegUser +from sfa.trust.certificate import convert_public_key, Keypair + + +class Importer: + def __init__(self): + self.config = Config() + self.logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog') + self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL) + self.auth_hierarchy = Hierarchy () + self.TrustedRoots = TrustedRoots(self.config.get_trustedroots_dir()) + + # check before creating a RegRecord entry as we run this over and over + def record_exists (self, type, hrn): + return dbsession.query(RegRecord).filter_by(hrn=hrn,type=type).count()!=0 + + def create_top_level_auth_records(self, hrn): + """ + Create top level db records (includes root and sub authorities (local/remote) + """ + # make sure parent exists + parent_hrn = get_authority(hrn) + if not parent_hrn: + parent_hrn = hrn + if not parent_hrn == hrn: + self.create_top_level_auth_records(parent_hrn) + + # ensure key and cert exists: + self.auth_hierarchy.create_top_level_auth(hrn) + # create the db record if it doesnt already exist + if not self.record_exists ('authority',hrn): + auth_info = self.auth_hierarchy.get_auth_info(hrn) + auth_record = RegAuthority(hrn=hrn, gid=auth_info.get_gid_object(), + authority=get_authority(hrn)) + auth_record.just_created() + dbsession.add (auth_record) + dbsession.commit() + self.logger.info("SfaImporter: imported authority (parent) %s " % auth_record) + + + def create_sm_client_record(self): + """ + Create a user record for the Slicemanager service. + """ + hrn = self.interface_hrn + '.slicemanager' + urn = hrn_to_urn(hrn, 'user') + if not self.auth_hierarchy.auth_exists(urn): + self.logger.info("SfaImporter: creating Slice Manager user") + self.auth_hierarchy.create_auth(urn) + + if self.record_exists ('user',hrn): return + auth_info = self.auth_hierarchy.get_auth_info(hrn) + user_record = RegUser(hrn=hrn, gid=auth_info.get_gid_object(), + authority=get_authority(hrn)) + user_record.just_created() + dbsession.add (user_record) + dbsession.commit() + self.logger.info("SfaImporter: importing user (slicemanager) %s " % user_record) + + + def create_interface_records(self): + """ + Create a record for each SFA interface + """ + # just create certs for all sfa interfaces even if they + # aren't enabled + auth_info = self.auth_hierarchy.get_auth_info(self.interface_hrn) + pkey = auth_info.get_pkey_object() + hrn=self.interface_hrn + for type in [ 'authority+sa', 'authority+am', 'authority+sm', ]: + urn = hrn_to_urn(hrn, type) + gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) + # for now we have to preserve the authority+<> stuff + if self.record_exists (type,hrn): continue + interface_record = RegAuthority(type=type, hrn=hrn, gid=gid, + authority=get_authority(hrn)) + interface_record.just_created() + dbsession.add (interface_record) + dbsession.commit() + self.logger.info("SfaImporter: imported authority (%s) %s " % (type,interface_record)) + + def run(self, options=None): + if not self.config.SFA_REGISTRY_ENABLED: + self.logger.critical("Importer: need SFA_REGISTRY_ENABLED to run import") + + # testbed-neutral : create local certificates and the like + auth_hierarchy = Hierarchy () + self.create_top_level_auth_records(self.config.SFA_INTERFACE_HRN) + + # testbed-specific + testbed_importer = None + generic=Generic.the_flavour() + importer_class = generic.importer_class() + if importer_class: + self.logger.info ("Using flavour %s for importing (class %s)"%\ + (generic.flavour,importer_class.__name__)) + testbed_importer = importer_class (auth_hierarchy, self.logger) + if testbed_importer: + testbed_importer.add_options(options) + testbed_importer.run (options) + + diff --git a/sfa/importer/openstackimporter.py b/sfa/importer/openstackimporter.py index 32def38e..2331fa72 100644 --- a/sfa/importer/openstackimporter.py +++ b/sfa/importer/openstackimporter.py @@ -3,13 +3,10 @@ import os from sfa.util.config import Config from sfa.util.xrn import Xrn, get_leaf, get_authority, hrn_to_urn from sfa.util.plxrn import hostname_to_hrn, slicename_to_hrn, email_to_hrn, hrn_to_pl_slicename - from sfa.trust.gid import create_uuid from sfa.trust.certificate import convert_public_key, Keypair - from sfa.storage.alchemy import dbsession from sfa.storage.model import RegRecord, RegAuthority, RegUser, RegSlice, RegNode - from sfa.openstack.nova_shell import NovaShell def load_keys(filename): @@ -40,7 +37,7 @@ class OpenstackImporter: def run (self, options): # we don't have any options for now - self.logger.info ("PlImporter.run : to do") + self.logger.info ("OpenstackImporter.run : to do") config = Config () interface_hrn = config.SFA_INTERFACE_HRN diff --git a/sfa/importer/plimporter.py b/sfa/importer/plimporter.py index 153104b7..83673180 100644 --- a/sfa/importer/plimporter.py +++ b/sfa/importer/plimporter.py @@ -155,7 +155,8 @@ class PlImporter: key_ids = [] for person in persons: key_ids.extend(person['key_ids']) - keys = shell.GetKeys( {'peer_id': None, 'key_id': key_ids} ) + keys = shell.GetKeys( {'peer_id': None, 'key_id': key_ids, + 'key_type': 'ssh'} ) # create a hash of keys by key_id keys_by_id = dict ( [ ( key['key_id'], key ) for key in keys ] ) # create a dict person_id -> [ (plc)keys ] @@ -163,7 +164,9 @@ class PlImporter: for person in persons: pubkeys = [] for key_id in person['key_ids']: - pubkeys.append(keys_by_id[key_id]) + key = keys_by_id[key_id] + if key['key_type'] == 'ssh': + pubkeys.append(key) keys_by_person_id[person['person_id']] = pubkeys # Get all plc nodes nodes = shell.GetNodes( {'peer_id': None}, ['node_id', 'hostname', 'site_id']) diff --git a/sfa/importer/sfa-import.py b/sfa/importer/sfa-import.py deleted file mode 100755 index 27882823..00000000 --- a/sfa/importer/sfa-import.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python - -import sys - -from optparse import OptionParser - -from sfa.generic import Generic - -from sfa.util.config import Config -from sfa.util.sfalogging import _SfaLogger - -from sfa.trust.hierarchy import Hierarchy - -from sfa.importer.sfaimporter import SfaImporter - -COMMAND=sys.argv[0] - -def main (): - - config = Config() - logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog') - logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL) - if not config.SFA_REGISTRY_ENABLED: - logger.critical("COMMAND: need SFA_REGISTRY_ENABLED to run import") - - # testbed-neutral : create local certificates and the like - auth_hierarchy = Hierarchy () - sfa_importer = SfaImporter(auth_hierarchy, logger) - # testbed-specific - testbed_importer = None - generic=Generic.the_flavour() - importer_class = generic.importer_class() - if importer_class: - logger.info ("Using flavour %s for importing (class %s)"%\ - (generic.flavour,importer_class.__name__)) - testbed_importer = importer_class (auth_hierarchy, logger) - - parser = OptionParser () - sfa_importer.add_options (parser) - if testbed_importer: - testbed_importer.add_options (parser) - - (options, args) = parser.parse_args () - # no args supported ? - if args: - parser.print_help() - sys.exit(1) - - sfa_importer.run (options) - if testbed_importer: - testbed_importer.run (parser) - - -if __name__ == '__main__': - main() - diff --git a/sfa/importer/sfaimporter.py b/sfa/importer/sfaimporter.py deleted file mode 100644 index 4f17c2d1..00000000 --- a/sfa/importer/sfaimporter.py +++ /dev/null @@ -1,148 +0,0 @@ -# -# Public keys are extracted from the users' SSH keys automatically and used to -# create GIDs. This is relatively experimental as a custom tool had to be -# written to perform conversion from SSH to OpenSSL format. It only supports -# RSA keys at this time, not DSA keys. -## - -from sfa.util.xrn import get_authority, hrn_to_urn -from sfa.util.plxrn import email_to_hrn -from sfa.util.config import Config -from sfa.trust.certificate import convert_public_key, Keypair -from sfa.trust.trustedroots import TrustedRoots -from sfa.trust.gid import create_uuid - -from sfa.storage.alchemy import dbsession -from sfa.storage.model import RegRecord, RegAuthority, RegUser - -def _un_unicode(str): - if isinstance(str, unicode): - return str.encode("ascii", "ignore") - else: - return str - -def _cleanup_string(str): - # pgsql has a fit with strings that have high ascii in them, so filter it - # out when generating the hrns. - tmp = "" - for c in str: - if ord(c) < 128: - tmp = tmp + c - str = tmp - - str = _un_unicode(str) - str = str.replace(" ", "_") - str = str.replace(".", "_") - str = str.replace("(", "_") - str = str.replace("'", "_") - str = str.replace(")", "_") - str = str.replace('"', "_") - return str - -class SfaImporter: - - def __init__(self, auth_hierarchy, logger): - self.logger=logger - self.auth_hierarchy = auth_hierarchy - config = Config() - self.TrustedRoots = TrustedRoots(Config.get_trustedroots_dir(config)) - self.root_auth = config.SFA_REGISTRY_ROOT_AUTH - self.interface_hrn = config.SFA_INTERFACE_HRN - - # check before creating a RegRecord entry as we run this over and over - def record_exists (self, type, hrn): - return dbsession.query(RegRecord).filter_by(hrn=hrn,type=type).count()!=0 - - # record options into an OptionParser - def add_options (self, parser): - # no generic option - pass - - def run (self, options): - self.logger.info ("SfaImporter.run : no options used") - self.create_top_level_records() - - def create_top_level_records(self): - """ - Create top level and interface records - """ - # create root authority - self.create_top_level_auth_records(self.interface_hrn) - - # create s user record for the slice manager - self.create_sm_client_record() - - # create interface records - # xxx turning off the creation of authority+* - # in fact his is required - used in SfaApi._getCredentialRaw - # that tries to locate 'authority+sa' - self.create_interface_records() - - # add local root authority's cert to trusted list - self.logger.info("SfaImporter: adding " + self.interface_hrn + " to trusted list") - authority = self.auth_hierarchy.get_auth_info(self.interface_hrn) - self.TrustedRoots.add_gid(authority.get_gid_object()) - - def create_top_level_auth_records(self, hrn): - """ - Create top level db records (includes root and sub authorities (local/remote) - """ - # make sure parent exists - parent_hrn = get_authority(hrn) - if not parent_hrn: - parent_hrn = hrn - if not parent_hrn == hrn: - self.create_top_level_auth_records(parent_hrn) - - # ensure key and cert exists: - self.auth_hierarchy.create_top_level_auth(hrn) - # create the db record if it doesnt already exist - if self.record_exists ('authority',hrn): return - auth_info = self.auth_hierarchy.get_auth_info(hrn) - auth_record = RegAuthority(hrn=hrn, gid=auth_info.get_gid_object(), - authority=get_authority(hrn)) - auth_record.just_created() - dbsession.add (auth_record) - dbsession.commit() - self.logger.info("SfaImporter: imported authority (parent) %s " % auth_record) - - def create_sm_client_record(self): - """ - Create a user record for the Slicemanager service. - """ - hrn = self.interface_hrn + '.slicemanager' - urn = hrn_to_urn(hrn, 'user') - if not self.auth_hierarchy.auth_exists(urn): - self.logger.info("SfaImporter: creating Slice Manager user") - self.auth_hierarchy.create_auth(urn) - - if self.record_exists ('user',hrn): return - auth_info = self.auth_hierarchy.get_auth_info(hrn) - user_record = RegUser(hrn=hrn, gid=auth_info.get_gid_object(), - authority=get_authority(hrn)) - user_record.just_created() - dbsession.add (user_record) - dbsession.commit() - self.logger.info("SfaImporter: importing user (slicemanager) %s " % user_record) - - def create_interface_records(self): - """ - Create a record for each SFA interface - """ - # just create certs for all sfa interfaces even if they - # aren't enabled - auth_info = self.auth_hierarchy.get_auth_info(self.interface_hrn) - pkey = auth_info.get_pkey_object() - hrn=self.interface_hrn - for type in [ 'authority+sa', 'authority+am', 'authority+sm', ]: - urn = hrn_to_urn(hrn, type) - gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey) - # for now we have to preserve the authority+<> stuff - if self.record_exists (type,hrn): continue - interface_record = RegAuthority(type=type, hrn=hrn, gid=gid, - authority=get_authority(hrn)) - interface_record.just_created() - dbsession.add (interface_record) - dbsession.commit() - self.logger.info("SfaImporter: imported authority (%s) %s " % (type,interface_record)) - diff --git a/sfa/managers/registry_manager.py b/sfa/managers/registry_manager.py index db4348d6..518072b0 100644 --- a/sfa/managers/registry_manager.py +++ b/sfa/managers/registry_manager.py @@ -70,9 +70,10 @@ class RegistryManager: caller_gid = record.get_gid_object() else: caller_hrn, caller_type = urn_to_hrn(caller_xrn) - caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first() if caller_type: - caller_record = caller_record.filter_by(type=caller_type) + caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first() + else: + caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first() if not caller_record: raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type)) caller_gid = GID(string=caller_record.gid) diff --git a/sfa/methods/GetCredential.py b/sfa/methods/GetCredential.py index f5344a27..22d021cd 100644 --- a/sfa/methods/GetCredential.py +++ b/sfa/methods/GetCredential.py @@ -44,5 +44,5 @@ class GetCredential(Method): origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name)) - return self.api.manager.GetCredential(self.api, xrn, self.api.auth.client_gid.get_urn()) + return self.api.manager.GetCredential(self.api, xrn, type, self.api.auth.client_gid.get_urn()) diff --git a/sfa/plc/plaggregate.py b/sfa/plc/plaggregate.py index b0c78d11..b84dac49 100644 --- a/sfa/plc/plaggregate.py +++ b/sfa/plc/plaggregate.py @@ -135,11 +135,12 @@ class PlAggregate: return (slice, slivers) - def get_nodes_and_links(self, slice=None,slivers=[], options={}): + def get_nodes_and_links(self, slice_xrn, slice=None,slivers=[], options={}): # if we are dealing with a slice that has no node just return # and empty list - if not slice or not slice['node_ids']: - return ([],[]) + if slice_xrn: + if not slice or not slice['node_ids']: + return ([],[]) filter = {} tags_filter = {} @@ -248,7 +249,7 @@ class PlAggregate: if slice and 'expires' in slice: rspec.xml.set('expires', datetime_to_string(utcparse(slice['expires']))) - nodes, links = self.get_nodes_and_links(slice, slivers) + nodes, links = self.get_nodes_and_links(slice_xrn, slice, slivers) rspec.version.add_nodes(nodes) rspec.version.add_links(links) diff --git a/sfa/server/sfa-ca.py b/sfa/server/sfa-ca.py deleted file mode 100755 index 9ab75e7e..00000000 --- a/sfa/server/sfa-ca.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/python - -# -# SFA Certificate Signing and management. Root authorities can use this script -# to sign the certificate of another authority and become its parent. Sub -# authorities (authorities that have had their cert signed by another authority) -# can use this script to update their registry hierarchy with the new cert -# -# Example usage: -# -## sign a peer cert -# sfa-ca.py --sign PEER_CERT_FILENAME -o OUTPUT_FILENAME -# -## import a cert and update the registry hierarchy -# sfa-ca.py --import CERT_FILENAME -# -## display a cert -# sfa-ca.py --display CERT_FILENAME - - -import os -import sys -from optparse import OptionParser - -from sfa.util.config import Config - -from sfa.trust.gid import GID, create_uuid -from sfa.trust.hierarchy import Hierarchy - -from sfa.storage.alchemy import dbsession -from sfa.storage.model import RegRecord - -def main(): - args = sys.argv - script_name = args[0] - parser = OptionParser(usage="%(script_name)s [options]" % locals()) - parser.add_option("-d", "--display", dest="display", default=None, - help="print contents of specified gid") - parser.add_option("-s", "--sign", dest="sign", default=None, - help="gid to sign" ) - parser.add_option("-k", "--key", dest="key", default=None, - help="keyfile to use for signing") - parser.add_option("-a", "--authority", dest="authority", default=None, - help="sign the gid using the specified authority ") - parser.add_option("-i", "--import", dest="importgid", default=None, - help="gid file to import into the registry") - parser.add_option("-e", "--export", dest="export", - help="name of gid to export from registry") - parser.add_option("-t", "--type", dest="type", - help="record type", default=None) - parser.add_option("-o", "--outfile", dest="outfile", - help="where to write the exprted gid") - parser.add_option("-v", "--verbose", dest="verbose", default=False, - action="store_true", help="be verbose") - - (options, args) = parser.parse_args() - - - if options.display: - display(options) - elif options.sign: - sign(options) - elif options.importgid: - import_gid(options) - elif options.export: - export_gid(options) - else: - parser.print_help() - sys.exit(1) - - -def display(options): - """ - Display the sepcified GID - """ - gidfile = os.path.abspath(options.display) - if not gidfile or not os.path.isfile(gidfile): - print "No such gid: %s" % gidfile - sys.exit(1) - gid = GID(filename=gidfile) - gid.dump(dump_parents=True) - -def sign(options): - """ - Sign the specified gid - """ - hierarchy = Hierarchy() - config = Config() - default_authority = config.SFA_INTERFACE_HRN - auth_info = hierarchy.get_auth_info(default_authority) - - # load the gid - gidfile = os.path.abspath(options.sign) - if not os.path.isfile(gidfile): - print "no such gid: %s" % gidfile - sys.exit(1) - gid = GID(filename=gidfile) - - # extract pub_key and create new gid - pkey = gid.get_pubkey() - urn = gid.get_urn() - gid = hierarchy.create_gid(urn, create_uuid(), pkey) - - # get the outfile - outfile = options.outfile - if not outfile: - outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn()) - - # save the signed gid - if options.verbose: - print "Writing signed gid %s" % outfile - gid.save_to_file(outfile, save_parents=True) - - -def export_gid(options): - # lookup the record for the specified hrn - hrn = options.export - type = options.type - # check sfa table first - request=dbsession.query(RegRecord).filter_by(hrn=hrn) - if type: request = request.filter_by(type=type) - record=request.first() - if not record: - # check the authorities hierarchy - hierarchy = Hierarchy() - try: - auth_info = hierarchy.get_auth_info(hrn) - gid = auth_info.gid_object - except: - print "Record: %s not found" % hrn - sys.exit(1) - else: - gid = GID(string=record.gid) - - # get the outfile - outfile = options.outfile - if not outfile: - outfile = os.path.abspath('./%s.gid' % gid.get_hrn()) - - # save it - if options.verbose: - print "Writing %s gid to %s" % (gid.get_hrn(), outfile) - gid.save_to_file(outfile, save_parents=True) - -def import_gid(options): - """ - Import the specified gid into the registry (db and authorities - hierarchy) overwriting any previous gid. - """ - # load the gid - gidfile = os.path.abspath(options.importgid) - if not gidfile or not os.path.isfile(gidfile): - print "No such gid: %s" % gidfile - sys.exit(1) - gid = GID(filename=gidfile) - - # check if it exists within the hierarchy - hierarchy = Hierarchy() - if not hierarchy.auth_exists(gid.get_hrn()): - print "%s not found in hierarchy" % gid.get_hrn() - sys.exit(1) - - # check if record exists in db - record = dbsession.query(RegRecord).filter_by(type='authority',hrn=gid.get_hrn()).first() - if not record: - print "%s not found in record database" % gid.get_hrn() - sys.exit(1) - - # update the database record - record.gid = gid.save_to_string(save_parents=True) - dbsession.commit() - if options.verbose: - print "Imported %s gid into db" % record['hrn'] - - # update the hierarchy - auth_info = hierarchy.get_auth_info(gid.get_hrn()) - filename = auth_info.gid_filename - gid.save_to_file(filename, save_parents=True) - if options.verbose: - print "Writing %s gid to %s" % (gid.get_hrn(), filename) - - # ending here - return - -if __name__ == '__main__': - main() diff --git a/sfa/storage/dbschema.py b/sfa/storage/dbschema.py index 3776d527..4c99fb2b 100644 --- a/sfa/storage/dbschema.py +++ b/sfa/storage/dbschema.py @@ -120,7 +120,10 @@ class DBSchema: def nuke (self): model.drop_tables(self.engine) # so in this case it's like we haven't initialized the db at all - migrate.drop_version_control (self.url, self.repository) + try: + migrate.drop_version_control (self.url, self.repository) + except migrate.exceptions.DatabaseNotControlledError: + logger.log_exc("Failed to drop version control") if __name__ == '__main__': diff --git a/sfa/storage/record.py b/sfa/storage/record.py index b31ed26a..254ca3d5 100644 --- a/sfa/storage/record.py +++ b/sfa/storage/record.py @@ -14,6 +14,10 @@ class Record: xml_dict = xml_record.todict() self.load_from_dict(xml_dict) + + def get_field(self, field): + return self.__dict__.get(field, None) + # xxx fixme # turns out the date_created field is received by the client as a 'created' int # (and 'last_updated' does not make it at all) @@ -33,6 +37,9 @@ class Record: d=self.__dict__ keys=[k for k in d.keys() if not k.startswith('_')] return dict ( [ (k,d[k]) for k in keys ] ) + + def toxml(self): + return self.save_as_xml() def load_from_dict (self, d): for (k,v) in d.iteritems(): @@ -44,14 +51,13 @@ class Record: # in addition we provide convenience for converting to and from xml records # for this purpose only, we need the subclasses to define 'fields' as either # a list or a dictionary - def xml_fields (self): - fields=self.fields - if isinstance(fields,dict): fields=fields.keys() + def fields (self): + fields = self.__dict__.keys() return fields def save_as_xml (self): # xxx not sure about the scope here - input_dict = dict( [ (key, getattr(self.key), ) for key in self.xml_fields() if getattr(self,key,None) ] ) + input_dict = dict( [ (key, getattr(self,key)) for key in self.fields() if getattr(self,key,None) ] ) xml_record=XML("") xml_record.parse_dict (input_dict) return xml_record.toxml() @@ -71,29 +77,23 @@ class Record: raise Exception, "Invalid format %s" % format def dump_text(self, dump_parents=False): - # print core fields in this order - core_fields = [ 'hrn', 'type', 'authority', 'date_created', 'created', 'last_updated', 'gid', ] print "".join(['=' for i in range(40)]) print "RECORD" - print " hrn:", self.hrn - print " type:", self.type - print " authority:", self.authority - print " date created:", self.date_repr( ['date_created','created'] ) - print " last updated:", self.date_repr('last_updated') - print " gid:" - if self.gid: - print GID(self.gid).dump_string(8, dump_parents) - # print remaining fields - for attrib_name in dir(self): + for attrib_name in self.fields(): attrib = getattr(self, attrib_name) # skip internals if attrib_name.startswith('_'): continue - # skip core fields - if attrib_name in core_fields: continue # skip callables if callable (attrib): continue - print " %s: %s" % (attrib_name, attrib) + # handle gid + if attrib_name == 'gid': + print " gid:" + print GID(attrib).dump_string(8, dump_parents) + elif attrib_name in ['date created', 'last updated']: + print " %s: %s" % (attrib_name, self.date_repr(attrib_name)) + else: + print " %s: %s" % (attrib_name, attrib) def dump_simple(self): return "%s"%self