more pep8-friendly
[sfa.git] / sfa / server / sfaapi.py
index 845ccff..231fdeb 100644 (file)
@@ -1,46 +1,52 @@
-import os, os.path
+# pylint: disable=c0111
+
+import os
+import os.path
 import datetime
 
 import datetime
 
-from sfa.util.faults import SfaAPIError
+from sfa.util.faults import SfaFault, RecordNotFound
+from sfa.util.genicode import GENICODE
 from sfa.util.config import Config
 from sfa.util.cache import Cache
 from sfa.util.config import Config
 from sfa.util.cache import Cache
+
 from sfa.trust.auth import Auth
 from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.credential import Credential
 from sfa.trust.rights import determine_rights
 from sfa.trust.auth import Auth
 from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.credential import Credential
 from sfa.trust.rights import determine_rights
+from sfa.util.version import version_core
 from sfa.server.xmlrpcapi import XmlrpcApi
 from sfa.server.xmlrpcapi import XmlrpcApi
-from sfa.util.genicode import GENICODE
+from sfa.client.return_value import ReturnValue
 
 
-# thgen xxx fixme this is wrong all right, but temporary, will use generic
-from sfa.util.table import SfaTable
+from sfa.storage.alchemy import alchemy
 
 ####################
 
 ####################
-class SfaApi (XmlrpcApi): 
-    
+
+
+class SfaApi(XmlrpcApi):
     """
     """
-    An SfaApi instance is a basic xmlrcp service
+    An SfaApi instance is a basic xmlrpc service
     augmented with the local cryptographic material and hrn
 
     It also has the notion of its own interface (a string describing
     augmented with the local cryptographic material and hrn
 
     It also has the notion of its own interface (a string describing
-    whether we run a registry, aggregate or slicemgr) and has 
-    the notion of neighbour sfa services as defined 
+    whether we run a registry, aggregate or slicemgr) and has
+    the notion of neighbour sfa services as defined
     in /etc/sfa/{aggregates,registries}.xml
 
     Finally it contains a cache instance
 
     in /etc/sfa/{aggregates,registries}.xml
 
     Finally it contains a cache instance
 
-    It gets augmented by the generic layer with 
+    It gets augmented by the generic layer with
     (*) an instance of manager (actually a manager module for now)
     (*) an instance of manager (actually a manager module for now)
-    (*) which in turn holds an instance of a testbed driver
-    For convenience api.manager.driver == api.driver
+        beware that this is shared among all instances of api
+    (*) an instance of a testbed driver
     """
 
     """
 
-    def __init__ (self, encoding="utf-8", methods='sfa.methods', 
-                  config = "/etc/sfa/sfa_config.py", 
-                  peer_cert = None, interface = None, 
-                  key_file = None, cert_file = None, cache = None):
-        
-        XmlrpcApi.__init__ (self, encoding)
-        
+    def __init__(self, encoding="utf-8", methods='sfa.methods',
+                 config="/etc/sfa/sfa_config",
+                 peer_cert=None, interface=None,
+                 key_file=None, cert_file=None, cache=None):
+
+        XmlrpcApi.__init__(self, encoding)
+
         # we may be just be documenting the API
         if config is None:
             return
         # we may be just be documenting the API
         if config is None:
             return
@@ -60,21 +66,22 @@ class SfaApi (XmlrpcApi):
 
         # load registries
         from sfa.server.registry import Registries
 
         # load registries
         from sfa.server.registry import Registries
-        self.registries = Registries() 
+        self.registries = Registries()
 
         # load aggregates
         from sfa.server.aggregate import Aggregates
         self.aggregates = Aggregates()
 
         # load aggregates
         from sfa.server.aggregate import Aggregates
         self.aggregates = Aggregates()
-        
+
         # filled later on by generic/Generic
         # filled later on by generic/Generic
-        self.manager=None
+        self.manager = None
+        self._dbsession = None
 
     def server_proxy(self, interface, cred, timeout=30):
         """
         Returns a connection to the specified interface. Use the specified
 
     def server_proxy(self, interface, cred, timeout=30):
         """
         Returns a connection to the specified interface. Use the specified
-        credential to determine the caller and look for the caller's key/cert 
-        in the registry hierarchy cache. 
-        """       
+        credential to determine the caller and look for the caller's key/cert
+        in the registry hierarchy cache.
+        """
         from sfa.trust.hierarchy import Hierarchy
         if not isinstance(cred, Credential):
             cred_obj = Credential(string=cred)
         from sfa.trust.hierarchy import Hierarchy
         if not isinstance(cred, Credential):
             cred_obj = Credential(string=cred)
@@ -87,99 +94,111 @@ class SfaApi (XmlrpcApi):
         cert_file = auth_info.get_gid_filename()
         server = interface.server_proxy(key_file, cert_file, timeout)
         return server
         cert_file = auth_info.get_gid_filename()
         server = interface.server_proxy(key_file, cert_file, timeout)
         return server
-               
-        
-    def getCredential(self):
+
+    def dbsession(self):
+        if self._dbsession is None:
+            self._dbsession = alchemy.session()
+        return self._dbsession
+
+    def close_dbsession(self):
+        if self._dbsession is None:
+            return
+        alchemy.close_session(self._dbsession)
+        self._dbsession = None
+
+    def getCredential(self, minimumExpiration=0):
         """
         """
-        Return a valid credential for this interface. 
+        Return a valid credential for this interface.
         """
         type = 'authority'
         path = self.config.SFA_DATA_DIR
         filename = ".".join([self.interface, self.hrn, type, "cred"])
         """
         type = 'authority'
         path = self.config.SFA_DATA_DIR
         filename = ".".join([self.interface, self.hrn, type, "cred"])
-        cred_filename = os.path.join(path,filename)
+        cred_filename = os.path.join(path, filename)
         cred = None
         if os.path.isfile(cred_filename):
         cred = None
         if os.path.isfile(cred_filename):
-            cred = Credential(filename = cred_filename)
+            cred = Credential(filename=cred_filename)
             # make sure cred isnt expired
             if not cred.get_expiration or \
             # make sure cred isnt expired
             if not cred.get_expiration or \
-               datetime.datetime.utcnow() < cred.get_expiration():    
+               datetime.datetime.utcnow() + datetime.timedelta(seconds=minimumExpiration) < cred.get_expiration():
                 return cred.save_to_string(save_parents=True)
 
         # get a new credential
         if self.interface in ['registry']:
                 return cred.save_to_string(save_parents=True)
 
         # get a new credential
         if self.interface in ['registry']:
-            cred =  self.__getCredentialRaw()
+            cred = self._getCredentialRaw()
         else:
         else:
-            cred =  self.__getCredential()
+            cred = self._getCredential()
         cred.save_to_file(cred_filename, save_parents=True)
 
         return cred.save_to_string(save_parents=True)
 
         cred.save_to_file(cred_filename, save_parents=True)
 
         return cred.save_to_string(save_parents=True)
 
-
     def getDelegatedCredential(self, creds):
         """
         Attempt to find a credential delegated to us in
         the specified list of creds.
         """
         from sfa.trust.hierarchy import Hierarchy
     def getDelegatedCredential(self, creds):
         """
         Attempt to find a credential delegated to us in
         the specified list of creds.
         """
         from sfa.trust.hierarchy import Hierarchy
-        if creds and not isinstance(creds, list): 
+        if creds and not isinstance(creds, list):
             creds = [creds]
         hierarchy = Hierarchy()
             creds = [creds]
         hierarchy = Hierarchy()
-                
+
         delegated_cred = None
         for cred in creds:
         delegated_cred = None
         for cred in creds:
-            if hierarchy.auth_exists(Credential(string=cred).get_gid_caller().get_hrn()):
+            if hierarchy.auth_exists(Credential(cred=cred).get_gid_caller().get_hrn()):
                 delegated_cred = cred
                 break
         return delegated_cred
                 delegated_cred = cred
                 break
         return delegated_cred
-    def __getCredential(self):
-        """ 
-        Get our credential from a remote registry 
+
+    def _getCredential(self):
+        """
+        Get our credential from a remote registry
         """
         from sfa.server.registry import Registries
         registries = Registries()
         """
         from sfa.server.registry import Registries
         registries = Registries()
-        registry = registries.server_proxy(self.hrn, self.key_file, self.cert_file)
-        cert_string=self.cert.save_to_string(save_parents=True)
+        registry = registries.server_proxy(
+            self.hrn, self.key_file, self.cert_file)
+        cert_string = self.cert.save_to_string(save_parents=True)
         # get self credential
         # get self credential
-        self_cred = registry.GetSelfCredential(cert_string, self.hrn, 'authority')
+        self_cred = registry.GetSelfCredential(
+            cert_string, self.hrn, 'authority')
         # get credential
         cred = registry.GetCredential(self_cred, self.hrn, 'authority')
         return Credential(string=cred)
 
         # get credential
         cred = registry.GetCredential(self_cred, self.hrn, 'authority')
         return Credential(string=cred)
 
-    def __getCredentialRaw(self):
+    def _getCredentialRaw(self):
         """
         Get our current credential directly from the local registry.
         """
 
         hrn = self.hrn
         auth_hrn = self.auth.get_authority(hrn)
         """
         Get our current credential directly from the local registry.
         """
 
         hrn = self.hrn
         auth_hrn = self.auth.get_authority(hrn)
-    
+
         # is this a root or sub authority
         if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
             auth_hrn = hrn
         auth_info = self.auth.get_auth_info(auth_hrn)
         # is this a root or sub authority
         if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
             auth_hrn = hrn
         auth_info = self.auth.get_auth_info(auth_hrn)
-        # xxx thgen fixme - use SfaTable hardwired for now 
-        #table = self.SfaTable()
-        table = SfaTable()
-        records = table.findObjects({'hrn': hrn, 'type': 'authority+sa'})
-        if not records:
-            raise RecordNotFound
-        record = records[0]
-        type = record['type']
+        # xxx although unlikely we might want to check for a potential leak
+        dbsession = self.dbsession()
+        from sfa.storage.model import RegRecord
+        record = dbsession.query(RegRecord).filter_by(
+            type='authority+sa', hrn=hrn).first()
+        if not record:
+            raise RecordNotFound(hrn)
+        type = record.type
         object_gid = record.get_gid_object()
         object_gid = record.get_gid_object()
-        new_cred = Credential(subject = object_gid.get_subject())
+        new_cred = Credential(subject=object_gid.get_subject())
         new_cred.set_gid_caller(object_gid)
         new_cred.set_gid_object(object_gid)
         new_cred.set_gid_caller(object_gid)
         new_cred.set_gid_object(object_gid)
-        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
-        
+        new_cred.set_issuer_keys(
+            auth_info.get_privkey_filename(), auth_info.get_gid_filename())
+
         r1 = determine_rights(type, hrn)
         new_cred.set_privileges(r1)
         new_cred.encode()
         new_cred.sign()
 
         return new_cred
         r1 = determine_rights(type, hrn)
         new_cred.set_privileges(r1)
         new_cred.encode()
         new_cred.sign()
 
         return new_cred
-   
-    def loadCredential (self):
+
+    def loadCredential(self):
         """
         Attempt to load credential from file if it exists. If it doesnt get
         credential from registry.
         """
         Attempt to load credential from file if it exists. If it doesnt get
         credential from registry.
@@ -189,9 +208,9 @@ class SfaApi (XmlrpcApi):
         # XX This is really the aggregate's credential. Using this is easier than getting
         # the registry's credential from iteslf (ssl errors).
         filename = self.interface + self.hrn + ".ma.cred"
         # XX This is really the aggregate's credential. Using this is easier than getting
         # the registry's credential from iteslf (ssl errors).
         filename = self.interface + self.hrn + ".ma.cred"
-        ma_cred_path = os.path.join(self.config.SFA_DATA_DIR,filename)
+        ma_cred_path = os.path.join(self.config.SFA_DATA_DIR, filename)
         try:
         try:
-            self.credential = Credential(filename = ma_cred_path)
+            self.credential = Credential(filename=ma_cred_path)
         except IOError:
             self.credential = self.getCredentialFromRegistry()
 
         except IOError:
             self.credential = self.getCredentialFromRegistry()
 
@@ -201,22 +220,22 @@ class SfaApi (XmlrpcApi):
         if self.cache:
             server_version = self.cache.get(cache_key)
         if not server_version:
         if self.cache:
             server_version = self.cache.get(cache_key)
         if not server_version:
-            server_version = server.GetVersion()
+            result = server.GetVersion()
+            server_version = ReturnValue.get_value(result)
             # cache version for 24 hours
             # cache version for 24 hours
-            self.cache.add(cache_key, server_version, ttl= 60*60*24)
+            self.cache.add(cache_key, server_version, ttl=60 * 60 * 24)
         return server_version
 
         return server_version
 
-
     def get_geni_code(self, result):
         code = {
     def get_geni_code(self, result):
         code = {
-            'geni_code': GENICODE.SUCCESS, 
+            'geni_code': GENICODE.SUCCESS,
             'am_type': 'sfa',
             'am_code': None,
         }
             'am_type': 'sfa',
             'am_code': None,
         }
-        if isinstnace(result, SfaFault):
+        if isinstance(result, SfaFault):
             code['geni_code'] = result.faultCode
             code['geni_code'] = result.faultCode
-            code['am_code'] = result.faultCode                        
-                
+            code['am_code'] = result.faultCode
+
         return code
 
     def get_geni_value(self, result):
         return code
 
     def get_geni_value(self, result):
@@ -227,26 +246,26 @@ class SfaApi (XmlrpcApi):
 
     def get_geni_output(self, result):
         output = ""
 
     def get_geni_output(self, result):
         output = ""
-        if isinstance(result, SFaFault):
-            output = result.faultString 
+        if isinstance(result, SfaFault):
+            output = result.faultString
         return output
 
         return output
 
-    def prepare_response_v2_am(self, result):
+    def prepare_response_am(self, result):
+        version = version_core()
         response = {
         response = {
+            'geni_api': 3,
             'code': self.get_geni_code(result),
             'value': self.get_geni_value(result),
             'output': self.get_geni_output(result),
         }
         return response
             'code': self.get_geni_code(result),
             'value': self.get_geni_value(result),
             'output': self.get_geni_output(result),
         }
         return response
-    
+
     def prepare_response(self, result, method=""):
         """
     def prepare_response(self, result, method=""):
         """
-        Converts the specified result into a standard GENI compliant 
-        response  
+        Converts the specified result into a standard GENI compliant
+        response
         """
         """
-        if self.interface.lower() == 'aggregate': 
-            if hasattr(self.config, 'SFA_AGGREGATE_API_VERSION') and \
-              self.config.SFA_AGGREGATE_API_VERSION == "2":
-                result = self.prepare_response_v2_am(result)
+        # as of dec 13 2011 we only support API v2
+        if self.interface.lower() in ['aggregate', 'slicemgr']:
+            result = self.prepare_response_am(result)
         return XmlrpcApi.prepare_response(self, result, method)
         return XmlrpcApi.prepare_response(self, result, method)
-