Merge branch 'master' of ssh://bakers@git.planet-lab.org/git/sfa
[sfa.git] / sfa / client / sfi.py
index 233f3a6..6e0c82c 100755 (executable)
@@ -15,7 +15,7 @@ from lxml import etree
 from StringIO import StringIO
 from types import StringTypes, ListType
 from optparse import OptionParser
-from sfa.util.sfalogging import sfa_logger,sfa_logger_goes_to_console
+from sfa.util.sfalogging import sfi_logger
 from sfa.trust.certificate import Keypair, Certificate
 from sfa.trust.gid import GID
 from sfa.trust.credential import Credential
@@ -26,6 +26,8 @@ import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 from sfa.util.config import Config
 from sfa.util.version import version_core
 from sfa.util.cache import Cache
+from sfa.rspecs.rspec_version import RSpecVersion
+from sfa.rspecs.pg_rspec import pg_rspec_request_version
 
 AGGREGATE_PORT=12346
 CM_PORT=12346
@@ -141,8 +143,8 @@ class Sfi:
         self.user = None
         self.authority = None
         self.hashrequest = False
-        sfa_logger_goes_to_console()
-        self.logger=sfa_logger()
+        self.logger = sfi_logger
+        self.logger.enable_console()
    
     def create_cmd_parser(self, command, additional_cmdargs=None):
         cmdargs = {"list": "authority",
@@ -273,6 +275,8 @@ class Sfi:
         parser.add_option("-k", "--hashrequest",
                          action="store_true", dest="hashrequest", default=False,
                          help="Create a hash of the request that will be authenticated on the server")
+        parser.add_option("-t", "--timeout", dest="timeout", default=30,
+                         help="Amout of time tom wait before timing out the request")
         parser.disable_interspersed_args()
 
         return parser
@@ -345,13 +349,11 @@ class Sfi:
        self.key = Keypair(filename=key_file) 
        self.key_file = key_file
        self.cert_file = cert_file
-       self.cert = GID(filename=cert_file) 
-       # Establish connection to server(s)
+       self.cert = GID(filename=cert_file)
        self.logger.info("Contacting Registry at: %s"%self.reg_url)
-       self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)  
+       self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)  
        self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
-       self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, self.options)
-
+       self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
        return
 
     def get_cached_server_version(self, server):
@@ -373,6 +375,8 @@ class Sfi:
             version = server.GetVersion()
             # cache version for 24 hours
             cache.add(cache_key, version, ttl= 60*60*24)
+            self.logger.info("Updating cache file %s" % cache_file)
+            cache.save_to_file(cache_file)
 
 
         return version   
@@ -436,19 +440,20 @@ class Sfi:
         cert.sign()
         self.logger.info("Writing self-signed certificate to %s"%cert_file)
         cert.save_to_file(cert_file)
+        self.cert = cert
         # try to get registry issued cert
         try:
             self.logger.info("Getting Registry issued cert")
             self.read_config()
             # *hack.  need to set registyr before _get_gid() is called 
-            self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, self.options)
+            self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
             gid = self._get_gid(type='user')
             self.registry = None 
             self.logger.info("Writing certificate to %s"%cert_file)
             gid.save_to_file(cert_file)
         except:
             self.logger.info("Failed to download Registry issued cert")
+
         return cert_file
 
     def get_cached_gid(self, file):
@@ -481,18 +486,23 @@ class Sfi:
             hrn = self.user
  
         gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
+        print gidfile
         gid = self.get_cached_gid(gidfile)
         if not gid:
             user_cred = self.get_user_cred()
             records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
-            record = None
+            if not records:
+                raise RecordNotFound(args[0])
+            record = records[0]
             if type:
+                record=None
                 for rec in records:
-                   if type == record['type']:
+                   if type == rec['type']:
                         record = rec 
             if not record:
                 raise RecordNotFound(args[0])
-            gid = GID(string=records[0]['gid'])
+            
+            gid = GID(string=record['gid'])
             self.logger.info("Writing gid to %s"%gidfile)
             gid.save_to_file(filename=gidfile)
         return gid   
@@ -610,7 +620,7 @@ class Sfi:
         host_parts = host.split('/')
         host_parts[0] = host_parts[0] + ":" + str(port)
         url =  "http://%s" %  "/".join(host_parts)    
-        return xmlrpcprotocol.get_server(url, keyfile, certfile, self.options)
+        return xmlrpcprotocol.get_server(url, keyfile, certfile, timeout=self.options.timeout, verbose=self.options.debug)
 
     # xxx opts could be retrieved in self.options
     def get_server_from_opts(self, opts):
@@ -804,6 +814,8 @@ class Sfi:
         """ 
         trusted_certs = self.registry.get_trusted_certs()
         for trusted_cert in trusted_certs:
+            gid = GID(string=trusted_cert)
+            gid.dump()
             cert = Certificate(string=trusted_cert)
             self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
         return 
@@ -886,7 +898,14 @@ class Sfi:
             delegated_cred = self.delegate_cred(cred, get_authority(self.authority))
             creds.append(delegated_cred)
         if opts.rspec_version:
-            call_options['rspec_version'] = opts.rspec_version 
+            server_version = self.get_cached_server_version(server)
+            if 'sfa' in server_version:
+                # just request the version the client wants 
+                call_options['rspec_version'] = dict(RSpecVersion(opts.rspec_version)) 
+            else:
+                # this must be a protogeni aggregate. We should request a v2 ad rspec
+                # regardless of what the client user requested 
+                call_options['rspec_version'] = dict(pg_rspec_request_version)     
         #panos add info options
         if opts.info:
             call_options['info'] = opts.info 
@@ -924,7 +943,7 @@ class Sfi:
         #  }]
         users = []
         server = self.get_server_from_opts(opts)
-        version = server.GetVersion()
+        version = self.get_cached_server_version(server)
         if 'sfa' not in version:
             # need to pass along user keys if this request is going to a ProtoGENI aggregate 
             # ProtoGeni Aggregates will only install the keys of the user that is issuing the
@@ -1123,13 +1142,12 @@ class Sfi:
         (cmd_opts, cmd_args) = self.cmd_parser.parse_args(args[1:])
 
         self.set_servers()
-    
         self.logger.info("Command=%s" % command)
         if command in ("resources"):
             self.logger.debug("resources cmd_opts %s" % cmd_opts.format)
         elif command in ("list", "show", "remove"):
             self.logger.debug("cmd_opts.type %s" % cmd_opts.type)
-        self.logger.debug('cmd_args %s',cmd_args)
+        self.logger.debug('cmd_args %s' % cmd_args)
 
         try:
             self.dispatch(command, cmd_opts, cmd_args)