really fixed the redundant logging issue this time.
[sfa.git] / sfa / plc / api.py
index d578698..200d05c 100644 (file)
@@ -6,18 +6,20 @@ import sys
 import os
 import traceback
 import string
+import datetime
 import xmlrpclib
 
 from sfa.util.faults import *
 from sfa.util.api import *
 from sfa.util.config import *
-from sfa.util.sfalogging import sfa_logger
+from sfa.util.sfalogging import logger
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 from sfa.trust.auth import Auth
-from sfa.trust.rights import Right, Rights
+from sfa.trust.rights import Right, Rights, determine_rights
 from sfa.trust.credential import Credential,Keypair
 from sfa.trust.certificate import Certificate
-from sfa.util.namespace import get_authority, hrn_to_pl_slicename, hrn_to_pl_slicename, hrn_to_urn, slicename_to_hrn, hostname_to_hrn
+from sfa.util.xrn import get_authority, hrn_to_urn
+from sfa.util.plxrn import hostname_to_hrn, hrn_to_pl_slicename, hrn_to_pl_slicename, slicename_to_hrn
 from sfa.util.nodemanager import NodeManager
 try:
     from collections import defaultdict
@@ -97,13 +99,13 @@ class SfaAPI(BaseAPI):
         self.credential = None
         # Initialize the PLC shell only if SFA wraps a myPLC
         rspec_type = self.config.get_aggregate_type()
-        if (rspec_type == 'pl' or rspec_type == 'vini' or rspec_type == 'eucalyptus'):
+        if (rspec_type == 'pl' or rspec_type == 'vini' or \
+            rspec_type == 'eucalyptus' or rspec_type == 'max'):
             self.plshell = self.getPLCShell()
             self.plshell_version = "4.3"
 
         self.hrn = self.config.SFA_INTERFACE_HRN
         self.time_format = "%Y-%m-%d %H:%M:%S"
-        self.logger=sfa_logger()
 
     def getPLCShell(self):
         self.plauth = {'Username': self.config.SFA_PLC_USER,
@@ -125,10 +127,27 @@ class SfaAPI(BaseAPI):
         """
         Return a valid credential for this interface. 
         """
+        type = 'authority'
+        path = self.config.SFA_DATA_DIR
+        filename = ".".join([self.interface, self.hrn, type, "cred"])
+        cred_filename = path + os.sep + filename
+        cred = None
+        if os.path.isfile(cred_filename):
+            cred = Credential(filename = cred_filename)
+            # make sure cred isnt expired
+            if not cred.get_expiration or \
+               datetime.datetime.today() < cred.get_expiration():    
+                return cred.save_to_string(save_parents=True)
+
+        # get a new credential
         if self.interface in ['registry']:
-            return self.getCredentialFromLocalRegistry()
+            cred =  self.__getCredentialRaw()
         else:
-            return self.getCredentialFromRegistry()
+            cred =  self.__getCredential()
+        cred.save_to_file(cred_filename, save_parents=True)
+
+        return cred.save_to_string(save_parents=True)
+
 
     def getDelegatedCredential(self, creds):
         """
@@ -142,32 +161,21 @@ class SfaAPI(BaseAPI):
             return None
         return delegated_creds[0]
  
-    def getCredentialFromRegistry(self):
+    def __getCredential(self):
         """ 
         Get our credential from a remote registry 
         """
-        type = 'authority'
-        path = self.config.SFA_DATA_DIR
-        filename = ".".join([self.interface, self.hrn, type, "cred"])
-        cred_filename = path + os.sep + filename
-        try:
-            credential = Credential(filename = cred_filename)
-            return credential.save_to_string(save_parents=True)
-        except IOError:
-            from sfa.server.registry import Registries
-            registries = Registries(self)
-            registry = registries[self.hrn]
-            cert_string=self.cert.save_to_string(save_parents=True)
-            # get self credential
-            self_cred = registry.GetSelfCredential(cert_string, self.hrn, type)
-            # get credential
-            cred = registry.GetCredential(self_cred, self.hrn, type)
-            
-            # save cred to file
-            Credential(string=cred).save_to_file(cred_filename, save_parents=True)
-            return cred
-
-    def getCredentialFromLocalRegistry(self):
+        from sfa.server.registry import Registries
+        registries = Registries(self)
+        registry = registries[self.hrn]
+        cert_string=self.cert.save_to_string(save_parents=True)
+        # get self credential
+        self_cred = registry.GetSelfCredential(cert_string, self.hrn, 'authority')
+        # get credential
+        cred = registry.GetCredential(self_cred, self.hrn, 'authority')
+        return Credential(string=cred)
+
+    def __getCredentialRaw(self):
         """
         Get our current credential directly from the local registry.
         """
@@ -193,15 +201,10 @@ class SfaAPI(BaseAPI):
         
         r1 = determine_rights(type, hrn)
         new_cred.set_privileges(r1)
-
-        auth_kind = "authority,ma,sa"
-
-        new_cred.set_parent(self.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
-
         new_cred.encode()
         new_cred.sign()
 
-        return new_cred.save_to_string(save_parents=True)
+        return new_cred
    
 
     def loadCredential (self):
@@ -335,8 +338,11 @@ class SfaAPI(BaseAPI):
                         break
             # fill in key info
             if record['type'] == 'user':
-                pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys] 
-                record['keys'] = pubkeys
+                if 'key_ids' not in record:
+                    logger.info("user record has no 'key_ids' - need to import from myplc ?")
+                else:
+                    pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys] 
+                    record['keys'] = pubkeys
 
         # fill in record hrns
         records = self.fill_record_hrns(records)   
@@ -379,7 +385,6 @@ class SfaAPI(BaseAPI):
        
         # convert ids to hrns
         for record in records:
-             
             # get all relevant data
             type = record['type']
             pointer = record['pointer']
@@ -413,7 +418,7 @@ class SfaAPI(BaseAPI):
                                if site_id in sites]
                 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
                 record['sites'] = site_hrns
-
+            
         return records   
 
     def fill_record_sfa_info(self, records):
@@ -471,44 +476,50 @@ class SfaAPI(BaseAPI):
         # fill sfa info
         for record in records:
             # skip records with no pl info (top level authorities)
-            if record['pointer'] == -1:
-                continue 
+            #if record['pointer'] == -1:
+            #    continue 
             sfa_info = {}
             type = record['type']
             if (type == "slice"):
                 # all slice users are researchers
+                record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
                 record['PI'] = []
                 record['researcher'] = []
-                for person_id in record['person_ids']:
+                for person_id in record.get('person_ids', []):
                     hrns = [person['hrn'] for person in persons[person_id]]
                     record['researcher'].extend(hrns)                
 
                 # pis at the slice's site
-                pl_pis = site_pis[record['site_id']]
-                pi_ids = [pi['person_id'] for pi in pl_pis]
-                for person_id in pi_ids:
-                    hrns = [person['hrn'] for person in persons[person_id]]
-                    record['PI'].extend(hrns)
-                record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
-                record['geni_creator'] = record['PI'] 
-                
-            elif (type == "authority"):
-                record['PI'] = []
-                record['operator'] = []
-                record['owner'] = []
-                for pointer in record['person_ids']:
-                    if pointer not in persons or pointer not in pl_persons:
-                        # this means there is not sfa or pl record for this user
-                        continue   
-                    hrns = [person['hrn'] for person in persons[pointer]] 
-                    roles = pl_persons[pointer]['roles']   
-                    if 'pi' in roles:
+                if 'site_id' in record and record['site_id'] in site_pis:
+                    pl_pis = site_pis[record['site_id']]
+                    pi_ids = [pi['person_id'] for pi in pl_pis]
+                    for person_id in pi_ids:
+                        hrns = [person['hrn'] for person in persons[person_id]]
                         record['PI'].extend(hrns)
-                    if 'tech' in roles:
-                        record['operator'].extend(hrns)
-                    if 'admin' in roles:
-                        record['owner'].extend(hrns)
-                    # xxx TODO: OrganizationName
+                        record['geni_creator'] = record['PI'] 
+                
+            elif (type.startswith("authority")):
+                record['url'] = None
+                if record['hrn'] in self.aggregates:
+                    record['url'] = self.aggregates[record['hrn']].url
+
+                if record['pointer'] != -1:
+                    record['PI'] = []
+                    record['operator'] = []
+                    record['owner'] = []
+                    for pointer in record.get('person_ids', []):
+                        if pointer not in persons or pointer not in pl_persons:
+                            # this means there is not sfa or pl record for this user
+                            continue   
+                        hrns = [person['hrn'] for person in persons[pointer]] 
+                        roles = pl_persons[pointer]['roles']   
+                        if 'pi' in roles:
+                            record['PI'].extend(hrns)
+                        if 'tech' in roles:
+                            record['operator'].extend(hrns)
+                        if 'admin' in roles:
+                            record['owner'].extend(hrns)
+                        # xxx TODO: OrganizationName
             elif (type == "node"):
                 sfa_info['dns'] = record.get("hostname", "")
                 # xxx TODO: URI, LatLong, IP, DNS