removed another bunch of references to geni
[sfa.git] / sfa / plc / api.py
index a1e702f..b5c9ce4 100644 (file)
@@ -1,5 +1,5 @@
 #
 #
-# Geniwrapper XML-RPC and SOAP interfaces
+# SFA XML-RPC and SOAP interfaces
 #
 ### $Id$
 ### $URL$
 #
 ### $Id$
 ### $URL$
@@ -10,100 +10,30 @@ import os
 import traceback
 import string
 import xmlrpclib
 import traceback
 import string
 import xmlrpclib
-
 from sfa.trust.auth import Auth
 from sfa.util.config import *
 from sfa.util.faults import *
 from sfa.util.debug import *
 from sfa.trust.rights import *
 from sfa.trust.credential import *
 from sfa.trust.auth import Auth
 from sfa.util.config import *
 from sfa.util.faults import *
 from sfa.util.debug import *
 from sfa.trust.rights import *
 from sfa.trust.credential import *
-from sfa.util.misc import *
+from sfa.trust.certificate import *
+from sfa.util.namespace import *
+from sfa.util.api import *
+from sfa.util.nodemanager import NodeManager
 from sfa.util.sfalogging import *
 from sfa.util.sfalogging import *
-from sfa.util.genitable import *
+from sfa.util.table import SfaTable
 
 
-# See "2.2 Characters" in the XML specification:
-#
-# #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
-# avoiding
-# [#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDDF]
-
-invalid_xml_ascii = map(chr, range(0x0, 0x8) + [0xB, 0xC] + range(0xE, 0x1F))
-xml_escape_table = string.maketrans("".join(invalid_xml_ascii), "?" * len(invalid_xml_ascii))
-
-def xmlrpclib_escape(s, replace = string.replace):
-    """
-    xmlrpclib does not handle invalid 7-bit control characters. This
-    function augments xmlrpclib.escape, which by default only replaces
-    '&', '<', and '>' with entities.
-    """
-
-    # This is the standard xmlrpclib.escape function
-    s = replace(s, "&", "&amp;")
-    s = replace(s, "<", "&lt;")
-    s = replace(s, ">", "&gt;",)
-
-    # Replace invalid 7-bit control characters with '?'
-    return s.translate(xml_escape_table)
-
-def xmlrpclib_dump(self, value, write):
-    """
-    xmlrpclib cannot marshal instances of subclasses of built-in
-    types. This function overrides xmlrpclib.Marshaller.__dump so that
-    any value that is an instance of one of its acceptable types is
-    marshalled as that type.
-
-    xmlrpclib also cannot handle invalid 7-bit control characters. See
-    above.
-    """
-
-    # Use our escape function
-    args = [self, value, write]
-    if isinstance(value, (str, unicode)):
-        args.append(xmlrpclib_escape)
-
-    try:
-        # Try for an exact match first
-        f = self.dispatch[type(value)]
-    except KeyError:
-        raise
-        # Try for an isinstance() match
-        for Type, f in self.dispatch.iteritems():
-            if isinstance(value, Type):
-                f(*args)
-                return
-        raise TypeError, "cannot marshal %s objects" % type(value)
-    else:
-        f(*args)
-
-# You can't hide from me!
-xmlrpclib.Marshaller._Marshaller__dump = xmlrpclib_dump
-
-# SOAP support is optional
-try:
-    import SOAPpy
-    from SOAPpy.Parser import parseSOAPRPC
-    from SOAPpy.Types import faultType
-    from SOAPpy.NS import NS
-    from SOAPpy.SOAPBuilder import buildSOAP
-except ImportError:
-    SOAPpy = None
-
-
-def import_deep(name):
-    mod = __import__(name)
-    components = name.split('.')
-    for comp in components[1:]:
-        mod = getattr(mod, comp)
-    return mod
-
-class GeniAPI:
+class SfaAPI(BaseAPI):
 
     # flat list of method names
     import sfa.methods
     methods = sfa.methods.all
     
 
     # flat list of method names
     import sfa.methods
     methods = sfa.methods.all
     
-    def __init__(self, config = "/etc/sfa/sfa_config", encoding = "utf-8", 
+    def __init__(self, config = "/etc/sfa/sfa_config", encoding = "utf-8", methods='sfa.methods', 
                  peer_cert = None, interface = None, key_file = None, cert_file = None):
                  peer_cert = None, interface = None, key_file = None, cert_file = None):
+        BaseAPI.__init__(self, config=config, encoding=encoding, methods=methods, peer_cert=peer_cert,
+                         interface=interface, key_file=key_file, cert_file=cert_file)
         self.encoding = encoding
 
         # Better just be documenting the API
         self.encoding = encoding
 
         # Better just be documenting the API
@@ -115,11 +45,14 @@ class GeniAPI:
         self.auth = Auth(peer_cert)
         self.interface = interface
         self.key_file = key_file
         self.auth = Auth(peer_cert)
         self.interface = interface
         self.key_file = key_file
+        self.key = Keypair(filename=self.key_file)
         self.cert_file = cert_file
         self.cert_file = cert_file
+        self.cert = Certificate(filename=self.cert_file)
         self.credential = None
         
         # Initialize the PLC shell only if SFA wraps a myPLC
         self.credential = None
         
         # Initialize the PLC shell only if SFA wraps a myPLC
-        if (self.config.get_aggregate_rspec_type() == 'pl'):
+        rspec_type = self.config.get_aggregate_rspec_type()
+        if (rspec_type == 'pl' or rspec_type == 'vini'):
             self.plshell = self.getPLCShell()
             self.plshell_version = self.getPLCShellVersion()
 
             self.plshell = self.getPLCShell()
             self.plshell_version = self.getPLCShellVersion()
 
@@ -166,25 +99,29 @@ class GeniAPI:
         else:
             return self.getCredentialFromRegistry()
     
         else:
             return self.getCredentialFromRegistry()
     
-
     def getCredentialFromRegistry(self):
         """ 
     def getCredentialFromRegistry(self):
         """ 
-        Get our credential from a remote registry using a geniclient connection
+        Get our credential from a remote registry 
         """
         type = 'authority'
         """
         type = 'authority'
-        path = self.config.SFA_BASE_DIR
+        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)
         filename = ".".join([self.interface, self.hrn, type, "cred"])
         cred_filename = path + os.sep + filename
         try:
             credential = Credential(filename = cred_filename)
-            return credential
+            return credential.save_to_string(save_parents=True)
         except IOError:
             from sfa.server.registry import Registries
             registries = Registries(self)
             registry = registries[self.hrn]
         except IOError:
             from sfa.server.registry import Registries
             registries = Registries(self)
             registry = registries[self.hrn]
-            self_cred = registry.get_credential(None, type, self.hrn)
+            cert_string=self.cert.save_to_string(save_parents=True)
+            # get self credential
+            self_cred = registry.get_self_credential(cert_string, type, self.hrn)
+            # get credential
             cred = registry.get_credential(self_cred, type, self.hrn)
             cred = registry.get_credential(self_cred, type, self.hrn)
-            cred.save_to_file(cred_filename, save_parents=True)
+            
+            # save cred to file
+            Credential(string=cred).save_to_file(cred_filename, save_parents=True)
             return cred
 
     def getCredentialFromLocalRegistry(self):
             return cred
 
     def getCredentialFromLocalRegistry(self):
@@ -199,7 +136,7 @@ class GeniAPI:
         if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
             auth_hrn = hrn
         auth_info = self.auth.get_auth_info(auth_hrn)
         if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
             auth_hrn = hrn
         auth_info = self.auth.get_auth_info(auth_hrn)
-        table = GeniTable()
+        table = SfaTable()
         records = table.findObjects(hrn)
         if not records:
             raise RecordNotFound
         records = table.findObjects(hrn)
         if not records:
             raise RecordNotFound
@@ -221,7 +158,7 @@ class GeniAPI:
         new_cred.encode()
         new_cred.sign()
 
         new_cred.encode()
         new_cred.sign()
 
-        return new_cred
+        return new_cred.save_to_string(save_parents=True)
    
 
     def loadCredential (self):
    
 
     def loadCredential (self):
@@ -233,22 +170,22 @@ class GeniAPI:
         # see if this file exists
         # XX This is really the aggregate's credential. Using this is easier than getting
         # the registry's credential from iteslf (ssl errors).   
         # see if this file exists
         # XX This is really the aggregate's credential. Using this is easier than getting
         # the registry's credential from iteslf (ssl errors).   
-        ma_cred_filename = self.config.SFA_BASE_DIR + os.sep + self.interface + self.hrn + ".ma.cred"
+        ma_cred_filename = self.config.SFA_DATA_DIR + os.sep + self.interface + self.hrn + ".ma.cred"
         try:
             self.credential = Credential(filename = ma_cred_filename)
         except IOError:
             self.credential = self.getCredentialFromRegistry()
 
     ##
         try:
             self.credential = Credential(filename = ma_cred_filename)
         except IOError:
             self.credential = self.getCredentialFromRegistry()
 
     ##
-    # Convert geni fields to PLC fields for use when registering up updating
+    # Convert SFA fields to PLC fields for use when registering up updating
     # registry record in the PLC database
     #
     # @param type type of record (user, slice, ...)
     # @param hrn human readable name
     # registry record in the PLC database
     #
     # @param type type of record (user, slice, ...)
     # @param hrn human readable name
-    # @param geni_fields dictionary of geni fields
+    # @param sfa_fields dictionary of SFA fields
     # @param pl_fields dictionary of PLC fields (output)
 
     # @param pl_fields dictionary of PLC fields (output)
 
-    def geni_fields_to_pl_fields(self, type, hrn, record):
+    def sfa_fields_to_pl_fields(self, type, hrn, record):
 
         def convert_ints(tmpdict, int_fields):
             for field in int_fields:
 
         def convert_ints(tmpdict, int_fields):
             for field in int_fields:
@@ -267,11 +204,13 @@ class GeniAPI:
                pl_record["url"] = record["url"]
            if "description" in record:
                pl_record["description"] = record["description"]
                pl_record["url"] = record["url"]
            if "description" in record:
                pl_record["description"] = record["description"]
+           if "expires" in record:
+               pl_record["expires"] = int(record["expires"])
 
         elif type == "node":
             if not "hostname" in pl_record:
                 if not "hostname" in record:
 
         elif type == "node":
             if not "hostname" in pl_record:
                 if not "hostname" in record:
-                    raise MissingGeniInfo("hostname")
+                    raise MissingSfaInfo("hostname")
                 pl_record["hostname"] = record["hostname"]
             if not "model" in pl_record:
                 pl_record["model"] = "geni"
                 pl_record["hostname"] = record["hostname"]
             if not "model" in pl_record:
                 pl_record["model"] = "geni"
@@ -295,7 +234,7 @@ class GeniAPI:
 
     def fill_record_pl_info(self, record):
         """
 
     def fill_record_pl_info(self, record):
         """
-        Fill in the planetlab specific fields of a Geni record. This
+        Fill in the planetlab specific fields of a SFA record. This
         involves calling the appropriate PLC method to retrieve the 
         database record for the object.
         
         involves calling the appropriate PLC method to retrieve the 
         database record for the object.
         
@@ -323,7 +262,7 @@ class GeniAPI:
         elif (type == "node"):
             pl_res = self.plshell.GetNodes(self.plauth, [pointer])
         else:
         elif (type == "node"):
             pl_res = self.plshell.GetNodes(self.plauth, [pointer])
         else:
-            raise UnknownGeniType(type)
+            raise UnknownSfaType(type)
         
         if not pl_res:
             raise PlanetLabRecordDoesNotExist(record['hrn'])
         
         if not pl_res:
             raise PlanetLabRecordDoesNotExist(record['hrn'])
@@ -367,15 +306,15 @@ class GeniAPI:
 
 
 
 
 
 
-    def fill_record_geni_info(self, record):
-        geni_info = {}
+    def fill_record_sfa_info(self, record):
+        sfa_info = {}
         type = record['type']
         type = record['type']
-        table = GeniTable()
+        table = SfaTable()
         if (type == "slice"):
             person_ids = record.get("person_ids", [])
             persons = table.find({'type': 'user', 'pointer': person_ids})
             researchers = [person['hrn'] for person in persons]
         if (type == "slice"):
             person_ids = record.get("person_ids", [])
             persons = table.find({'type': 'user', 'pointer': person_ids})
             researchers = [person['hrn'] for person in persons]
-            geni_info['researcher'] = researchers
+            sfa_info['researcher'] = researchers
 
         elif (type == "authority"):
             person_ids = record.get("person_ids", [])
 
         elif (type == "authority"):
             person_ids = record.get("person_ids", [])
@@ -399,28 +338,28 @@ class GeniAPI:
                 if 'admin' in person['roles']:
                     admins.append(hrn)
             
                 if 'admin' in person['roles']:
                     admins.append(hrn)
             
-            geni_info['PI'] = pis
-            geni_info['operator'] = techs
-            geni_info['owner'] = admins
+            sfa_info['PI'] = pis
+            sfa_info['operator'] = techs
+            sfa_info['owner'] = admins
             # xxx TODO: OrganizationName
 
         elif (type == "node"):
             # xxx TODO: OrganizationName
 
         elif (type == "node"):
-            geni_info['dns'] = record.get("hostname", "")
+            sfa_info['dns'] = record.get("hostname", "")
             # xxx TODO: URI, LatLong, IP, DNS
     
         elif (type == "user"):
             # xxx TODO: URI, LatLong, IP, DNS
     
         elif (type == "user"):
-            geni_info['email'] = record.get("email", "")
+            sfa_info['email'] = record.get("email", "")
             # xxx TODO: PostalAddress, Phone
 
             # xxx TODO: PostalAddress, Phone
 
-        record.update(geni_info)
+        record.update(sfa_info)
 
     def fill_record_info(self, record):
         """
 
     def fill_record_info(self, record):
         """
-        Given a geni record, fill in the PLC specific and Geni specific
+        Given a SFA record, fill in the PLC specific and SFA specific
         fields in the record. 
         """
         self.fill_record_pl_info(record)
         fields in the record. 
         """
         self.fill_record_pl_info(record)
-        self.fill_record_geni_info(record)
+        self.fill_record_sfa_info(record)
 
     def update_membership_list(self, oldRecord, record, listName, addFunc, delFunc):
         # get a list of the HRNs tht are members of the old and new records
 
     def update_membership_list(self, oldRecord, record, listName, addFunc, delFunc):
         # get a list of the HRNs tht are members of the old and new records
@@ -437,7 +376,7 @@ class GeniAPI:
         # build a list of the new person ids, by looking up each person to get
         # their pointer
         newIdList = []
         # build a list of the new person ids, by looking up each person to get
         # their pointer
         newIdList = []
-        table = GeniTable()
+        table = SfaTable()
         records = table.find({'type': 'user', 'hrn': newList})
         for rec in records:
             newIdList.append(rec['pointer'])
         records = table.find({'type': 'user', 'hrn': newList})
         for rec in records:
             newIdList.append(rec['pointer'])
@@ -472,74 +411,25 @@ class GeniAPI:
             pass
 
 
             pass
 
 
-    def callable(self, method):
-        """
-        Return a new instance of the specified method.
-        """
-        # Look up method
-        if method not in self.methods:
-            raise GeniInvalidAPIMethod, method
-        
-        # Get new instance of method
-        try:
-            classname = method.split(".")[-1]
-            module = __import__("sfa.methods." + method, globals(), locals(), [classname])
-            callablemethod = getattr(module, classname)(self)
-            return getattr(module, classname)(self)
-        except ImportError, AttributeError:
-            raise
-            raise GeniInvalidAPIMethod, method
-
-    def call(self, source, method, *args):
-        """
-        Call the named method from the specified source with the
-        specified arguments.
-        """
-        function = self.callable(method)
-        function.source = source
-        return function(*args)
 
 
-    def handle(self, source, data):
-        """
-        Handle an XML-RPC or SOAP request from the specified source.
-        """
-        # Parse request into method name and arguments
-        try:
-            interface = xmlrpclib
-            (args, method) = xmlrpclib.loads(data)
-            methodresponse = True
-        except Exception, e:
-            if SOAPpy is not None:
-                interface = SOAPpy
-                (r, header, body, attrs) = parseSOAPRPC(data, header = 1, body = 1, attrs = 1)
-                method = r._name
-                args = r._aslist()
-                # XXX Support named arguments
-            else:
-                raise e
+class ComponentAPI(BaseAPI):
 
 
-        try:
-            result = self.call(source, method, *args)
-        except Exception, fault:
-            traceback.print_exc(file = log)
-            # Handle expected faults
-            if interface == xmlrpclib:
-                result = fault
-                methodresponse = None
-            elif interface == SOAPpy:
-                result = faultParameter(NS.ENV_T + ":Server", "Method Failed", method)
-                result._setDetail("Fault %d: %s" % (fault.faultCode, fault.faultString))
-            else:
-                raise
-
-        # Return result
-        if interface == xmlrpclib:
-            if not isinstance(result, GeniFault):
-                result = (result,)
-
-            data = xmlrpclib.dumps(result, methodresponse = True, encoding = self.encoding, allow_none = 1)
-        elif interface == SOAPpy:
-            data = buildSOAP(kw = {'%sResponse' % method: {'Result': result}}, encoding = self.encoding)
-
-        return data
+    def __init__(self, config = "/etc/sfa/sfa_config", encoding = "utf-8", methods='sfa.methods',
+                 peer_cert = None, interface = None, key_file = None, cert_file = None):
+
+        BaseAPI.__init__(self, config=config, encoding=encoding, methods=methods, peer_cert=peer_cert,
+                         interface=interface, key_file=key_file, cert_file=cert_file)
+        self.encoding = encoding
 
 
+        # Better just be documenting the API
+        if config is None:
+            return
+
+        self.nodemanager = NodeManager()
+
+    def sliver_exists(self):
+        sliver_dict = self.nodemanager.GetXIDs()
+        if slicename in sliver_dict.keys():
+            return True
+        else:
+            return False