Looks like that in the recent release of util-vserver, these variables cannot be...
[sfa.git] / sfa / client / sfi.py
index 6115d36..69ce862 100755 (executable)
@@ -3,9 +3,11 @@
 # sfi -- slice-based facility interface
 
 import sys
+sys.path.append('.')
 import os, os.path
 import tempfile
 import traceback
+import socket
 from types import StringTypes, ListType
 from optparse import OptionParser
 from sfa.trust.certificate import Keypair, Certificate
@@ -140,8 +142,9 @@ class Sfi:
                   "slices": "",
                   "resources": "[name]",
                   "create": "name rspec",
+                  "get_trusted_certs": "cred",
                   "get_ticket": "name rspec",
-                  "redeem_ticket": "ticket rspec",  
+                  "redeem_ticket": "ticket",  
                   "delete": "name",
                   "reset": "name",
                   "start": "name",
@@ -174,6 +177,10 @@ class Sfi:
             parser.add_option("-a", "--aggregate", dest="aggregate",default=None,
                              help="aggregate hrn")
 
+        if command in ("start", "stop", "reset", "delete", "slices"):
+            parser.add_option("-c", "--component", dest="component",default=None,
+                             help="component hrn")
+            
         if command in ("list", "show", "remove"):
             parser.add_option("-t", "--type", dest="type",type="choice",
                             help="type filter ([all]|user|slice|sa|ma|node|aggregate)",
@@ -318,7 +325,8 @@ class Sfi:
     
     
     def get_key_file(self):
-       file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".pkey")
+       file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
+       #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".pkey")
        if (os.path.isfile(file)):
           return file
        else:
@@ -328,7 +336,8 @@ class Sfi:
     
     def get_cert_file(self,key_file):
     
-       file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cert")
+       #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cert")
+       file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
        if (os.path.isfile(file)):
           return file
        else:
@@ -343,7 +352,8 @@ class Sfi:
           return file
    
     def get_gid(self):
-        file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".gid")
+        #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".gid")
+        file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".gid")
         if (os.path.isfile(file)):
             gid = GID(filename=file)
             return gid
@@ -360,7 +370,8 @@ class Sfi:
             return gid       
  
     def get_user_cred(self):
-        file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cred")
+        #file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".cred")
+        file=os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
         if (os.path.isfile(file)):
             user_cred = Credential(filename=file)
             return user_cred
@@ -370,6 +381,10 @@ class Sfi:
             request_hash=None
             if self.hashrequest:
                 request_hash = self.key.compute_hash([cert_string, "user", self.user])
+           user_name=self.user.replace(self.authority+".", '')
+           if user_name.count(".") > 0:
+              user_name = user_name.replace(".", '_')
+              self.user=self.authority + "." + user_name
             user_cred = self.registry.get_self_credential(cert_string, "user", self.user, request_hash)
             if user_cred:
                cred = Credential(string=user_cred)
@@ -502,6 +517,19 @@ class Sfi:
            os.remove(outfn)
     
        return key_string
+
+    def get_component_server_from_hrn(self, hrn):
+        # direct connection to the nodes component manager interface
+        user_cred = self.get_user_cred().save_to_string(save_parents=True)
+        request_hash = self.key.compute_hash([user_cred, hrn])
+        records = self.registry.resolve(user_cred, hrn, request_hash)
+        records = filter_records('node', records)
+        if not records:
+            print "No such component:", opts.component
+        record = records[0]
+        cm_port = "12346"
+        url = "https://%s:%s" % (record['hostname'], cm_port)
+        return xmlrpcprotocol.get_server(url, self.key_file, self.cert_file)
     
     #
     # Following functions implement the commands
@@ -537,7 +565,7 @@ class Sfi:
         if opts.file:
             file = opts.file
             if not file.startswith(os.sep):
-                file = os.path.join(self.options.sfi_dir, get_leaf(self.user) + ".gid")
+                file = os.path.join(self.options.sfi_dir, file)
             save_records_to_file(file, list)
         return
     
@@ -565,7 +593,7 @@ class Sfi:
                 record = GeniRecord(dict = record)
             if (opts.format=="text"): 
                 record.dump()  
-            else: 
+            else:
                 print record.save_to_string() 
        
         if opts.file:
@@ -688,8 +716,17 @@ class Sfi:
             arg_list = [cred]  
             request_hash = self.key.compute_hash(arg_list)
         return self.registry.update(cred, record, request_hash)
-   
-    
+  
+    def get_trusted_certs(self, opts, args):
+        """
+        return the trusted certs at this interface 
+        """ 
+        trusted_certs = self.registry.get_trusted_certs()
+        for trusted_cert in trusted_certs:
+            cert = Certificate(string=trusted_cert)
+            print cert.get_subject()
+        return 
+
     def aggregates(self, opts, args):
         """
         return a list of details about known aggregates
@@ -722,21 +759,6 @@ class Sfi:
         display_list(result)
         return
 
-    def components(self, opts, args):
-        """
-        return a list of details about known components
-        """ 
-        user_cred = self.get_user_cred().save_to_string(save_parents=True)
-        hrn = None
-        if args:
-            hrn = args[0]
-        request_hash=None
-        if self.hashrequest:
-            arg_list = [user_cred, hrn]
-            request_hash = self.key.compute_hash(arg_list)
-        result = self.sm.components(user_cred, hrn, request_hash)
-        display_list(result)
-        return
  
     #
     # Slice-related commands
@@ -751,7 +773,12 @@ class Sfi:
         if self.hashrequest:
             arg_list = [user_cred]
             request_hash = self.key.compute_hash(arg_list)
-        results = self.slicemgr.get_slices(user_cred, request_hash)
+
+        server = self.slicemgr
+        # direct connection to the nodes component manager interface
+        if opts.component:
+            server = self.get_component_server_from_hrn(opts.component)
+        results = server.get_slices(user_cred, request_hash)
         display_list(results)
         return
     
@@ -761,7 +788,7 @@ class Sfi:
         server = self.slicemgr
         if opts.aggregate:
             agg_hrn = opts.aggregate
-            arg_list = [user_cred, arg_hrn]
+            arg_list = [user_cred, agg_hrn]
             request_hash = self.key.compute_hash(arg_list)
             aggregates = self.registry.get_aggregates(user_cred, agg_hrn, request_hash)
             if not aggregates:
@@ -836,56 +863,101 @@ class Sfi:
         print "writing ticket to ", file        
         ticket = SfaTicket(string=ticket_string)
         ticket.save_to_file(filename=file, save_parents=True)
-        print ticket_string  
 
     def redeem_ticket(self, opts, args):
-        ticket, rspec = args[0], args[1]
+        ticket_file = args[0]
+        
+        # get slice hrn from the ticket
+        # use this to get the right slice credential 
+        ticket = SfaTicket(filename=ticket_file)
+        ticket.decode()
+        slice_hrn = ticket.attributes['slivers'][0]['hrn']
+        user_cred = self.get_user_cred()
+        slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
+        
         # get a list node hostnames from the nodespecs in the rspec 
-        resource_spec = RSpec(rspec)
-        nodepecs = resource_spec.getDictsByTagName('NodeSpec')
-        from pprint import pprint
-        pprint(nodespecs) 
+        rspec = RSpec()
+        rspec.parseString(ticket.rspec)
+        nodespecs = rspec.getDictsByTagName('NodeSpec')
+        hostnames = [nodespec['name'] for nodespec in nodespecs]
+        
+        # create an xmlrpc connection to the component manager at each of these
+        # components and gall redeem_ticket
+        connections = {}
+        for hostname in hostnames:
+            try:
+                cm_port = "12346" 
+                url = "https://%(hostname)s:%(cm_port)s" % locals() 
+                print "Calling get_ticket at %(url)s " % locals(),  
+                cm = xmlrpcprotocol.get_server(url, self.key_file, self.cert_file)
+                cm.redeem_ticket(slice_cred, ticket.save_to_string(save_parents=True))
+                print "Success"
+            except socket.gaierror:
+                print "Failed:",
+                print "Componet Manager not accepting requests" 
+            except Exception, e:
+                print "Failed:", e.message
+             
         return
  
     # delete named slice
     def delete(self,opts, args):
         slice_hrn = args[0]
+        server = self.slicemgr
+        # direct connection to the nodes component manager interface
+        if opts.component:
+            server = self.get_component_server_from_hrn(opts.component)
         slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
         request_hash=None
         if self.hashrequest:
             arg_list = [slice_cred, slice_hrn]
             request_hash = self.key.compute_hash(arg_list) 
-        return self.slicemgr.delete_slice(slice_cred, slice_hrn, request_hash)
+        return server.delete_slice(slice_cred, slice_hrn, request_hash)
     
     # start named slice
     def start(self,opts, args):
         slice_hrn = args[0]
-        slice_cred = self.get_slice_cred(args[0])
+        server = self.slicemgr
+        # direct connection to the nodes component manager interface
+        if opts.component:
+            server = self.get_component_server_from_hrn(opts.component)
+        slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
         request_hash=None
         if self.hashrequest:
             arg_list = [slice_cred, slice_hrn]
             request_hash = self.key.compute_hash(arg_list)
-        return self.slicemgr.start_slice(slice_cred, slice_hrn, request_hash)
+        return server.start_slice(slice_cred, slice_hrn, request_hash)
     
     # stop named slice
     def stop(self,opts, args):
         slice_hrn = args[0]
+        server = self.slicemgr
+        # direct connection to the nodes component manager interface
+        if opts.component:
+            server = self.get_component_server_from_hrn(opts.component)
+
         slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
         request_hash=None
         if self.hashrequest:
             arg_list = [slice_cred, slice_hrn]
             request_hash = self.key.compute_hash(arg_list)
-        return self.slicemgr.stop_slice(slice_cred, slice_hrn, request_hash)
+        return server.stop_slice(slice_cred, slice_hrn, request_hash)
     
     # reset named slice
     def reset(self,opts, args):
         slice_hrn = args[0]
+        server = self.slicemgr
+        # direct connection to the nodes component manager interface
+        if opts.component:
+            server = self.get_component_server_from_hrn(opts.component)
         slice_cred = self.get_slice_cred(args[0]).save_to_string(save_parents=True)
         request_hash=None
         if self.hashrequest:
             arg_list = [slice_cred, slice_hrn]
             request_hash = self.key.compute_hash(arg_list)
-        return self.slicemgr.reset_slice(slice_cred, slice_hrn, request_hash)
+        return server.reset_slice(slice_cred, slice_hrn, request_hash)
     
     #
     # Main: parse arguments and dispatch to command