Merge branch 'master' into sqlalchemy
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Tue, 24 Jan 2012 12:23:50 +0000 (13:23 +0100)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Tue, 24 Jan 2012 12:23:50 +0000 (13:23 +0100)
Conflicts:
sfa/managers/registry_manager_openstack.py

1  2 
sfa/client/sfi.py
sfa/managers/registry_manager_openstack.py
sfa/server/sfa-clean-peer-records.py
sfa/server/sfa-start.py

diff --combined sfa/client/sfi.py
@@@ -28,8 -28,7 +28,8 @@@ from sfa.util.config import Confi
  from sfa.util.version import version_core
  from sfa.util.cache import Cache
  
 -from sfa.storage.record import SfaRecord, UserRecord, SliceRecord, NodeRecord, AuthorityRecord
 +from sfa.storage.persistentobjs import RegRecord, RegAuthority, RegUser, RegSlice, RegNode
 +from sfa.storage.persistentobjs import make_record
  
  from sfa.rspecs.rspec import RSpec
  from sfa.rspecs.rspec_converter import RSpecConverter
@@@ -107,35 -106,44 +107,35 @@@ def save_rspec_to_file(rspec, filename)
      f.close()
      return
  
 -def save_records_to_file(filename, recordList, format="xml"):
 +def save_records_to_file(filename, record_dicts, format="xml"):
      if format == "xml":
          index = 0
 -        for record in recordList:
 +        for record_dict in record_dicts:
              if index > 0:
 -                save_record_to_file(filename + "." + str(index), record)
 +                save_record_to_file(filename + "." + str(index), record_dict)
              else:
 -                save_record_to_file(filename, record)
 +                save_record_to_file(filename, record_dict)
              index = index + 1
      elif format == "xmllist":
          f = open(filename, "w")
          f.write("<recordlist>\n")
 -        for record in recordList:
 -            record = SfaRecord(dict=record)
 -            f.write('<record hrn="' + record.get_name() + '" type="' + record.get_type() + '" />\n')
 +        for record_dict in record_dicts:
 +            record_obj=make_record (dict=record_dict)
 +            f.write('<record hrn="' + record_obj.hrn + '" type="' + record_obj.type + '" />\n')
          f.write("</recordlist>\n")
          f.close()
      elif format == "hrnlist":
          f = open(filename, "w")
 -        for record in recordList:
 -            record = SfaRecord(dict=record)
 -            f.write(record.get_name() + "\n")
 +        for record_dict in record_dicts:
 +            record_obj=make_record (dict=record_dict)
 +            f.write(record_obj.hrn + "\n")
          f.close()
      else:
          # this should never happen
          print "unknown output format", format
  
 -def save_record_to_file(filename, record):
 -    if record['type'] in ['user']:
 -        record = UserRecord(dict=record)
 -    elif record['type'] in ['slice']:
 -        record = SliceRecord(dict=record)
 -    elif record['type'] in ['node']:
 -        record = NodeRecord(dict=record)
 -    elif record['type'] in ['authority', 'ma', 'sa']:
 -        record = AuthorityRecord(dict=record)
 -    else:
 -        record = SfaRecord(dict=record)
 +def save_record_to_file(filename, record_dict):
 +    rec_record = make_record (dict=record_dict)
      str = record.save_to_string()
      f=codecs.open(filename, encoding='utf-8',mode="w")
      f.write(str)
  # load methods
  def load_record_from_file(filename):
      f=codecs.open(filename, encoding="utf-8", mode="r")
 -    str = f.read()
 +    xml_string = f.read()
      f.close()
 -    record = SfaRecord(string=str)
 -    return record
 +    return make_record (xml=xml_string)
  
  
  import uuid
@@@ -323,6 -332,8 +323,8 @@@ class Sfi
                           help="root registry", metavar="URL", default=None)
          parser.add_option("-s", "--sliceapi", dest="sm", default=None, metavar="URL",
                           help="slice API - in general a SM URL, but can be used to talk to an aggregate")
+         parser.add_option("-R", "--raw", dest="raw", action="store_true", default=False,
+                           help="Display raw, unparsed server response")   
          parser.add_option("-d", "--dir", dest="sfi_dir",
                           help="config & working directory - default is %default",
                           metavar="PATH", default=Sfi.default_sfi_dir())
@@@ -699,16 -710,27 +701,16 @@@ or version information about sfi itsel
              self.print_help()
              sys.exit(1)
          hrn = args[0]
 -        records = self.registry().Resolve(hrn, self.my_credential_string)
 -        records = filter_records(options.type, records)
 -        if not records:
 +        record_dicts = self.registry().Resolve(hrn, self.my_credential_string)
 +        record_dicts = filter_records(options.type, record_dicts)
 +        if not record_dicts:
              self.logger.error("No record of type %s"% options.type)
 +        records = [ make_record (dict=record_dict) for record_dict in record_dicts ]
          for record in records:
 -            if record['type'] in ['user']:
 -                record = UserRecord(dict=record)
 -            elif record['type'] in ['slice']:
 -                record = SliceRecord(dict=record)
 -            elif record['type'] in ['node']:
 -                record = NodeRecord(dict=record)
 -            elif record['type'].startswith('authority'):
 -                record = AuthorityRecord(dict=record)
 -            else:
 -                record = SfaRecord(dict=record)
 -            if (options.format == "text"): 
 -                record.dump()  
 -            else:
 -                print record.save_to_string() 
 +            if (options.format == "text"):      record.dump()  
 +            else:                               print record.save_as_xml() 
          if options.file:
 -            save_records_to_file(options.file, records, options.fileformat)
 +            save_records_to_file(options.file, record_dicts, options.fileformat)
          return
      
      def add(self, options, args):
              sys.exit(1)
          record_filepath = args[0]
          rec_file = self.get_record_file(record_filepath)
 -        record = load_record_from_file(rec_file).as_dict()
 +        record = load_record_from_file(rec_file).todict()
          return self.registry().Register(record, auth_cred)
      
      def update(self, options, args):
              sys.exit(1)
          rec_file = self.get_record_file(args[0])
          record = load_record_from_file(rec_file)
 -        if record['type'] == "user":
 -            if record.get_name() == self.user:
 +        if record.type == "user":
 +            if record.hrn == self.user:
                  cred = self.my_credential_string
              else:
                  cred = self.my_authority_credential_string()
 -        elif record['type'] in ["slice"]:
 +        elif record.type in ["slice"]:
              try:
 -                cred = self.slice_credential_string(record.get_name())
 +                cred = self.slice_credential_string(record.hrn)
              except ServerException, e:
                 # XXX smbaker -- once we have better error return codes, update this
                 # to do something better than a string compare
                     cred = self.my_authority_credential_string()
                 else:
                     raise
 -        elif record.get_type() in ["authority"]:
 +        elif record.type in ["authority"]:
              cred = self.my_authority_credential_string()
 -        elif record.get_type() == 'node':
 +        elif record.type == 'node':
              cred = self.my_authority_credential_string()
          else:
 -            raise "unknown record type" + record.get_type()
 -        record = record.as_dict()
 -        return self.registry().Update(record, cred)
 +            raise "unknown record type" + record.type
 +        record_dict = record.todict()
 +        return self.registry().Update(record_dict, cred)
    
      def remove(self, options, args):
          "remove registry record by name (Remove)"
        api_options['call_id']=unique_call_id()
          result = server.ListSlices(creds, *self.ois(server,api_options))
          value = ReturnValue.get_value(result)
-         display_list(value)
+         if self.options.raw:
+             print result
+         else:
+             display_list(value)
          return
      
      # show rspec for named slice
@@@ -832,7 -857,10 +837,10 @@@ or with an slice hrn, shows currently p
          result = server.ListResources (creds, api_options)
          value = ReturnValue.get_value(result)
          if options.file is None:
-             display_rspec(value, options.format)
+             if self.options.raw:
+                 print result
+             else:
+                 display_rspec(value, options.format)
          else:
              save_rspec_to_file(value, options.file)
          return
          result = server.CreateSliver(slice_urn, creds, rspec, users, *self.ois(server, api_options))
          value = ReturnValue.get_value(result)
          if options.file is None:
-             print value
+             if self.options.raw:
+                 print result
+             else:
+                 print value
          else:
              save_rspec_to_file (value, options.file)
          return value
          api_options = {}
          api_options ['call_id'] = unique_call_id()
          result = server.DeleteSliver(slice_urn, creds, *self.ois(server, api_options ) )
-         # xxx no ReturnValue ??
-         return result
+         value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
+         return value 
    
      def status(self, options, args):
          """
  
          # options and call_id when supported
          api_options = {}
-       api_options['call_id']=unique_call_id()
+         api_options['call_id']=unique_call_id()
          result = server.SliverStatus(slice_urn, creds, *self.ois(server,api_options))
          value = ReturnValue.get_value(result)
-         print value
+         if self.options.raw:
+             print result
+         else:
+             print value
          if options.file:
              save_variable_to_file(value, options.file, options.fileformat)
  
              delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
              creds.append(delegated_cred)
          # xxx Thierry - does this not need an api_options as well ?
-         return server.Start(slice_urn, creds)
+         result = server.Start(slice_urn, creds)
+         value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
+         return value
      
      def stop(self, options, args):
          """
          if options.delegate:
              delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
              creds.append(delegated_cred)
-         return server.Stop(slice_urn, creds)
+         result =  server.Stop(slice_urn, creds)
+         value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
+         return value
      
      # reset named slice
      def reset(self, options, args):
          if options.delegate:
              delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
              creds.append(delegated_cred)
-         return server.reset_slice(creds, slice_urn)
+         result = server.reset_slice(creds, slice_urn)
+         value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
+         return value
  
      def renew(self, options, args):
          """
        api_options['call_id']=unique_call_id()
          result =  server.RenewSliver(slice_urn, creds, time, *self.ois(server,api_options))
          value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
          return value
  
  
          if options.delegate:
              delegated_cred = self.delegate_cred(slice_cred, get_authority(self.authority))
              creds.append(delegated_cred)
-         return server.Shutdown(slice_urn, creds)         
+         result = server.Shutdown(slice_urn, creds)
+         value = ReturnValue.get_value(result)
+         if self.options.raw:
+             print result
+         else:
+             print value
+         return value         
      
  
      def get_ticket(self, options, args):
@@@ -1,4 -1,5 +1,4 @@@
  import types
 -import time 
  # for get_key_from_incoming_ip
  import tempfile
  import os
@@@ -12,33 -13,16 +12,19 @@@ from sfa.util.xrn import Xrn, get_autho
  from sfa.util.plxrn import hrn_to_pl_login_base
  from sfa.util.version import version_core
  from sfa.util.sfalogging import logger
 +
  from sfa.trust.gid import GID 
  from sfa.trust.credential import Credential
  from sfa.trust.certificate import Certificate, Keypair, convert_public_key
  from sfa.trust.gid import create_uuid
 -from sfa.storage.record import SfaRecord
 -from sfa.storage.table import SfaTable
 -from sfa.managers import registry_manager
  
 -class RegistryManager(registry_manager.RegistryManager):
 +from sfa.storage.persistentobjs import make_record,RegRecord
 +from sfa.storage.alchemy import dbsession
 +
 +from sfa.managers.registry_manager import RegistryManager
 +
 +class RegistryManager(RegistryManager):
  
-     def __init__ (self, config): pass
-     # The GENI GetVersion call
-     def GetVersion(self, api, options):
-         peers = dict ( [ (hrn,interface.get_url()) for (hrn,interface) in api.registries.iteritems() 
-                        if hrn != api.hrn])
-         xrn=Xrn(api.hrn)
-         return version_core({'interface':'registry',
-                              'sfa': 2,
-                              'geni_api': 2,
-                              'hrn':xrn.get_hrn(),
-                              'urn':xrn.get_urn(),
-                              'peers':peers})
-     
      def GetCredential(self, api, xrn, type, is_self=False):
          # convert xrn to hrn     
          if type:
          auth_hrn = api.auth.get_authority(hrn)
          if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
              auth_hrn = hrn
 -        # get record info
          auth_info = api.auth.get_auth_info(auth_hrn)
 -        table = SfaTable()
 -        records = table.findObjects({'type': type, 'hrn': hrn})
 -        if not records:
 -            raise RecordNotFound(hrn)
 -        record = records[0]
 +        # get record info
 +        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
 +        if not record:
 +            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))
      
          # verify_cancreate_credential requires that the member lists
          # (researchers, pis, etc) be filled in
 -        self.driver.augment_records_with_testbed_info (record)
 -        if not self.driver.is_enabled (record):
 -              raise AccountNotEnabled(": PlanetLab account %s is not enabled. Please contact your site PI" %(record['email']))
 +        logger.debug("get credential before augment dict, keys=%s"%record.__dict__.keys())
 +        self.driver.augment_records_with_testbed_info (record.__dict__)
 +        logger.debug("get credential after augment dict, keys=%s"%record.__dict__.keys())
 +        if not self.driver.is_enabled (record.__dict__):
 +              raise AccountNotEnabled(": PlanetLab account %s is not enabled. Please contact your site PI" %(record.email))
      
          # get the callers gid
          # if this is a self cred the record's gid is the caller's gid
              caller_hrn = caller_gid.get_hrn()
          
          object_hrn = record.get_gid_object().get_hrn()
 -        rights = api.auth.determine_user_rights(caller_hrn, record)
 +        rights = api.auth.determine_user_rights(caller_hrn, record.__dict__)
          # make sure caller has rights to this object
          if rights.is_empty():
 -            raise PermissionError(caller_hrn + " has no rights to " + record['name'])
 +            raise PermissionError(caller_hrn + " has no rights to " + record.hrn)
      
 -        object_gid = GID(string=record['gid'])
 +        object_gid = GID(string=record.gid)
          new_cred = Credential(subject = object_gid.get_subject())
          new_cred.set_gid_caller(caller_gid)
          new_cred.set_gid_object(object_gid)
@@@ -87,8 -71,8 +73,8 @@@
          #new_cred.set_pubkey(object_gid.get_pubkey())
          new_cred.set_privileges(rights)
          new_cred.get_privileges().delegate_all_privileges(True)
 -        if 'expires' in record:
 -            date = utcparse(record['expires'])
 +        if hasattr(record,'expires'):
 +            date = utcparse(record.expires)
              expires = datetime_to_epoch(date)
              new_cred.set_expiration(int(expires))
          auth_kind = "authority,ma,sa"
          return new_cred.save_to_string(save_parents=True)
      
      
-     def Resolve(self, api, xrns, type=None, full=True):
-     
-         if not isinstance(xrns, types.ListType):
-             xrns = [xrns]
-             # try to infer type if not set and we get a single input
-             if not type:
-                 type = Xrn(xrns).get_type()
-         hrns = [urn_to_hrn(xrn)[0] for xrn in xrns] 
-         # load all known registry names into a prefix tree and attempt to find
-         # the longest matching prefix
-         # create a dict where key is a registry hrn and its value is a list
-         # of hrns at that registry (determined by the known prefix tree).  
-         xrn_dict = {}
-         registries = api.registries
-         tree = prefixTree()
-         registry_hrns = registries.keys()
-         tree.load(registry_hrns)
-         for xrn in xrns:
-             registry_hrn = tree.best_match(urn_to_hrn(xrn)[0])
-             if registry_hrn not in xrn_dict:
-                 xrn_dict[registry_hrn] = []
-             xrn_dict[registry_hrn].append(xrn)
-             
-         records = [] 
-         for registry_hrn in xrn_dict:
-             # skip the hrn without a registry hrn
-             # XX should we let the user know the authority is unknown?       
-             if not registry_hrn:
-                 continue
-     
-             # if the best match (longest matching hrn) is not the local registry,
-             # forward the request
-             xrns = xrn_dict[registry_hrn]
-             if registry_hrn != api.hrn:
-                 credential = api.getCredential()
-                 interface = api.registries[registry_hrn]
-                 server_proxy = api.server_proxy(interface, credential)
-                 peer_records = server_proxy.Resolve(xrns, credential,type)
-                 # pass foreign records as-is
-                 # previous code used to read
-                 # records.extend([SfaRecord(dict=record).as_dict() for record in peer_records])
-                 # not sure why the records coming through xmlrpc had to be processed at all
-                 records.extend(peer_records)
-     
-         # try resolving the remaining unfound records at the local registry
-         local_hrns = list ( set(hrns).difference([record['hrn'] for record in records]) )
-         # 
-         local_records = dbsession.query(RegRecord).filter(RegRecord.hrn.in_(local_hrns))
-         if type:
-             local_records = local_records.filter_by(type=type)
-         local_records=local_records.all()
-         logger.info("Resolve: local_records=%s (type=%s)"%(local_records,type))
-         local_dicts = [ record.__dict__ for record in local_records ]
-         
-         if full:
-             # in full mode we get as much info as we can, which involves contacting the 
-             # testbed for getting implementation details about the record
-             self.driver.augment_records_with_testbed_info(local_dicts)
-             # also we fill the 'url' field for known authorities
-             # used to be in the driver code, sounds like a poorman thing though
-             def solve_neighbour_url (record):
-                 if not record.type.startswith('authority'): return 
-                 hrn=record.hrn
-                 for neighbour_dict in [ api.aggregates, api.registries ]:
-                     if hrn in neighbour_dict:
-                         record.url=neighbour_dict[hrn].get_url()
-                         return 
-             for record in local_records: solve_neighbour_url (record)
-         
-         # convert local record objects to dicts for xmlrpc
-         # xxx somehow here calling dict(record) issues a weird error
-         # however record.todict() seems to work fine
-         # records.extend( [ dict(record) for record in local_records ] )
-         records.extend( [ record.todict() for record in local_records ] )    
-         if not records:
-             raise RecordNotFound(str(hrns))
-     
-         return records
-     
-     def List (self, api, xrn, origin_hrn=None):
-         hrn, type = urn_to_hrn(xrn)
-         # load all know registry names into a prefix tree and attempt to find
-         # the longest matching prefix
-         registries = api.registries
-         registry_hrns = registries.keys()
-         tree = prefixTree()
-         tree.load(registry_hrns)
-         registry_hrn = tree.best_match(hrn)
-        
-         #if there was no match then this record belongs to an unknow registry
-         if not registry_hrn:
-             raise MissingAuthority(xrn)
-         # if the best match (longest matching hrn) is not the local registry,
-         # forward the request
-         record_dicts = []    
-         if registry_hrn != api.hrn:
-             credential = api.getCredential()
-             interface = api.registries[registry_hrn]
-             server_proxy = api.server_proxy(interface, credential)
-             record_list = server_proxy.List(xrn, credential)
-             # same as above, no need to process what comes from through xmlrpc
-             # pass foreign records as-is
-             record_dicts = record_list
-         
-         # if we still have not found the record yet, try the local registry
-         if not record_dicts:
-             if not api.auth.hierarchy.auth_exists(hrn):
-                 raise MissingAuthority(hrn)
-             records = dbsession.query(RegRecord).filter_by(authority=hrn)
-             record_dicts=[ record.todict() for record in records ]
-     
-         return record_dicts
-     
-     
-     def CreateGid(self, api, xrn, cert):
-         # get the authority
-         authority = Xrn(xrn=xrn).get_authority_hrn()
-         auth_info = api.auth.get_auth_info(authority)
-         if not cert:
-             pkey = Keypair(create=True)
-         else:
-             certificate = Certificate(string=cert)
-             pkey = certificate.get_pubkey()    
-         gid = api.auth.hierarchy.create_gid(xrn, create_uuid(), pkey) 
-         return gid.save_to_string(save_parents=True)
-     
-     ####################
-     # utility for handling relationships among the SFA objects 
-     # given that the SFA db does not handle this sort of relationsships
-     # it will rely on side-effects in the testbed to keep this persistent
-     
      # subject_record describes the subject of the relationships
      # ref_record contains the target values for the various relationships we need to manage
      # (to begin with, this is just the slice x person relationship)
 -    def update_relations (self, subject_record, ref_record):
 -        type=subject_record['type']
 +    def update_relations (self, subject_obj, ref_obj):
 +        type=subject_obj.type
          if type=='slice':
 -            self.update_relation(subject_record, 'researcher', ref_record.get('researcher'), 'user')
 +            self.update_relation(subject_obj, 'researcher', ref_obj.researcher, 'user')
          
      # field_key is the name of one field in the record, typically 'researcher' for a 'slice' record
      # hrns is the list of hrns that should be linked to the subject from now on
      # target_type would be e.g. 'user' in the 'slice' x 'researcher' example
 -    def update_relation (self, sfa_record, field_key, hrns, target_type):
 +    def update_relation (self, record_obj, field_key, hrns, target_type):
          # locate the linked objects in our db
 -        subject_type=sfa_record['type']
 -        subject_id=sfa_record['pointer']
 -        table = SfaTable()
 -        link_sfa_records = table.find ({'type':target_type, 'hrn': hrns})
 -        link_ids = [ rec.get('pointer') for rec in link_sfa_records ]
 +        subject_type=record_obj.type
 +        subject_id=record_obj.pointer
 +        # get the 'pointer' field of all matching records
 +        link_id_tuples = dbsession.query(RegRecord.pointer).filter_by(type=target_type).filter(RegRecord.hrn.in_(hrns)).all()
 +        # sqlalchemy returns named tuples for columns
 +        link_ids = [ tuple.pointer for tuple in link_id_tuples ]
          self.driver.update_relation (subject_type, target_type, subject_id, link_ids)
 -        
  
-     def Register(self, api, record_dict):
-     
-         hrn, type = record_dict['hrn'], record_dict['type']
-         urn = hrn_to_urn(hrn,type)
-         # validate the type
-         if type not in ['authority', 'slice', 'node', 'user']:
-             raise UnknownSfaType(type) 
-         
-         # check if record_dict already exists
-         existing_records = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).all()
-         if existing_records:
-             raise ExistingRecord(hrn)
-            
-         assert ('type' in record_dict)
-         # returns the right type of RegRecord according to type in record
-         record = make_record(dict=record_dict)
-         record.just_created()
-         record.authority = get_authority(record.hrn)
-         auth_info = api.auth.get_auth_info(record.authority)
-         pub_key = None
-         # make sure record has a gid
-         if not record.gid:
-             uuid = create_uuid()
-             pkey = Keypair(create=True)
-             if getattr(record,'keys',None):
-                 pub_key=record.keys
-                 # use only first key in record
-                 if isinstance(record.keys, types.ListType):
-                     pub_key = record.keys[0]
-                 pkey = convert_public_key(pub_key)
-     
-             gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
-             gid = gid_object.save_to_string(save_parents=True)
-             record.gid = gid
-     
-         if type in ["authority"]:
-             # update the tree
-             if not api.auth.hierarchy.auth_exists(hrn):
-                 api.auth.hierarchy.create_auth(hrn_to_urn(hrn,'authority'))
-     
-             # get the GID from the newly created authority
-             gid = auth_info.get_gid_object()
-             record.gid=gid.save_to_string(save_parents=True)
-         # update testbed-specific data if needed
-         pointer = self.driver.register (record.__dict__, hrn, pub_key)
-         record.pointer=pointer
-         dbsession.add(record)
-         dbsession.commit()
-     
-         # update membership for researchers, pis, owners, operators
-         self.update_relations (record, record)
-         
-         return record.get_gid_object().save_to_string(save_parents=True)
-     
-     def Update(self, api, record_dict):
-         assert ('type' in record_dict)
-         new_record=RegRecord(dict=record_dict)
-         type = new_record.type
-         hrn = new_record.hrn
-         
-         # make sure the record exists
-         record = dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
-         if not record:
-             raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))
-         record.just_updated()
-     
-         # validate the type
-         if type not in ['authority', 'slice', 'node', 'user']:
-             raise UnknownSfaType(type) 
-         # Use the pointer from the existing record, not the one that the user
-         # gave us. This prevents the user from inserting a forged pointer
-         pointer = record.pointer
-     
-         # is the a change in keys ?
-         new_key=None
-         if type=='user':
-             if getattr(new_key,'keys',None):
-                 new_key=new_record.keys
-                 if isinstance (new_key,types.ListType):
-                     new_key=new_key[0]
-         # update the PLC information that was specified with the record
-         if not self.driver.update (record.__dict__, new_record.__dict__, hrn, new_key):
-             logger.warning("driver.update failed")
-     
-         # take new_key into account
-         if new_key:
-             # update the openssl key and gid
-             pkey = convert_public_key(new_key)
-             uuid = create_uuid()
-             urn = hrn_to_urn(hrn,type)
-             gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
-             gid = gid_object.save_to_string(save_parents=True)
-             record.gid = gid
-             dsession.commit()
-         
-         # update membership for researchers, pis, owners, operators
-         self.update_relations (record, new_record)
-         
-         return 1 
-     
-     # expecting an Xrn instance
-     def Remove(self, api, xrn, origin_hrn=None):
-         hrn=xrn.get_hrn()
-         type=xrn.get_type()
-         request=dbsession.query(RegRecord).filter_by(hrn=hrn)
-         if type and type not in ['all', '*']:
-             request=request.filter_by(type=type)
-     
-         record = request.first()
-         if not record:
-             msg="Could not find hrn %s"%hrn
-             if type: msg += " type=%s"%type
-             raise RecordNotFound(msg)
-         type = record.type
-         if type not in ['slice', 'user', 'node', 'authority'] :
-             raise UnknownSfaType(type)
-         credential = api.getCredential()
-         registries = api.registries
-     
-         # Try to remove the object from the PLCDB of federated agg.
-         # This is attempted before removing the object from the local agg's PLCDB and sfa table
-         if hrn.startswith(api.hrn) and type in ['user', 'slice', 'authority']:
-             for registry in registries:
-                 if registry not in [api.hrn]:
-                     try:
-                         result=registries[registry].remove_peer_object(credential, record, origin_hrn)
-                     except:
-                         pass
-         # call testbed callback first
-         # IIUC this is done on the local testbed TOO because of the refreshpeer link
-         if not self.driver.remove(record.__dict__):
-             logger.warning("driver.remove failed")
-         # delete from sfa db
-         dbsession.delete(record)
-         dbsession.commit()
-     
-         return 1
-     # This is a PLC-specific thing, won't work with other platforms
-     def get_key_from_incoming_ip (self, api):
-         # verify that the callers's ip address exist in the db and is an interface
-         # for a node in the db
-         (ip, port) = api.remote_addr
-         interfaces = self.driver.shell.GetInterfaces({'ip': ip}, ['node_id'])
-         if not interfaces:
-             raise NonExistingRecord("no such ip %(ip)s" % locals())
-         nodes = self.driver.shell.GetNodes([interfaces[0]['node_id']], ['node_id', 'hostname'])
-         if not nodes:
-             raise NonExistingRecord("no such node using ip %(ip)s" % locals())
-         node = nodes[0]
-        
-         # look up the sfa record
-         record=dbsession.query(RegRecord).filter_by(type='node',pointer=node['node_id']).first()
-         if not record:
-             raise RecordNotFound("node with pointer %s"%node['node_id'])
-         
-         # generate a new keypair and gid
-         uuid = create_uuid()
-         pkey = Keypair(create=True)
-         urn = hrn_to_urn(record.hrn, record.type)
-         gid_object = api.auth.hierarchy.create_gid(urn, uuid, pkey)
-         gid = gid_object.save_to_string(save_parents=True)
-         record.gid = gid
-         # update the record
-         dbsession.commit()
-   
-         # attempt the scp the key
-         # and gid onto the node
-         # this will only work for planetlab based components
-         (kfd, key_filename) = tempfile.mkstemp() 
-         (gfd, gid_filename) = tempfile.mkstemp() 
-         pkey.save_to_file(key_filename)
-         gid_object.save_to_file(gid_filename, save_parents=True)
-         host = node['hostname']
-         key_dest="/etc/sfa/node.key"
-         gid_dest="/etc/sfa/node.gid" 
-         scp = "/usr/bin/scp" 
-         #identity = "/etc/planetlab/root_ssh_key.rsa"
-         identity = "/etc/sfa/root_ssh_key"
-         scp_options=" -i %(identity)s " % locals()
-         scp_options+="-o StrictHostKeyChecking=no " % locals()
-         scp_key_command="%(scp)s %(scp_options)s %(key_filename)s root@%(host)s:%(key_dest)s" %\
-                          locals()
-         scp_gid_command="%(scp)s %(scp_options)s %(gid_filename)s root@%(host)s:%(gid_dest)s" %\
-                          locals()    
-         all_commands = [scp_key_command, scp_gid_command]
-         
-         for command in all_commands:
-             (status, output) = commands.getstatusoutput(command)
-             if status:
-                 raise Exception, output
-         for filename in [key_filename, gid_filename]:
-             os.unlink(filename)
-         return 1 
@@@ -12,8 -12,7 +12,8 @@@ from sfa.trust.certificate import Keypa
  from sfa.trust.hierarchy import Hierarchy
  from sfa.server.registry import Registries
  
 -from sfa.storage.table import SfaTable
 +from sfa.storage.alchemy import dbsession
 +from sfa.storage.persistentobjs import RegRecord
  
  from sfa.client.sfaserverproxy import SfaServerProxy 
  
@@@ -27,9 -26,9 +27,9 @@@ def main()
      # Get the path to the sfa server key/cert files from 
      # the sfa hierarchy object
      sfa_hierarchy = Hierarchy()
-     sfa_key_path = sfa_hierarchy.basedir
-     key_file = os.path.join(sfa_key_path, "server.key")
-     cert_file = os.path.join(sfa_key_path, "server.cert")
+     auth_info = sfa_hierarchy.get_interface_auth_info()
+     key_file = auth_info.get_privkey_filename()
+     cert_file = auth_info.get_gid_filename()
      key = Keypair(filename=key_file) 
  
      # get a connection to our local sfa registry
      tree.load(registries.keys())
      
      # get local peer records
 -    table = SfaTable()
 -    peer_records = table.find({'~peer_authority': None})
 +    peer_records=dbsession.query(RegRecord).filter (RegRecord.peer_authority != None).all()
      found_records = []
      hrn_dict = {}
      for record in peer_records:
 -        registry_hrn = tree.best_match(record['hrn'])
 +        registry_hrn = tree.best_match(record.hrn)
          if registry_hrn not in hrn_dict:
              hrn_dict[registry_hrn] = []
 -        hrn_dict[registry_hrn].append(record['hrn'])
 +        hrn_dict[registry_hrn].append(record.hrn)
  
      # attempt to resolve the record at the authoritative interface 
      for registry_hrn in hrn_dict:
@@@ -75,8 -75,8 +75,8 @@@
  
      # remove what wasnt found 
      for peer_record in peer_records:
 -        if peer_record['hrn'] not in found_records:
 -            registries[sfa_api.hrn].Remove(peer_record['hrn'], credential, peer_record['type'])
 +        if peer_record.hrn not in found_records:
 +            registries[sfa_api.hrn].Remove(peer_record.hrn, credential, peer_record.type)
                  
  if __name__ == '__main__':
      main()
diff --combined sfa/server/sfa-start.py
@@@ -40,10 -40,10 +40,10 @@@ from sfa.trust.trustedroots import Trus
  from sfa.trust.certificate import Keypair, Certificate
  from sfa.trust.hierarchy import Hierarchy
  from sfa.trust.gid import GID
  from sfa.server.sfaapi import SfaApi
  from sfa.server.registry import Registries
  from sfa.server.aggregate import Aggregates
+ from sfa.client.return_value import ReturnValue
  
  # after http://www.erlenstar.demon.co.uk/unix/faq_2.html
  def daemon():
@@@ -100,7 -100,7 +100,7 @@@ def install_peer_certs(server_key_file
                  logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
                  continue
        
-             trusted_gids = interface.get_trusted_certs()
+             trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
              if trusted_gids:
                  # the gid we want should be the first one in the list,
                  # but lets make sure
                      message = "interface: %s\t" % (api.interface)
                      message += "unable to install trusted gid for %s" % \
                                 (new_hrn)
-                     gid = GID(string=trusted_gids[0])
+                     gid = GID(string=trusted_gid)
                      peer_gids.append(gid)
                      if gid.get_hrn() == new_hrn:
                          gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn)
@@@ -129,35 -129,35 +129,35 @@@ def update_cert_records(gids)
      Make sure there is a record in the registry for the specified gids. 
      Removes old records from the db.
      """
 -    # import SfaTable here so this module can be loaded by PlcComponentApi
 -    from sfa.storage.table import SfaTable
 -    from sfa.storage.record import SfaRecord
 +    # import db stuff here here so this module can be loaded by PlcComponentApi
 +    from sfa.storage.alchemy import dbsession
 +    from sfa.storage.persistentobjs import RegRecord
      if not gids:
          return
 -    table = SfaTable()
      # get records that actually exist in the db
      gid_urns = [gid.get_urn() for gid in gids]
      hrns_expected = [gid.get_hrn() for gid in gids]
 -    records_found = table.find({'hrn': hrns_expected, 'pointer': -1}) 
 +    records_found = dbsession.query(RegRecord).\
 +        filter_by(pointer=-1).filter(RegRecord.hrn.in_(hrns_expected)).all()
  
      # remove old records
      for record in records_found:
 -        if record['hrn'] not in hrns_expected and \
 -            record['hrn'] != self.api.config.SFA_INTERFACE_HRN:
 -            table.remove(record)
 +        if record.hrn not in hrns_expected and \
 +            record.hrn != self.api.config.SFA_INTERFACE_HRN:
 +            dbsession.delete(record)
  
      # TODO: store urn in the db so we do this in 1 query 
      for gid in gids:
          hrn, type = gid.get_hrn(), gid.get_type()
 -        record = table.find({'hrn': hrn, 'type': type, 'pointer': -1})
 +        record = dbsession.query(RegRecord).filter_by(hrn=hrn, type=type,pointer=-1).first()
          if not record:
 -            record = {
 -                'hrn': hrn, 'type': type, 'pointer': -1,
 -                'authority': get_authority(hrn),
 -                'gid': gid.save_to_string(save_parents=True),
 -            }
 -            record = SfaRecord(dict=record)
 -            table.insert(record)
 +            record = RegRecord (dict= {'type':type,
 +                                       'hrn': hrn, 
 +                                       'authority': get_authority(hrn),
 +                                       'gid': gid.save_to_string(save_parents=True),
 +                                       })
 +            dbsession.add(record)
 +    dbsession.commit()
          
  def main():
      # Generate command line parser