Merged trunk in from 17245:17645
authorJosh Karlin <jkarlin@bbn.com>
Mon, 12 Apr 2010 18:15:22 +0000 (18:15 +0000)
committerJosh Karlin <jkarlin@bbn.com>
Mon, 12 Apr 2010 18:15:22 +0000 (18:15 +0000)
33 files changed:
TODO
config/default_config.xml
setup.py
sfa.spec
sfa/client/sfi.py
sfa/managers/aggregate_manager_pl.py
sfa/managers/registry_manager_pl.py
sfa/managers/slice_manager_pl.py
sfa/methods/CreateSliver.py [new file with mode: 0644]
sfa/methods/ListResources.py [new file with mode: 0644]
sfa/methods/get_credential.py
sfa/methods/get_resources.py
sfa/methods/get_trusted_certs.py
sfa/plc/api.py
sfa/plc/nodes.py
sfa/plc/slices.py
sfa/server/aggregate.py
sfa/server/interface.py [new file with mode: 0644]
sfa/server/modpython/SfaAggregateModPython.py [moved from sfa/server/SfaAggregateModPython.py with 100% similarity]
sfa/server/modpython/SfaRegistryModPython.py [moved from sfa/server/SfaRegistryModPython.py with 100% similarity]
sfa/server/modpython/SfaSliceMgrModPython.py [moved from sfa/server/SfaSliceMgrModPython.py with 100% similarity]
sfa/server/modpython/sfa.aggregate.httpd.conf [moved from sfa/server/sfa.aggregate.httpd.conf with 100% similarity]
sfa/server/modpython/sfa.registry.httpd.conf [moved from sfa/server/sfa.registry.httpd.conf with 100% similarity]
sfa/server/modpython/sfa.slicemgr.httpd.conf [moved from sfa/server/sfa.slicemgr.httpd.conf with 100% similarity]
sfa/server/registry.py
sfa/server/sfa-server.py
sfa/server/sfa_component_setup.py
sfa/trust/auth.py
sfa/trust/rights.py
sfa/util/api.py
sfa/util/record.py
sfa/util/server.py
sfa/util/table.py

diff --git a/TODO b/TODO
index 99db1ad..cafce3e 100644 (file)
--- a/TODO
+++ b/TODO
   slices were on it and recreate them? do we make some sort of transaction log)   
 
 - Registry
-* sfa.plc.api.SfaAPI.fill_record_pl_info() should add the sites PIs to a slice records researchers list
+* sign peer gids 
 * update call should attempt to push updates to federated peers if 
   the peer has a record for an object that is updated locally  
 * api.update_membership() shoudl behave more like resolve when looking up records (attempt to resolve records at federated registeries) instead of only looking in the local registry
-* support generic registry records (dont depend on postgres!)
+* move db tables into db with less overhead (tokyocabinet?)
+* make resolve, fill_record_info more fault tolerent. Skip records with failures
 
 - Auth Service
   * develop a simple service where users auth using username/passord and 
index 7e5dfdf..a63b56b 100644 (file)
@@ -106,6 +106,12 @@ $URL$
          <description>The type of backend server for this
          aggregate. Some aggregates may not be myplc.</description>
        </variable>
+    
+    <variable id="rspec_schema" type="string">
+      <name>RSpec Schema</name>
+      <value>/etc/sfa/pl.rng</value>
+      <description>The path to the default schema</description>
+    </variable>
 
        <variable id="host" type="hostname">
          <name>Hostname</name>
index 040c76e..8d77792 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,8 @@ data_files = [('/etc/sfa/', [ 'config/aggregates.xml',
                               'config/geni_aggregates.xml',
                               'config/registries.xml',
                               'config/default_config.xml',
-                              'config/sfi_config']),
+                              'config/sfi_config',
+                              'sfa/managers/pl/pl.rng']),
               ('/etc/sfatables/matches/', glob('sfatables/matches/*.xml')),
               ('/etc/sfatables/targets/', glob('sfatables/targets/*.xml')),
               ('/etc/init.d/', ['sfa/init.d/sfa', 'sfa/init.d/sfa-cm'])]
index b5d9c42..2e32acb 100644 (file)
--- a/sfa.spec
+++ b/sfa.spec
@@ -6,7 +6,7 @@
 
 %define name sfa
 %define version 0.9
-%define taglevel 10
+%define taglevel 11
 
 %define release %{taglevel}%{?pldistro:.%{pldistro}}%{?date:.%{date}}
 %global python_sitearch        %( python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)" )
@@ -154,6 +154,14 @@ chkconfig --add sfa
 %post cm
 chkconfig --add sfa-cm
 %changelog
+* Thu Apr 08 2010 Tony Mack <tmack@cs.princeton.edu> - sfa-0.9-11
+- SfaServer now uses a pool of threads to handle requests concurrently
+- sfa.util.rspec no longer used to process/manage rspecs (deprecated). This is now handled by sfa.plc.network and is not backwards compatible
+- PIs can now get a slice credential for any slice at their site without having to be a member of the slice
+- Registry records for federated peers (defined in registries.xml, aggregates.xml) updated when sfa service is started
+- Interfaces will try to fetch and install gids from peers listed in registries.xml/aggregates.xml if gid is not found in /etc/sfa/trusted_roots dir   
+- Component manager does not install gid files if slice already has them  
 * Thu Jan 21 2010 anil vengalil <avengali@sophia.inria.fr> - sfa-0.9-10
 - This tag is quite same as the previous one (sfa-0.9-9) except that the vini and max aggregate managers are also updated for urn support.  Other features are:
 - - sfa-config-tty now has the same features like plc-config-tty
index 90e1f87..9070bdb 100755 (executable)
@@ -627,7 +627,7 @@ class Sfi:
            print "Error: Object credential", object_hrn, "does not have delegate bit set"
            return
     
-       records = self.registry.resolve(user_cred, args[0])
+       records = self.registry.resolve(user_cred.save_to_string(save_parents=True), args[0])
        records = filter_records("user", records)
     
        if not records:
@@ -635,14 +635,14 @@ class Sfi:
            return
     
        # the gid of the user who will be delegated to
-       delegee_gid = records[0].get_gid_object()
+       delegee_gid = GID(string=records[0]['gid'])
        delegee_hrn = delegee_gid.get_hrn()
-    
+   
        # the key and hrn of the user who will be delegating
        user_key = Keypair(filename = self.get_key_file())
        user_hrn = user_cred.get_gid_caller().get_hrn()
-    
-       dcred = Credential(subject=object_hrn + " delegated to " + delegee_hrn)
+       subject_string = "%s delegated to %s" % (object_hrn, delegee_hrn)
+       dcred = Credential(subject=subject_string)
        dcred.set_gid_caller(delegee_gid)
        dcred.set_gid_object(object_gid)
        privs = object_cred.get_privileges()
index c5f57fe..2ca9db4 100644 (file)
@@ -15,7 +15,6 @@ from sfa.util.record import SfaRecord
 from sfa.util.policy import Policy
 from sfa.util.record import *
 from sfa.util.sfaticket import SfaTicket
-from sfa.server.registry import Registries
 from sfa.util.debug import log
 from sfa.plc.slices import Slices
 import sfa.plc.peers as peers
@@ -56,8 +55,7 @@ def create_slice(api, xrn, xml):
     slices = Slices(api)
     peer = slices.get_peer(hrn)
     sfa_peer = slices.get_sfa_peer(hrn)
-    registries = Registries(api)
-    registry = registries[api.hrn]
+    registry = api.registries[api.hrn]
     credential = api.getCredential()
     site_id, remote_site_id = slices.verify_site(registry, credential, hrn, 
                                                  peer, sfa_peer)
@@ -69,7 +67,8 @@ def create_slice(api, xrn, xml):
     slice = network.get_slice(api, hrn)
     current = __get_hostnames(slice.get_nodes())
 
-    network.addRSpec(xml, "/var/www/html/schemas/pl.rng")
+    network.addRSpec(xml, api.config.SFA_AGGREGATE_RSPEC_SCHEMA)
+    
     request = __get_hostnames(network.nodesWithSlivers())
     
     # remove nodes not in rspec
@@ -98,8 +97,7 @@ def create_slice(api, xrn, xml):
 def get_ticket(api, xrn, rspec, origin_hrn=None):
     slice_hrn, type = urn_to_hrn(xrn)
     # the the slice record
-    registries = Registries(api)
-    registry = registries[api.hrn]
+    registry = api.registries[api.hrn]
     credential = api.getCredential()
     records = registry.resolve(credential, xrn)
     
index 2108c15..18181ae 100644 (file)
@@ -1,6 +1,5 @@
 import types
 import time 
-from sfa.server.registry import Registries
 from sfa.util.prefixTree import prefixTree
 from sfa.util.record import SfaRecord
 from sfa.util.table import SfaTable
@@ -77,8 +76,7 @@ def resolve(api, xrns, type=None, origin_hrn=None, full=True):
     # create a dict whre key is an registry hrn and its value is a
     # hrns at that registry (determined by the known prefix tree).  
     xrn_dict = {}
-    # XX Preload this into the api module
-    registries = Registries(api)
+    registries = api.registries
     tree = prefixTree()
     registry_hrns = registries.keys()
     tree.load(registry_hrns)
@@ -127,7 +125,7 @@ def list(api, xrn, origin_hrn=None):
     # load all know registry names into a prefix tree and attempt to find
     # the longest matching prefix
     records = []
-    registries = Registries(api)
+    registries = api.registries
     registry_hrns = registries.keys()
     tree = prefixTree()
     tree.load(registry_hrns)
@@ -368,7 +366,7 @@ def remove(api, xrn, type, origin_hrn=None):
     type = record['type']
 
     credential = api.getCredential()
-    registries = Registries(api)
+    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
index b3854a0..2c824cf 100644 (file)
@@ -20,13 +20,12 @@ from sfa.util.prefixTree import prefixTree
 from sfa.util.rspec import *
 from sfa.util.sfaticket import *
 from sfa.util.debug import log
-from sfa.server.registry import Registries
-from sfa.server.aggregate import Aggregates
+from sfa.util.sfalogging import logger
 import sfa.plc.peers as peers
 
 def delete_slice(api, xrn, origin_hrn=None):
     credential = api.getCredential()
-    aggregates = Aggregates(api)
+    aggregates = api.aggregates
     for aggregate in aggregates:
         success = False
         # request hash is optional so lets try the call without it
@@ -60,7 +59,7 @@ def create_slice(api, xrn, rspec, origin_hrn=None):
             message = "%s (line %s)" % (error.message, error.line)
             raise InvalidRSpec(message)
 
-    aggs = Aggregates(api)
+    aggs = api.aggregates
     cred = api.getCredential()                                                 
     for agg in aggs:
         if agg not in [api.auth.client_cred.get_gid_caller().get_hrn()]:      
@@ -91,7 +90,7 @@ def get_ticket(api, xrn, rspec, origin_hrn=None):
         rspecs[net_hrn] = temp_rspec.toxml() 
     
     # send the rspec to the appropiate aggregate/sm
-    aggregates = Aggregates(api)
+    aggregates = api.aggregates
     credential = api.getCredential()
     tickets = {}
     for net_hrn in rspecs:
@@ -198,19 +197,22 @@ def get_rspec(api, xrn=None, origin_hrn=None):
     hrn, type = urn_to_hrn(xrn)
     rspec = None
 
-    aggs = Aggregates(api)
+    aggs = api.aggregates
     cred = api.getCredential()                                                 
+
+    print >> log, "Aggregates = %s" % aggs
     for agg in aggs:
         if agg not in [api.auth.client_cred.get_gid_caller().get_hrn()]:      
             try:
                 # get the rspec from the aggregate
                 agg_rspec = aggs[agg].get_resources(cred, xrn, origin_hrn)
             except:
+                
                 # XX print out to some error log
                 print >> log, "Error getting resources at aggregate %s" % agg
                 traceback.print_exc(log)
                 print >> log, "%s" % (traceback.format_exc())
-
+                continue
                 
             try:
                 tree = etree.parse(StringIO(agg_rspec))
diff --git a/sfa/methods/CreateSliver.py b/sfa/methods/CreateSliver.py
new file mode 100644 (file)
index 0000000..28f644e
--- /dev/null
@@ -0,0 +1,57 @@
+from sfa.util.faults import *
+from sfa.util.namespace import *
+from sfa.util.method import Method
+from sfa.util.parameter import Parameter, Mixed
+from sfa.trust.auth import Auth
+from sfa.trust.gid import GID
+from sfa.trust.certificate import Certificate
+
+class CreateSliver(Method):
+    """
+    Allocate resources to a slice.  This operation is expected to
+    start the allocated resources asynchornously after the operation
+    has successfully completed.  Callers can check on the status of
+    the resources using SliverStatus.
+
+    @param slice_urn (string) URN of slice to allocate to
+    @param credentials ([string]) of credentials
+    @param rspec (string) rspec to allocate
+    
+    """
+    interfaces = ['geni_am']
+    accepts = [
+        Parameter(str, "Slice URN"),
+        Parameter(type([str]), "List of credentials"),
+        Parameter(str, "RSpec")
+        ]
+    returns = Parameter(str, "Allocated RSpec")
+
+    def call(self, slice_xrn, creds, rspec):
+        hrn, type = urn_to_hrn(slice_xrn)
+
+        self.api.logger.info("interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"%(self.api.interface, hrn, creds, self.name))
+
+        # Validate that at least one of the credentials is good enough
+        found = False
+        for cred in creds:
+            try:
+                self.api.auth.check(cred, 'createslice')
+                found = True
+                break
+            except:
+                continue
+            
+        if not found:
+            raise InsufficientRights('CreateSliver: Credentials either did not verify, were no longer valid, or did not have appropriate privileges')
+            
+        
+        manager_base = 'sfa.managers'
+
+        if self.api.interface in ['geni_am']:
+            mgr_type = self.api.config.SFA_GENI_AGGREGATE_TYPE
+            manager_module = manager_base + ".geni_am_%s" % mgr_type
+            manager = __import__(manager_module, fromlist=[manager_base])
+            return manager.CreateSlice(self.api, slice_xrn, creds, rspec)
+
+        return ''
+    
diff --git a/sfa/methods/ListResources.py b/sfa/methods/ListResources.py
new file mode 100644 (file)
index 0000000..11c10f7
--- /dev/null
@@ -0,0 +1,48 @@
+from sfa.util.faults import *
+from sfa.util.namespace import *
+from sfa.util.method import Method
+from sfa.util.parameter import Parameter, Mixed
+from sfa.trust.auth import Auth
+from sfa.trust.gid import GID
+from sfa.trust.certificate import Certificate
+
+class ListResources(Method):
+    """
+    Returns information about available resources or resources allocated to this    slice
+    @param credential list
+    @param options dictionary
+    @return string
+    """
+    interfaces = ['geni_am']
+    accepts = [
+        Parameter(type([str]), "List of credentials"),
+        Parameter(dict, "Options")
+        ]
+    returns = Parameter(str, "List of resources")
+
+    def call(self, creds, options):
+        self.api.logger.info("interface: %s\tmethod-name: %s" % (self.api.interface, self.name))
+
+        # Validate that at least one of the credentials is good enough
+        found = False
+        for cred in creds:
+            try:
+                self.api.auth.check(cred, 'ListResources')
+                found = True
+                break
+            except:
+                continue
+            
+        if not found:
+            raise InsufficientRights('ListResources: Credentials either did not verify, were no longer valid, or did not have appropriate privileges')
+        
+        manager_base = 'sfa.managers'
+
+        if self.api.interface in ['geni_am']:
+            mgr_type = self.api.config.SFA_GENI_AGGREGATE_TYPE
+            manager_module = manager_base + ".geni_am_%s" % mgr_type
+            manager = __import__(manager_module, fromlist=[manager_base])
+            return manager.ListResources(self.api, creds, options)
+
+        return ''
+    
index f788ead..14b9d1a 100644 (file)
@@ -38,11 +38,11 @@ class get_credential(Method):
         else:
             hrn, type = urn_to_hrn(xrn)
 
-       #log the call
-       if not origin_hrn:
+        #log the call
+        if not origin_hrn:
             origin_hrn = Credential(string=cred).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)) 
-
+        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))        
+        self.api.logger.info("get_credential cred = %s" % cred)
         self.api.auth.check(cred, 'getcredential')
         self.api.auth.verify_object_belongs_to_me(hrn)
 
index 6e93926..3904598 100644 (file)
@@ -45,7 +45,11 @@ class get_resources(Method):
         self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))
 
         # validate the cred    
+        self.api.logger.info("Checking for %s" % self.api.interface)
+        #self.api.logger.info("Credential = %s" % cred)
         self.api.auth.check(cred, 'listnodes')
+        self.api.logger.info("Checked out!")
+        
 
         # send the call to the right manager
         manager_base = 'sfa.managers'
index 7c62240..334734b 100644 (file)
@@ -10,22 +10,33 @@ from sfa.trust.credential import Credential
 class get_trusted_certs(Method):
     """
     @param cred credential string specifying the rights of the caller
-    @return 1 is successful, faults otherwise  
+    @return list of gid strings  
     """
 
-    interfaces = ['registry']
+    interfaces = ['registry', 'aggregate', 'slicemgr']
     
     accepts = [
-        Parameter(str, "Credential string")
+        Mixed(Parameter(str, "Credential string"),
+              Parameter(None, "Credential not specified"))
         ]
 
-    returns = Parameter(int, "1 if successful")
+    returns = Parameter([str], "List of GID strings")
     
-    def call(self, cred):
+    def call(self, cred = None):
+        # If cred is not specified just return the gid for this interface.
+        # This is true when when a peer is attempting to initiate federation
+        # with this interface 
+        print cred
+        if not cred:
+            gid_strings = []
+            for gid in self.api.auth.trusted_cert_list:
+                if gid.get_hrn() == self.api.config.SFA_INTERFACE_HRN:
+                    gid_strings.append(gid.save_to_string(save_parents=True))   
+            return gid_strings
+
         # authenticate the cred
         self.api.auth.check(cred, 'gettrustedcerts')
-
-        trusted_cert_strings = [gid.save_to_string(save_parents=True) for \
+        gid_strings = [gid.save_to_string(save_parents=True) for \
                                 gid in self.api.auth.trusted_cert_list] 
         
-        return trusted_cert_strings 
+        return gid_strings 
index 3f6e729..44c38a9 100644 (file)
@@ -23,6 +23,10 @@ from sfa.util.nodemanager import NodeManager
 from sfa.util.sfalogging import *
 
 def list_to_dict(recs, key):
+    """
+    convert a list of dictionaries into a dictionary keyed on the 
+    specified dictionary key 
+    """
     keys = [rec[key] for rec in recs]
     return dict(zip(keys, recs))
 
@@ -59,7 +63,7 @@ class SfaAPI(BaseAPI):
         rspec_type = self.config.get_aggregate_type()
         if (rspec_type == 'pl' or rspec_type == 'vini'):
             self.plshell = self.getPLCShell()
-            self.plshell_version = self.getPLCShellVersion()
+            self.plshell_version = "4.3"
 
         self.hrn = self.config.SFA_INTERFACE_HRN
         self.time_format = "%Y-%m-%d %H:%M:%S"
@@ -70,35 +74,12 @@ class SfaAPI(BaseAPI):
                        'AuthMethod': 'password',
                        'AuthString': self.config.SFA_PLC_PASSWORD}
 
-        try:
-            sys.path.append(os.path.dirname(os.path.realpath("/usr/bin/plcsh")))
-            self.plshell_type = 'direct'
-            import PLC.Shell
-            shell = PLC.Shell.Shell(globals = globals())
-            shell.AuthCheck(self.plauth)
-            return shell
-        except ImportError:
-            self.plshell_type = 'xmlrpc' 
-            # connect via xmlrpc
-            url = self.config.SFA_PLC_URL
-            shell = xmlrpclib.Server(url, verbose = 0, allow_none = True)
-            shell.AuthCheck(self.plauth)
-            return shell
-
-    def getPLCShellVersion(self):
-        # We need to figure out what version of PLCAPI we are talking to.
-        # Some calls we need to make later will be different depending on
-        # the api version. 
-        try:
-            # This is probably a bad way to determine api versions
-            # but its easy and will work for now. Lets try to make 
-            # a call that only exists is PLCAPI.4.3. If it fails, we
-            # can assume the api version is 4.2
-            self.plshell.GetTagTypes(self.plauth)
-            return '4.3'
-        except:
-            return '4.2'
-            
+
+        self.plshell_type = 'xmlrpc' 
+        # connect via xmlrpc
+        url = self.config.SFA_PLC_URL
+        shell = xmlrpclib.Server(url, verbose = 0, allow_none = True)
+        return shell
 
     def getCredential(self):
         if self.interface in ['registry']:
@@ -286,7 +267,7 @@ class SfaAPI(BaseAPI):
 
         # fill record info
         for record in records:
-            # records with pointer==-1 do not have plc info associated with them.
+            # records with pointer==-1 do not have plc info.
             # for example, the top level authority records which are
             # authorities, but not PL "sites"
             if record['pointer'] == -1:
@@ -382,24 +363,46 @@ class SfaAPI(BaseAPI):
 
     def fill_record_sfa_info(self, records):
         # get person ids
-        has_authority = False
-        has_slice = False
         person_ids = []
+        site_ids = []
         for record in records:
-            if record['type'] == 'authority':
-                has_authority = True
             person_ids.extend(record.get("person_ids", []))
+            site_ids.extend(record.get("site_ids", [])) 
+            if 'site_id' in record:
+                site_ids.append(record['site_id']) 
+        
+        # get all pis from the sites we've encountered
+        # and store them in a dictionary keyed on site_id 
+        site_pis = {}
+        if site_ids:
+            pi_filter = {'|roles': ['pi'], '|site_ids': site_ids} 
+            pi_list = self.plshell.GetPersons(self.plauth, pi_filter, ['person_id', 'site_ids'])
+            for pi in pi_list:
+                # we will need the pi's hrns also
+                person_ids.append(pi['person_id'])
+                
+                # we also need to keep track of the sites these pis
+                # belong to
+                for site_id in pi['site_ids']:
+                    if site_id in site_pis:
+                        site_pis[site_id].append(pi)
+                    else:
+                        site_pis[site_id] = [pi]
+                 
+        # get sfa records for all records associated with these records.   
+        # we'll replace pl ids (person_ids) with hrns from the sfa records
+        # we obtain
         
-        # get sfa info
+        # get the sfa records
         table = self.SfaTable()
         person_list, persons = [], {}
-        pl_person_list, pl_persons = [], {}
         person_list = table.find({'type': 'user', 'pointer': person_ids})
         persons = list_to_dict(person_list, 'pointer')
-        if has_authority:
-            pl_person_list = self.plshell.GetPersons(self.plauth, person_ids, ['person_id', 'roles'])
-            pl_persons = list_to_dict(pl_person_list, 'person_id')
-            
+
+        # get the pl records
+        pl_person_list, pl_persons = [], {}
+        pl_person_list = self.plshell.GetPersons(self.plauth, person_ids, ['person_id', 'roles'])
+        pl_persons = list_to_dict(pl_person_list, 'person_id')
 
         # fill sfa info
         for record in records:
@@ -409,10 +412,15 @@ class SfaAPI(BaseAPI):
             sfa_info = {}
             type = record['type']
             if (type == "slice"):
+                # slice users
                 researchers = [persons[person_id]['hrn'] for person_id in record['person_ids'] \
                                if person_id in persons] 
                 sfa_info['researcher'] = researchers
-         
+                # pis at the slice's site
+                pl_pis = site_pis[record['site_id']]
+                pi_ids = [pi['person_id'] for pi in pl_pis] 
+                sfa_info['PI'] = [persons[person_id]['hrn'] for person_id in pi_ids]
+                
             elif (type == "authority"):
                 pis, techs, admins = [], [], []
                 for pointer in record['person_ids']:
@@ -427,7 +435,6 @@ class SfaAPI(BaseAPI):
                         techs.append(hrn)
                     if 'admin' in roles:
                         admins.append(hrn)
-            
                     sfa_info['PI'] = pis
                     sfa_info['operator'] = techs
                     sfa_info['owner'] = admins
index 9c5cf62..190ee63 100644 (file)
@@ -16,7 +16,6 @@ from sfa.util.debug import log
 from sfa.util.rspec import *
 from sfa.util.specdict import * 
 from sfa.util.policy import Policy
-from sfa.server.aggregate import Aggregates 
 
 class Nodes(SimpleStorage):
 
@@ -107,7 +106,7 @@ class Nodes(SimpleStorage):
         end_time = int(threshold.strftime("%s"))
         duration = end_time - start_time
 
-        aggregates = Aggregates(self.api)
+        aggregates = self.api.aggregates
         rspecs = {}
         networks = []
         rspec = RSpec()
index d8c48b7..9730e97 100644 (file)
@@ -16,8 +16,6 @@ from sfa.util.record import SfaRecord
 from sfa.util.policy import Policy
 from sfa.util.prefixTree import prefixTree
 from sfa.util.debug import log
-from sfa.server.aggregate import Aggregates
-from sfa.server.registry import Registries
 
 MAXINT =  2L**31-1
 
@@ -212,30 +210,17 @@ class Slices(SimpleStorage):
 
     def refresh_slices_smgr(self):
         slice_hrns = []
-        aggregates = Aggregates(self.api)
         credential = self.api.getCredential()
-        for aggregate in aggregates:
+        for aggregate in self.api.aggregates:
             success = False
-            # request hash is optional so lets try the call without it 
             try:
-                slices = aggregates[aggregate].get_slices(credential)
+                slices = self.api.aggregates[aggregate].get_slices(credential)
                 slice_hrns.extend(slices)
                 success = True
             except:
                 print >> log, "%s" % (traceback.format_exc())
                 print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
 
-            # try sending the request hash if the previous call failed 
-            if not success:
-                arg_list = [credential]
-                try:
-                    slices = aggregates[aggregate].get_slices(credential)
-                    slice_hrns.extend(slices)
-                    success = True
-                except:
-                    print >> log, "%s" % (traceback.format_exc())
-                    print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
-
         # update timestamp and threshold
         timestamp = datetime.datetime.now()
         hr_timestamp = timestamp.strftime(self.api.time_format)
@@ -420,8 +405,7 @@ class Slices(SimpleStorage):
         slicename = hrn_to_pl_slicename(hrn) 
         slice = {}
         slice_record = None
-        registries = Registries(self.api)
-        registry = registries[self.api.hrn]
+        registry = self.api.registries[self.api.hrn]
         credential = self.api.getCredential()
 
         site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
index 9295e3f..aecc3b6 100644 (file)
@@ -1,25 +1,13 @@
 ### $Id$
 ### $URL$
 
-import os
-import sys
-import datetime
-import time
-import xmlrpclib
-from types import StringTypes, ListType
 
 from sfa.util.server import SfaServer
-from sfa.util.storage import *
 from sfa.util.faults import *
+from sfa.server.interface import Interfaces
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 import sfa.util.soapprotocol as soapprotocol
 
-# GeniLight client support is optional
-try:
-    from egeni.geniLight_client import *
-except ImportError:
-    GeniClientLight = None
-
 
 class Aggregate(SfaServer):
 
@@ -37,71 +25,19 @@ class Aggregate(SfaServer):
 ##
 # Aggregates is a dictionary of aggregate connections keyed on the aggregate hrn
 
-class Aggregates(dict):
-
-    required_fields = ['hrn', 'addr', 'port']
-     
-    def __init__(self, api, file = "/etc/sfa/aggregates.xml"):
-        dict.__init__(self, {})
-        self.api = api
-        self.interfaces = []
-        # create default connection dict
-        connection_dict = {}
-        for field in self.required_fields:
-            connection_dict[field] = ''
-        aggregates_dict = {'aggregates': {'aggregate': [connection_dict]}}
-        # get possible config file locations
-        loaded = False
-        path = os.path.dirname(os.path.abspath(__file__))
-        filename = file.split(os.sep)[-1]
-        alt_file = path + os.sep + filename
-        files = [file, alt_file]
-        
-        for f in files:
-            try:
-                if os.path.isfile(f):
-                    self.aggregate_info = XmlStorage(f, aggregates_dict)
-                    loaded = True
-            except: pass
+class Aggregates(Interfaces):
 
-        # if file is missing, just recreate it in the right place
-        if not loaded:
-            self.aggregate_info = XmlStorage(file, aggregates_dict)
-        self.aggregate_info.load()
-        self.connectAggregates()
+    default_dict = {'aggregates': {'aggregate': [Interfaces.default_fields]}}
+    def __init__(self, api, conf_file = "/etc/sfa/aggregates.xml"):
+        Interfaces.__init__(self, api, conf_file, 'ma')
 
-    def connectAggregates(self):
+    def get_connections(self, interfaces):
         """
         Get connection details for the trusted peer aggregates from file and 
         create an connection to each. 
         """
-        aggregates = self.aggregate_info['aggregates']['aggregate']
-        if isinstance(aggregates, dict):
-            aggregates = [aggregates]
-        if isinstance(aggregates, list):
-            for aggregate in aggregates:
-                # make sure the required fields are present
-                if not set(self.required_fields).issubset(aggregate.keys()):
-                    continue
-                hrn, address, port = aggregate['hrn'], aggregate['addr'], aggregate['port']
-                if not hrn or not address or not port:
-                    continue
-                self.interfaces.append(aggregate)
-                # check which client we should use
-                # sfa.util.xmlrpcprotocol is default
-                client_type = 'xmlrpcprotocol'
-                if aggregate.has_key('client') and aggregate['client'] in ['geniclientlight']:
-                    client_type = 'geniclientlight'
-                
-                # create url
-                url = 'http://%(address)s:%(port)s' % locals()
-
-                # create the client connection
-                # make sure module exists before trying to instantiate it
-                if client_type in ['geniclientlight'] and GeniClientLight:
-                    self[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file)
-                else:
-                    self[hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
+        connections = Interfaces.get_connections(self, interfaces)
 
         # set up a connection to the local registry
         address = self.api.config.SFA_AGGREGATE_HOST
@@ -109,6 +45,6 @@ class Aggregates(dict):
         url = 'http://%(address)s:%(port)s' % locals()
         local_aggregate = {'hrn': self.api.hrn, 'addr': address, 'port': port}
         self.interfaces.append(local_aggregate) 
-        self[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
-
+        connections[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
+        return connections
 
diff --git a/sfa/server/interface.py b/sfa/server/interface.py
new file mode 100644 (file)
index 0000000..17f37c5
--- /dev/null
@@ -0,0 +1,186 @@
+#
+### $Id: interface.py 17583 2010-04-06 15:01:08Z tmack $
+### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/server/interface.py $
+#
+
+
+from sfa.util.faults import *
+from sfa.util.storage import *
+from sfa.util.namespace import *
+from sfa.trust.gid import GID
+from sfa.util.table import SfaTable
+from sfa.util.record import SfaRecord
+import sfa.util.xmlrpcprotocol as xmlrpcprotocol
+import sfa.util.soapprotocol as soapprotocol
+
+# GeniLight client support is optional
+try:
+    from egeni.geniLight_client import *
+except ImportError:
+    GeniClientLight = None            
+
+
+##
+# In is a dictionary of registry connections keyed on the registry
+# hrn
+
+class Interfaces(dict):
+    """
+    Interfaces is a base class for managing information on the
+    peers we are federated with. It is responsible for the following:
+
+    1) Makes sure a record exist in the local registry for the each 
+       fedeated peer   
+    2) Attepts to fetch and install trusted gids   
+    3) Provides connections (xmlrpc or soap) to federated peers
+    """
+
+    # fields that must be specified in the config file
+    default_fields = {
+        'hrn': '',
+        'addr': '', 
+        'port': '', 
+    }
+
+    # defined by the class 
+    default_dict = {}
+
+    # allowed types
+    types = ['sa', 'ma']
+
+    def __init__(self, api, conf_file, type):
+        if type not in self.types:
+            raise SfaInfaildArgument('Invalid type %s: must be in %s' % (type, self.types))    
+        dict.__init__(self, {})
+        self.api = api
+        self.type = type  
+        # load config file
+        self.interface_info = XmlStorage(conf_file, self.default_dict)
+        self.interface_info.load()
+        self.interfaces = self.interface_info.values()[0].values()[0]
+        if not isinstance(self.interfaces, list):
+            self.interfaces = [self.interfaces]
+        # get connections
+        self.update(self.get_connections(self.interfaces))
+
+    def sync_interfaces(self):
+        """
+        Install missing trusted gids and db records for our federated
+        interfaces
+        """     
+        # Attempt to get any missing peer gids
+        # There should be a gid file in /etc/sfa/trusted_roots for every
+        # peer registry found in in the registries.xml config file. If there
+        # are any missing gids, request a new one from the peer registry.
+        gids_current = self.api.auth.trusted_cert_list
+        hrns_current = [gid.get_hrn() for gid in gids_current] 
+        hrns_expected = [interface['hrn'] for interface in self.interfaces] 
+        new_hrns = set(hrns_expected).difference(hrns_current)
+        self.get_peer_gids(new_hrns)
+
+        # update the local db records for these registries
+        self.update_db_records(self.type)
+        
+    def get_peer_gids(self, new_hrns):
+        """
+        Install trusted gids from the specified interfaces.  
+        """
+        if not new_hrns:
+            return
+        trusted_certs_dir = self.api.config.get_trustedroots_dir()
+        for new_hrn in new_hrns:
+            # the gid for this interface should already be installed  
+            if new_hrn == self.api.config.SFA_INTERFACE_HRN:
+                continue
+            try:
+                # get gid from the registry
+                interface = self.get_connections(self.interfaces[new_hrn])[new_hrn]
+                trusted_gids = interface.get_trusted_certs()
+                # default message
+                message = "interface: %s\tunable to install trusted gid for %s" % \
+                           (self.api.interface, new_hrn) 
+                if trusted_gids:
+                    # the gid we want shoudl be the first one in the list, 
+                    # but lets make sure
+                    for trusted_gid in trusted_gids:
+                        gid = GID(string=trusted_gids[0])
+                        if gid.get_hrn() == new_hrn:
+                            gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn)
+                            gid.save_to_file(gid_filename, save_parents=True)
+                            message = "interface: %s\tinstalled trusted gid for %s" % \
+                                (self.api.interface, new_hrn)
+                # log the message
+                self.api.logger.info(message)
+            except:
+                message = "interface: %s\tunable to install trusted gid for %s" % \
+                            (self.api.interface, new_hrn) 
+                self.api.logger.info(message)
+        
+        # reload the trusted certs list
+        self.api.auth.load_trusted_certs()
+
+    def update_db_records(self, type):
+        """
+        Make sure there is a record in the local db for allowed registries
+        defined in the config file (registries.xml). Removes old records from
+        the db.         
+        """
+        # get hrns we expect to find
+        # ignore records for local interfaces
+        ignore_interfaces = [self.api.config.SFA_INTERFACE_HRN]
+        hrns_expected = [interface['hrn'] for interface in self.interfaces \
+                         if interface['hrn'] not in ignore_interfaces]
+
+        # get hrns that actually exist in the db
+        table = SfaTable()
+        records = table.find({'type': type})
+        hrns_found = [record['hrn'] for record in records]
+       
+        # remove old records
+        for record in records:
+            if record['hrn'] not in hrns_expected:
+                table.remove(record)
+
+        # add new records
+        for hrn in hrns_expected:
+            if hrn not in hrns_found:
+                record = {
+                    'hrn': hrn,
+                    'type': type,
+                    'pointer': -1, 
+                    'authority': get_authority(hrn),
+                }
+                record = SfaRecord(dict=record)
+                table.insert(record)
+                        
+    def get_connections(self, interfaces):
+        """
+        read connection details for the trusted peer registries from file return 
+        a dictionary of connections keyed on interface hrn. 
+        """
+        connections = {}
+        required_fields = self.default_fields.keys()
+        if not isinstance(interfaces, list):
+            interfaces = [interfaces]
+        for interface in interfaces:
+            # make sure the required fields are present and not null
+            if not all([interface.get(key) for key in required_fields]):
+                continue
+
+            hrn, address, port = interface['hrn'], interface['addr'], interface['port']
+            url = 'http://%(address)s:%(port)s' % locals()
+
+            # check which client we should use
+            # sfa.util.xmlrpcprotocol is default
+            client_type = 'xmlrpcprotocol'
+            if interface.has_key('client') and \
+               interface['client'] in ['geniclientlight'] and \
+               GeniClientLight:
+                client_type = 'geniclientlight'
+                connections[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file) 
+            else:
+                connections[hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
+
+        return connections 
index 1902a64..5658f37 100644 (file)
@@ -5,26 +5,15 @@
 ### $URL$
 #
 
-import tempfile
-import os
-import time
-import sys
-
 from sfa.util.server import SfaServer
 from sfa.util.faults import *
-from sfa.util.storage import *
+from sfa.server.interface import Interfaces
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 import sfa.util.soapprotocol as soapprotocol
  
-# GeniLight client support is optional
-try:
-    from egeni.geniLight_client import *
-except ImportError:
-    GeniClientLight = None            
 
 ##
 # Registry is a SfaServer that serves registry and slice operations at PLC.
-
 class Registry(SfaServer):
     ##
     # Create a new registry object.
@@ -33,7 +22,7 @@ class Registry(SfaServer):
     # @param port the port to listen on
     # @param key_file private key filename of registry
     # @param cert_file certificate filename containing public key (could be a GID file)
-
+    
     def __init__(self, ip, port, key_file, cert_file):
         SfaServer.__init__(self, ip, port, key_file, cert_file)
         self.server.interface = 'registry' 
@@ -43,79 +32,24 @@ class Registry(SfaServer):
 # Registries is a dictionary of registry connections keyed on the registry
 # hrn
 
-class Registries(dict):
-
-    required_fields = ['hrn', 'addr', 'port']
-
-    def __init__(self, api, file = "/etc/sfa/registries.xml"):
-        dict.__init__(self, {})
-        self.api = api
-        self.interfaces = []
-       
-        # create default connection dict
-        connection_dict = {}
-        for field in self.required_fields:
-            connection_dict[field] = ''
-        registries_dict = {'registries': {'registry': [connection_dict]}}
-
-        # get possible config file locations
-        loaded = False
-        path = os.path.dirname(os.path.abspath(__file__))
-        filename = file.split(os.sep)[-1]
-        alt_file = path + os.sep + filename
-        files = [file, alt_file]
+class Registries(Interfaces):
     
-        for f in files:
-            try:
-                if os.path.isfile(f):
-                    self.registry_info = XmlStorage(f, registries_dict)
-                    loaded = True
-            except: pass
+    default_dict = {'registries': {'registry': [Interfaces.default_fields]}}
+
+    def __init__(self, api, conf_file = "/etc/sfa/registries.xml"):
+        Interfaces.__init__(self, api, conf_file, 'sa') 
 
-        # if file is missing, just recreate it in the right place
-        if not loaded:
-            self.registry_info = XmlStorage(file, registries_dict)
-        self.registry_info.load()
-        self.connectRegistries()
-        
-    def connectRegistries(self):
+    def get_connections(self, interfaces):
         """
-        Get connection details for the trusted peer registries from file and 
-        create a connection to each
+        read connection details for the trusted peer registries from file return 
+        a dictionary of connections keyed on interface hrn
         """
-        registries = self.registry_info['registries']['registry']
-        if isinstance(registries, dict):
-            registries = [registries]
-        if isinstance(registries, list):
-            for registry in registries:
-                # make sure the required fields are present
-                if not set(self.required_fields).issubset(registry.keys()):
-                    continue
-                hrn, address, port = registry['hrn'], registry['addr'], registry['port']
-                if not hrn or not address or not port:
-                    continue
-                self.interfaces.append(registry)
-                # check which client we should use
-                # sfa.util.xmlrpcprotocol is default
-                client_type = 'xmlrpcprotocol'
-                if registry.has_key('client') and registry['client'] in ['geniclientlight']:
-                    client_type = 'geniclientlight'
-                
-                # create url
-                url = 'http://%(address)s:%(port)s' % locals()
-
-                # create the client connection
-                # make sure module exists before trying to instantiate it
-                if client_type in ['geniclientlight'] and GeniClientLight:
-                    self[hrn] = GeniClientLight(url, self.api.key_file, self.api.cert_file) 
-                else:    
-                    self[hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
+        connections = Interfaces.get_connections(self, interfaces)
 
         # set up a connection to the local registry
         address = self.api.config.SFA_REGISTRY_HOST
         port = self.api.config.SFA_REGISTRY_PORT
         url = 'http://%(address)s:%(port)s' % locals()
         local_registry = {'hrn': self.api.hrn, 'addr': address, 'port': port}
-        self.interfaces.append(local_registry)
-        self[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)            
-    
+        connections[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)            
+        return connections 
index 35d00be..db78d5c 100755 (executable)
@@ -43,6 +43,9 @@ from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.hierarchy import Hierarchy
 from sfa.util.config import Config
 from sfa.util.report import trace
+from sfa.plc.api import SfaAPI
+from sfa.server.registry import Registries
+from sfa.server.aggregate import Aggregates
 
 # after http://www.erlenstar.demon.co.uk/unix/faq_2.html
 def daemon():
@@ -154,6 +157,17 @@ def init_server(options, config):
             manager.init_server()
             
 
+def sync_interfaces():
+    """
+    Attempt to install missing trusted gids and db records for 
+    our federated interfaces
+    """
+    api = SfaAPI()
+    registries = Registries(api)
+    aggregates = Aggregates(api)
+    registries.sync_interfaces()
+    aggregates.sync_interfaces()
+
 def main():
     # xxx get rid of globals - name consistently CamelCase or under_score
     global AuthHierarchy
@@ -184,12 +198,12 @@ def main():
 
     config = Config()
     hierarchy = Hierarchy()
-    trusted_roots = TrustedRootList(config.get_trustedroots_dir())
     server_key_file = os.path.join(hierarchy.basedir, "server.key")
     server_cert_file = os.path.join(hierarchy.basedir, "server.cert")
 
     init_server_key(server_key_file, server_cert_file, config, hierarchy)
-    init_server(options, config)   
+    init_server(options, config)
+    sync_interfaces()   
  
     # start registry server
     if (options.registry):
index 227f992..7cea637 100755 (executable)
@@ -6,11 +6,26 @@ from optparse import OptionParser
 from sfa.util.config import Config
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 from sfa.util.namespace import *
+from sfa.util.faults import *
 from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.credential import Credential
 from sfa.trust.gid import GID
 from sfa.trust.hierarchy import Hierarchy
 
+KEYDIR = "/var/lib/sfa/"
+CONFDIR = "/etc/sfa/"
+
+def handle_gid_mismatch_exception(f):
+    def wrapper(*args, **kwds):
+        try: return f(*args, **kwds)
+        except ConnectionKeyGIDMismatch:
+            # clean regen server keypair and try again
+            print "cleaning keys and trying again"
+            clean_key_cred()
+            return f(args, kwds)
+
+    return wrapper
+
 def get_server(url=None, port=None, keyfile=None, certfile=None,verbose=False):
     """
     returns an xmlrpc connection to the service a the specified 
@@ -45,6 +60,26 @@ def create_default_dirs():
     for dir in all_dirs:
         if not os.path.exists(dir):
             os.makedirs(dir)
+
+def has_node_key():
+    key_file = KEYDIR + os.sep + 'server.key'
+    return os.path.exists(key_file) 
+
+def clean_key_cred():
+    """
+    remove the existing keypair and cred  and generate new ones
+    """
+    files = ["server.key", "server.cert", "node.cred"]
+    for f in files:
+        filepath = KEYDIR + os.sep + f
+        if os.path.isfile(filepath):
+            os.unlink(f)
+   
+    # install the new key pair
+    # get_credential will take care of generating the new keypair
+    # and credential 
+    get_credential()
+    
              
 def get_node_key(registry=None, verbose=False):
     # this call requires no authentication, 
@@ -74,7 +109,8 @@ def create_server_keypair(keyfile=None, certfile=None, hrn="component", verbose=
     cert.set_pubkey(key)
     cert.sign()
     cert.save_to_file(certfile, save_parents=True)       
-        
+
+@handle_gid_mismatch_exception
 def get_credential(registry=None, force=False, verbose=False):
     config = Config()
     hierarchy = Hierarchy()
@@ -115,6 +151,7 @@ def get_credential(registry=None, force=False, verbose=False):
     
     return cred
 
+@handle_gid_mismatch_exception
 def get_trusted_certs(registry=None, verbose=False):
     """
     refresh our list of trusted certs.
@@ -157,6 +194,7 @@ def get_trusted_certs(registry=None, verbose=False):
                 print "Removing old gid ", gid_name
             os.unlink(trusted_certs_dir + os.sep + gid_name)                     
 
+@handle_gid_mismatch_exception
 def get_gids(registry=None, verbose=False):
     """
     Get the gid for all instantiated slices on this node and store it
@@ -186,10 +224,24 @@ def get_gids(registry=None, verbose=False):
     api = ComponentAPI()
     xids_tuple = api.nodemanager.GetXIDs()
     slices = eval(xids_tuple[1])
-    slicenames = slices.keys()   
-    hrns = [slicename_to_hrn(interface_hrn, slicename) for slicename in slicenames]
-        
+    slicenames = slices.keys()
 
+    # generate a list of slices that dont have gids installed
+    slices_without_gids = []
+    for slicename in slicenames:
+        if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
+        or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
+            slices_without_gids.append(slicename) 
+    
+    # convert slicenames to hrns
+    hrns = [slicename_to_hrn(interface_hrn, slicename) \
+            for slicename in slices_without_gids]
+    
+    # exit if there are no gids to install
+    print hrns
+    if not hrns:
+        return
+        
     if verbose:
         print "Getting gids for slices on this node from registry"  
     # get the gids
index 15d3b58..06f490d 100644 (file)
@@ -27,10 +27,12 @@ class Auth:
         self.hierarchy = Hierarchy()
         if not config:
             self.config = Config()
-        self.trusted_cert_list = TrustedRootList(self.config.get_trustedroots_dir()).get_list()
+        self.load_trusted_certs()
         self.trusted_cert_file_list = TrustedRootList(self.config.get_trustedroots_dir()).get_file_list()
 
-
+    def load_trusted_certs(self):
+        self.trusted_cert_list = TrustedRootList(self.config.get_trustedroots_dir()).get_list()
+        
     def check(self, cred, operation):
         """
         Check the credential against the peer cert (callerGID included 
@@ -225,11 +227,15 @@ class Auth:
             pis = record.get("PI", [])
             operators = record.get("operator", [])
             if (caller_hrn == self.config.SFA_INTERFACE_HRN):
-                rl.add("authority,sa,ma",)
+                rl.add("authority")
+                rl.add("sa")
+                rl.add("ma")
             if (caller_hrn in pis):
-                rl.add("authority,sa")
+                rl.add("authority")
+                rl.add("sa")
             if (caller_hrn in operators):
-                rl.add("authority,ma")
+                rl.add("authority")
+                rl.add("ma")
 
         elif type == "user":
             rl.add("refresh")
index 4ecabb9..e3d110f 100644 (file)
@@ -30,6 +30,7 @@ privilege_table = {"authority": ["register", "remove", "update", "resolve", "lis
                    "operator": ["gettrustedcerts", "getgids"]}
 
 
+
 ##
 # Determine tje rights that an object should have. The rights are entirely
 # dependent on the type of the object. For example, users automatically
@@ -52,11 +53,15 @@ def determine_rights(type, name):
         rl.add("resolve")
         rl.add("info")
     elif type == "sa":
-        rl.add("authority,sa")
+        rl.add("authority")
+        rl.add("sa")
     elif type == "ma":
-        rl.add("authority,ma")
+        rl.add("authority")
+        rl.add("ma")
     elif type == "authority":
-        rl.add("authority,sa,ma")
+        rl.add("authority")
+        rl.add("sa")
+        rl.add("ma")
     elif type == "slice":
         rl.add("refresh")
         rl.add("embed")
index ad129de..635cc43 100644 (file)
@@ -115,6 +115,7 @@ class BaseAPI:
         # Load configuration
         self.config = Config(config)
         self.auth = Auth(peer_cert)
+        self.hrn = self.config.SFA_INTERFACE_HRN
         self.interface = interface
         self.key_file = key_file
         self.key = Keypair(filename=self.key_file)
@@ -124,6 +125,14 @@ class BaseAPI:
         self.source = None 
         self.time_format = "%Y-%m-%d %H:%M:%S"
         self.logger=get_sfa_logger()
+        
+        # load registries
+        from sfa.server.registry import Registries
+        self.registries = Registries(self) 
+
+        # load aggregates
+        from sfa.server.aggregate import Aggregates
+        self.aggregates = Aggregates(self)
 
 
     def callable(self, method):
index aad12ca..f9eaa09 100644 (file)
@@ -366,6 +366,7 @@ class SliceRecord(SfaRecord):
         'url': Parameter(str, 'Slice url'),
         'expires': Parameter(int, 'Date and time this slice exipres'),
         'researcher': Parameter([str], 'List of users for this slice'),
+        'PI': Parameter([str], 'List of PIs responsible for this slice'),
         'description': Parameter([str], 'Description of this slice'), 
         }
     fields.update(SfaRecord.fields)
index 197297d..38bbfca 100644 (file)
@@ -101,12 +101,6 @@ class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
                               cert_file = self.server.cert_file)
             # get arguments
             request = self.rfile.read(int(self.headers["content-length"]))
-            # In previous versions of SimpleXMLRPCServer, _dispatch
-            # could be overridden in this class, instead of in
-            # SimpleXMLRPCDispatcher. To maintain backwards compatibility,
-            # check to see if a subclass implements _dispatch and dispatch
-            # using that method if present.
-            #response = self.server._marshaled_dispatch(request, getattr(self, '_dispatch', None))
             remote_addr = (remote_ip, remote_port) = self.connection.getpeername()
             self.api.remote_addr = remote_addr
             response = self.api.handle(remote_addr, request)
index d376f63..40386ee 100644 (file)
@@ -179,9 +179,8 @@ class SfaTable(list):
 
     def drop(self):
         try:
-            self.db.do('DROP TABLE IF EXISTS ' + self.tablename)            
+            self.db.do('DROP TABLE IF EXISTS ' + self.tablename)
         except:
-
             try:
                 self.db.do('DROP TABLE ' + self.tablename)
             except: