From 40971b94986fbc73719d7be19b0bb81fe673a170 Mon Sep 17 00:00:00 2001
From: Josh Karlin <jkarlin@bbn.com>
Date: Mon, 19 Apr 2010 21:25:29 +0000
Subject: [PATCH] Full API implemented.

---
 sfa/client/sfi.py                    | 24 ++++++++++++++++++++----
 sfa/managers/aggregate_manager_pl.py |  2 +-
 sfa/managers/registry_manager_pl.py  | 23 +++++++++++++++++++++++
 sfa/managers/slice_manager_pl.py     |  1 +
 sfa/methods/CreateSliver.py          | 22 ++++++++++++++++++++--
 sfa/methods/GetVersion.py            |  8 +++++++-
 sfa/methods/ListResources.py         | 27 ++++++++++++++++++++++-----
 sfa/methods/__init__.py              |  1 +
 sfa/plc/network.py                   |  1 +
 sfa/trust/certificate.py             | 28 ++++++++++++++++------------
 sfa/trust/credential.py              | 20 ++++++++++----------
 sfa/trust/rights.py                  |  2 +-
 12 files changed, 123 insertions(+), 36 deletions(-)

diff --git a/sfa/client/sfi.py b/sfa/client/sfi.py
index 45635d0e..550edcfb 100755
--- a/sfa/client/sfi.py
+++ b/sfa/client/sfi.py
@@ -947,17 +947,15 @@ class Sfi:
         if args:
             xrn = args[0]
             cred = self.get_slice_cred(xrn).save_to_string(save_parents=True)
-
         if xrn:
             call_options['geni_slice_urn'] = xrn
             
-        rspec = server.ListResources([user_cred], call_options)
+        rspec = server.ListResources([cred], call_options)
         rspec = zlib.decompress(rspec.decode('base64'))
         print rspec
         
     def CreateSliver(self, opts, args):
         slice_xrn = args[0]
-        user_cred = self.get_user_cred()
         slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True)
         rspec_file = self.get_rspec_file(args[1])
         rspec = open(rspec_file).read()
@@ -966,10 +964,28 @@ class Sfi:
     
     def DeleteSliver(self, opts, args):
         slice_xrn = args[0]
-        user_cred = self.get_user_cred()
         slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True)
         server = self.geni_am
         return server.DeleteSliver(slice_xrn, [slice_cred])    
+
+    def SliverStatus(self, opts, args):
+        slice_xrn = args[0]
+        slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True)
+        server = self.geni_am
+        return server.SliverStatus(slice_xrn, [slice_cred])
+    
+    def RenewSliver(self, opts, args):
+        slice_xrn = args[0]
+        slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True)
+        time = args[1]
+        server = self.geni_am
+        return server.RenewSliver(slice_xrn, [slice_cred], time)   
+
+    def Shutdown(self, opts, args):
+        slice_xrn = args[0]
+        slice_cred = self.get_slice_cred(slice_xrn).save_to_string(save_parents=True)
+        server = self.geni_am
+        return server.Shutdown(slice_xrn, [slice_cred])         
     
     #
     # Main: parse arguments and dispatch to command
diff --git a/sfa/managers/aggregate_manager_pl.py b/sfa/managers/aggregate_manager_pl.py
index 2ca9db4f..12b170b9 100644
--- a/sfa/managers/aggregate_manager_pl.py
+++ b/sfa/managers/aggregate_manager_pl.py
@@ -146,7 +146,7 @@ def start_slice(api, xrn):
         raise RecordNotFound(hrn)
     slice_id = slices[0]
     attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
-    attribute_id = attreibutes[0]['slice_attribute_id']
+    attribute_id = attributes[0]['slice_attribute_id']
     api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
 
     return 1
diff --git a/sfa/managers/registry_manager_pl.py b/sfa/managers/registry_manager_pl.py
index 18181aec..6ed5da8d 100644
--- a/sfa/managers/registry_manager_pl.py
+++ b/sfa/managers/registry_manager_pl.py
@@ -10,6 +10,14 @@ from sfa.trust.credential import *
 from sfa.trust.certificate import *
 from sfa.util.faults import *
 
+def GetVersion():
+    version = {}
+    version['geni_api'] = 1
+    return version
+
+
+    
+
 def get_credential(api, xrn, type, is_self=False):
     # convert xrn to hrn     
     if type:
@@ -66,6 +74,21 @@ def get_credential(api, xrn, type, is_self=False):
 
     return new_cred.save_to_string(save_parents=True)
 
+# The GENI resolve call
+def Resolve(api, xrn, creds):
+    records = resolve(api, xrn)
+    
+    if len(records) == 0:
+        return {}
+    
+    record = records[0]
+    if record.type == 'slice':
+        return {'geni_urn': xrn, 'geni_creator': record.gid}
+    if record.type == 'user':
+        return {'geni_urn': xrn, 'geni_certificate': record.gid}
+    
+    
+
 def resolve(api, xrns, type=None, origin_hrn=None, full=True):
 
     # load all know registry names into a prefix tree and attempt to find
diff --git a/sfa/managers/slice_manager_pl.py b/sfa/managers/slice_manager_pl.py
index 2c824cfd..3a15b68c 100644
--- a/sfa/managers/slice_manager_pl.py
+++ b/sfa/managers/slice_manager_pl.py
@@ -23,6 +23,7 @@ from sfa.util.debug import log
 from sfa.util.sfalogging import logger
 import sfa.plc.peers as peers
 
+
 def delete_slice(api, xrn, origin_hrn=None):
     credential = api.getCredential()
     aggregates = api.aggregates
diff --git a/sfa/methods/CreateSliver.py b/sfa/methods/CreateSliver.py
index 48cf9803..e8738018 100644
--- a/sfa/methods/CreateSliver.py
+++ b/sfa/methods/CreateSliver.py
@@ -2,6 +2,9 @@ from sfa.util.faults import *
 from sfa.util.namespace import *
 from sfa.util.method import Method
 from sfa.util.parameter import Parameter
+from sfatables.runtime import SFATablesRules
+import sys
+from sfa.trust.credential import Credential
 
 class CreateSliver(Method):
     """
@@ -23,6 +26,17 @@ class CreateSliver(Method):
         ]
     returns = Parameter(str, "Allocated RSpec")
 
+    def __run_sfatables(self, manager, rules, hrn, origin_hrn, rspec):
+        if rules.sorted_rule_list:
+            contexts = rules.contexts
+            request_context = manager.fetch_context(hrn, origin_hrn, contexts)
+            rules.set_context(request_context)
+            newrspec = rules.apply(rspec)
+        else:    
+            newrspec = rspec
+        return newrspec
+
+
     def call(self, slice_xrn, creds, rspec):
         hrn, type = urn_to_hrn(slice_xrn)
 
@@ -33,14 +47,16 @@ class CreateSliver(Method):
         for cred in creds:
             try:
                 self.api.auth.check(cred, 'createslice')
+                origin_hrn = Credential(string=cred).get_gid_caller().get_hrn()
                 found = True
                 break
             except:
+                error = sys.exc_info()[:2]
                 continue
             
         if not found:
-            raise InsufficientRights('CreateSliver: Credentials either did not verify, were no longer valid, or did not have appropriate privileges')
-            
+            raise InsufficientRights('CreateSliver: Access denied: %s -- %s' % (error[0],error[1]))
+             
         
         manager_base = 'sfa.managers'
 
@@ -48,6 +64,8 @@ class CreateSliver(Method):
             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])
+            rspec = self.__run_sfatables(manager, SFATablesRules('INCOMING'),
+                                         hrn, origin_hrn, rspec)
             return manager.CreateSliver(self.api, slice_xrn, creds, rspec)
 
         return ''
diff --git a/sfa/methods/GetVersion.py b/sfa/methods/GetVersion.py
index f419d5a8..e1ca8b3b 100644
--- a/sfa/methods/GetVersion.py
+++ b/sfa/methods/GetVersion.py
@@ -9,7 +9,7 @@ class GetVersion(Method):
     Returns this GENI Aggregate Manager's Version Information
     @return version
     """
-    interfaces = ['geni_am']
+    interfaces = ['geni_am','registry']
     accepts = []
     returns = Parameter(dict, "Version information")
 
@@ -23,5 +23,11 @@ class GetVersion(Method):
             manager_module = manager_base + ".geni_am_%s" % mgr_type
             manager = __import__(manager_module, fromlist=[manager_base])
             return manager.GetVersion()
+        if self.api.interface in ['registry']:
+            mgr_type = self.api.config.SFA_REGISTRY_TYPE
+            manager_module = manager_base + ".slice_manager_%s" % mgr_type
+            manager = __import__(manager_module, fromlist=[manager_base])
+            return manager.GetVersion()
+        
         return {}
     
diff --git a/sfa/methods/ListResources.py b/sfa/methods/ListResources.py
index a28fb0e1..0007c255 100644
--- a/sfa/methods/ListResources.py
+++ b/sfa/methods/ListResources.py
@@ -2,6 +2,10 @@ 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.credential import Credential
+from sfatables.runtime import SFATablesRules
+import sys
+
 
 class ListResources(Method):
     """
@@ -19,27 +23,40 @@ class ListResources(Method):
 
     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')
+                self.api.auth.check(cred, 'listnodes')
                 found = True
+                user_cred = Credential(string=cred)
                 break
             except:
+                error = sys.exc_info()[:2]
                 continue
             
         if not found:
-            raise InsufficientRights('ListResources: Credentials either did not verify, were no longer valid, or did not have appropriate privileges')
+            raise InsufficientRights('ListResources: Access denied: %s -- %s' % (error[0],error[1]))
         
+        origin_hrn = user_cred.get_gid_caller().get_hrn()
+                    
         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)
+            rspec = manager.ListResources(self.api, creds, options)
+            outgoing_rules = SFATablesRules('OUTGOING')
+            
+        
+        filtered_rspec = rspec
+        if outgoing_rules.sorted_rule_list:
+            context = {'sfa':{'user':{'hrn':origin_hrn}, 'slice':{'hrn':None}}}
+            outgoing_rules.set_context(context)
+            filtered_rspec = outgoing_rules.apply(rspec)      
 
-        return ''
+        return filtered_rspec  
+    
     
diff --git a/sfa/methods/__init__.py b/sfa/methods/__init__.py
index 243db987..dd35e3e4 100644
--- a/sfa/methods/__init__.py
+++ b/sfa/methods/__init__.py
@@ -34,4 +34,5 @@ DeleteSliver
 SliverStatus
 RenewSliver
 Shutdown
+Resolve
 """.split()
diff --git a/sfa/plc/network.py b/sfa/plc/network.py
index 955036c5..01ed4f77 100644
--- a/sfa/plc/network.py
+++ b/sfa/plc/network.py
@@ -102,6 +102,7 @@ class Site:
     def toxml(self, xml):
         if not (self.public and self.enabled and self.node_ids):
             return
+
         with xml.site(id = self.idtag):
             with xml.name:
                 xml << self.name
diff --git a/sfa/trust/certificate.py b/sfa/trust/certificate.py
index c49c50cc..f7dec97c 100644
--- a/sfa/trust/certificate.py
+++ b/sfa/trust/certificate.py
@@ -22,8 +22,7 @@ import traceback
 from OpenSSL import crypto
 import M2Crypto
 from M2Crypto import X509
-from M2Crypto import EVP
-from random import randint
+from tempfile import mkstemp
 
 from sfa.util.faults import *
 
@@ -315,19 +314,24 @@ class Certificate:
    # Save the certificate to a file.
    # @param save_parents If save_parents==True, then also save the parent certificates.
 
-   def save_to_file(self, filename, save_parents=True):
+   def save_to_file(self, filename, save_parents=True, filep=None):
        string = self.save_to_string(save_parents=save_parents)
-       open(filename, 'w').write(string)
+       if filep:
+           f = filep
+       else:
+           f = open(filename, 'w')
+       f.write(string)
+       f.close()
+
    ##
    # Save the certificate to a random file in /tmp/
-   # @param save_parents If save_parents==True, then also save the parent certificates.
-   def save_to_random_tmp_file(self, save_parents=True):
-       while True:
-           filename = "/tmp/cred_%d" % randint(0,999999999)
-           if not os.path.isfile(filename):
-               break
-       self.save_to_file(filename, save_parents)
-       return filename
+   # @param save_parents If save_parents==True, then also save the parent certificates.  
+   def save_to_random_tmp_file(self, save_parents=True):       
+       fp, filename = mkstemp(suffix='cert', text=True)
+       fp = os.fdopen(fp, "w")
+       self.save_to_file(filename, save_parents=True, filep=fp)
+       return filename   
+
    ##
    # Sets the issuer private key and name
    # @param key Keypair object containing the private key of the issuer
diff --git a/sfa/trust/credential.py b/sfa/trust/credential.py
index c72817b5..bb58407e 100644
--- a/sfa/trust/credential.py
+++ b/sfa/trust/credential.py
@@ -9,8 +9,8 @@
 
 import os
 import datetime
-from random import randint
 from xml.dom.minidom import Document, parseString
+from tempfile import mkstemp
 
 from sfa.trust.credential_legacy import CredentialLegacy
 from sfa.trust.rights import *
@@ -411,19 +411,19 @@ class Credential(object):
         self.xml = doc.toxml()
 
 
-    def save_to_random_tmp_file(self):
-        while True:
-            filename = "/tmp/cred_%d" % randint(0,999999999)
-            if not os.path.isfile(filename):
-                break
-            
-        self.save_to_file(filename)
+    def save_to_random_tmp_file(self):       
+        fp, filename = mkstemp(suffix='cred', text=True)
+        fp = os.fdopen(fp, "w")
+        self.save_to_file(filename, save_parents=True, filep=fp)
         return filename
     
-    def save_to_file(self, filename, save_parents=True):
+    def save_to_file(self, filename, save_parents=True, filep=None):
         if not self.xml:
             self.encode()
-        f = open(filename, "w")
+        if filep:
+            f = filep 
+        else:
+            f = open(filename, "w")
         f.write(self.xml)
         f.close()
 
diff --git a/sfa/trust/rights.py b/sfa/trust/rights.py
index bef63824..fa5c043c 100644
--- a/sfa/trust/rights.py
+++ b/sfa/trust/rights.py
@@ -18,7 +18,7 @@
 
 privilege_table = {"authority": ["register", "remove", "update", "resolve", "list", "getcredential", "*"],
                    "refresh": ["remove", "update"],
-                   "resolve": ["resolve", "list", "getcredential", "listresources", "getversion"],
+                   "resolve": ["resolve", "list", "getcredential", "getversion"],
                    "sa": ["getticket", "redeemslice", "redeemticket", "createslice", "deleteslice", "updateslice", 
                           "getsliceresources", "getticket", "loanresources", "stopslice", "startslice", "renewsliver",
                           "deleteslice", "resetslice", "listslices", "listnodes", "getpolicy", "createsliver", "sliverestatus"],
-- 
2.47.0