source: fedd/fedd_client.py @ 5576a47

axis_examplecompt_changesinfo-opsversion-1.30version-2.00version-3.01version-3.02
Last change on this file since 5576a47 was 5576a47, checked in by Ted Faber <faber@…>, 15 years ago

project exporting in place

  • Property mode set to 100755
File size: 22.3 KB
RevLine 
[6ff0b91]1#!/usr/local/bin/python
2
3import sys
4import os
5import pwd
6
7from fedd_services import *
[f4f4117]8from fedd_internal_services import *
[6ff0b91]9
10from M2Crypto import SSL, X509
[329f61d]11from M2Crypto.m2xmlrpclib import SSL_Transport
[6ff0b91]12import M2Crypto.httpslib
[329f61d]13
14from xmlrpclib import ServerProxy, Error, dumps, loads
[bb3769a]15from ZSI.TC import QName, String, URI, AnyElement, UNBOUNDED, Any
16from ZSI.wstools.Namespaces import SOAP
17from ZSI.fault import FaultType, Detail
[6ff0b91]18
[2d58549]19import xmlrpclib
20
[51cc9df]21from fedd_util import fedd_ssl_context, pack_id, unpack_id
22from fedid import fedid
[9460b1e]23from remote_service import service_caller
[058f58e]24from service_error import *
[6ff0b91]25
26from optparse import OptionParser, OptionValueError
27
[bb3769a]28import parse_detail
29
[6ff0b91]30# Turn off the matching of hostname to certificate ID
31SSL.Connection.clientPostConnectionCheck = None
32
33class IDFormatException(RuntimeError): pass
34
35class access_method:
36    """Encapsulates an access method generically."""
37    (type_ssh, type_x509, type_pgp) = ('sshPubkey', 'X509', 'pgpPubkey')
38    default_type = type_ssh
39    def __init__(self, buf=None, type=None, file=None):
40        self.buf = buf
41
42        if type != None: self.type = type
43        else: self.type = access_method.default_type
44
45        if file != None:
46            self.readfile(file)
47   
48    def readfile(self, file, type=None):
49        f = open(file, "r")
50        self.buf = f.read();
51        f.close()
52        if type == None:
53            if self.type == None:
54                self.type = access_method.default_type
55        else:
56            self.type = type;
57   
58class node_desc:
59    def __init__(self, image, hardware, count=1):
60        if getattr(image, "__iter__", None) == None:
61            if image == None: self.image = [ ]
62            else: self.image = [ image ]
63        else:
64            self.image = image
65
66        if getattr(hardware, "__iter__", None) == None: 
67            if hardware == None: self.hardware = [ ]
68            else: self.hardware = [ hardware ]
69        else:
70            self.hardware = hardware
71        if count != None: self.count = int(count)
72        else: self.count = 1
73
74class fedd_client_opts(OptionParser):
75    """Encapsulate option processing in this class, rather than in main"""
76    def __init__(self):
77        OptionParser.__init__(self, usage="%prog [opts] (--help for details)",
78                version="0.1")
79
80        self.add_option("-c","--cert", action="store", dest="cert",
81                type="string", help="my certificate file")
82        self.add_option("-d", "--debug", action="count", dest="debug", 
[03e0290]83                default=0, help="Set debug.  Repeat for more information")
[8f91e66]84        self.add_option("-s", "--serializeOnly", action="store_true", 
[03e0290]85                dest="serialize_only", default=False,
[8f91e66]86                help="Print the SOAP request that would be sent and exit")
[6ff0b91]87        self.add_option("-T","--trusted", action="store", dest="trusted",
88                type="string", help="Trusted certificates (required)")
89        self.add_option("-u", "--url", action="store", dest="url",
[03e0290]90                type="string",default="https://localhost:23235", 
[6ff0b91]91                help="URL to connect to (default %default)")
[329f61d]92        self.add_option("-x","--transport", action="store", type="choice",
[03e0290]93                choices=("xmlrpc", "soap"), default="soap",
[329f61d]94                help="Transport for request (xmlrpc|soap) (Default: %default)")
[6ff0b91]95        self.add_option("--trace", action="store_const", dest="tracefile", 
96                const=sys.stderr, help="Print SOAP exchange to stderr")
97
[03e0290]98class fedd_create_opts(fedd_client_opts):
99    def __init__(self, access_keys, add_key_callback=None, 
100            add_cert_callback=None):
101        fedd_client_opts.__init__(self)
102        self.add_option("-e", "--experiment_cert", dest="out_certfile",
103                type="string", help="output certificate file")
[e40c7ee]104        self.add_option("-E", "--experiment_name", dest="exp_name",
105                type="string", help="output certificate file")
[03e0290]106        self.add_option("-F","--useFedid", action="store_true",
107                dest="use_fedid", default=False,
108                help="Use a fedid derived from my certificate as user identity")
109        self.add_option("-f", "--file", dest="file", 
110                help="experiment description file")
[5576a47]111        self.add_option("-p", "--project", action="store", dest="project", 
112                type="string",
113                help="Project to export from master")
[03e0290]114        if add_key_callback:
115            self.add_option("-k", "--sshKey", action="callback", type="string", 
116                    callback=add_key_callback, callback_args=(access_keys,),
117                    help="ssh key for access (can be supplied more than once")
118        if add_cert_callback:
119            self.add_option("-K", "--x509Key", action="callback",
120                    type="string", callback=add_cert_callback,
121                    callback_args=(access_keys,),
122                    help="X509 certificate for access " + \
123                        "(can be supplied more than once")
124        self.add_option("-m", "--master", dest="master",
125                help="Master testbed in the federation")
126        self.add_option("-U", "--username", action="store", dest="user",
127                type="string", help="Use this username instead of the uid")
[6ff0b91]128
[2c6128f]129class fedd_split_opts(fedd_create_opts):
130    def __init__(self, access_keys, add_key_callback=None, 
131            add_cert_callback=None):
132        fedd_create_opts.__init__(self, access_keys, add_key_callback,
133                add_cert_callback)
134        self.add_option('-t','--fedkit', action='store_true', dest='fedkit',
135                default=False,
136                help="get output suitable for federation kit install")
137
138
[03e0290]139class fedd_access_opts(fedd_create_opts):
140    def __init__(self, access_keys, node_descs, add_key_callback=None, 
141            add_cert_callback=None, add_node_callback=None):
142        fedd_create_opts.__init__(self, access_keys, add_key_callback,
143                add_cert_callback)
144        self.add_option("-a","--anonymous", action="store_true",
145                dest="anonymous", default=False,
146                help="Do not include a user in the request")
147        self.add_option("-l","--label", action="store", dest="label",
148                type="string", help="Label for output")
149        if add_node_callback:
150            self.add_option("-n", "--node", action="callback", type="string", 
151                    callback=add_node_callback, callback_args=(node_descs,),
152                    help="Node description: image:hardware[:count]")
153        self.add_option("-p", "--project", action="store", dest="project", 
154                type="string",
155                help="Use a project request with this project name")
156        self.add_option("-t", "--testbed", action="store", dest="testbed",
157                type="string",
158                help="Testbed identifier (URI) to contact (required)")
[6ff0b91]159
[e40c7ee]160class fedd_exp_data_opts(fedd_client_opts):
161    def __init__(self):
162        fedd_client_opts.__init__(self)
163        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
164                type="string", help="output certificate file")
165        self.add_option("-E", "--experiment_name", dest="exp_name",
166                type="string", help="output certificate file")
167
[0c0b13c]168def exit_with_fault(dict, out=sys.stderr):
169    """ Print an error message and exit.
170
[2d5c8b6]171    The dictionary contains the FeddFaultBody elements."""
[0c0b13c]172    codestr = ""
173
174    if dict.has_key('errstr'):
175        codestr = "Error: %s" % dict['errstr']
176
177    if dict.has_key('code'):
178        if len(codestr) > 0 : 
179            codestr += " (%d)" % dict['code']
180        else:
181            codestr = "Error Code: %d" % dict['code']
182
183    print>>out, codestr
184    print>>out, "Description: %s" % dict['desc']
185    sys.exit(dict.get('code', 20))
[03e0290]186# Base class that will do a the SOAP/XMLRPC exchange for a request.
187class fedd_rpc:
188    class RPCException:
189        def __init__(self, fb):
190            self.desc = fb.get('desc', None)
[e40c7ee]191            self.code = fb.get('code', -1)
[03e0290]192            self.errstr = fb.get('errstr', None)
193
194    def __init__(self, pre): 
195        """
[058f58e]196        Specialize the class for the pre method
[03e0290]197        """
198        self.RequestMessage = globals()["%sRequestMessage" % pre]
199        self.ResponseMessage = globals()["%sResponseMessage" % pre]
200        self.RequestBody="%sRequestBody" % pre
201        self.ResponseBody="%sResponseBody" % pre
202        self.method = pre
[058f58e]203
204        method_call = getattr(feddServiceLocator().getfeddPortType(),
205                self.method, None)
206        if method_call:
207            # The pre method is a fedd external service
208            self.caller = service_caller(self.method, 'getfeddPortType', 
209                    feddServiceLocator, self.RequestMessage, self.RequestBody)
210        else:
211            # The pre method is a fedd internal service
212            self.caller = service_caller(self.method, 
213                    'getfeddInternalPortType', feddInternalServiceLocator,
214                    self.RequestMessage, self.RequestBody)
215
[03e0290]216        self.RPCException = fedd_rpc.RPCException
217
218
219    def add_ssh_key(self, option, opt_str, value, parser, access_keys):
220        try:
221            access_keys.append(access_method(file=value,
222                type=access_method.type_ssh))
223        except IOError, (errno, strerror):
224            raise OptionValueError("Cannot generate sshPubkey from %s: "\
225                    "%s (%d)" % (value,strerror,errno))
226
227    def add_x509_cert(self, option, opt_str, value, parser, access_keys):
228        try:
229            access_keys.append(access_method(file=value,
230                type=access_method.type_x509))
231        except IOError, (errno, strerror):
232            raise OptionValueError("Cannot read x509 cert from %s: %s (%d)" %
233                    (value,strerror,errno))
234    def add_node_desc(self, option, opt_str, value, parser, node_descs):
235        def none_if_zero(x):
236            if len(x) > 0: return x
237            else: return None
238
239        params = map(none_if_zero, value.split(":"));
240       
241        if len(params) < 4 and len(params) > 1:
242            node_descs.append(node_desc(*params))
243        else:
244            raise OptionValueError("Bad node description: %s" % value)
245
246    def get_user_info(self, access_keys):
247        pw = pwd.getpwuid(os.getuid());
248        try_cert=None
249        user = None
250
251        if pw != None:
252            user = pw[0]
253            try_cert = "%s/.ssl/emulab.pem" % pw[5];
254            if not os.access(try_cert, os.R_OK):
255                try_cert = None
256            if len(access_keys) == 0:
257                for k in ["%s/.ssh/id_rsa.pub", "%s/.ssh/id_dsa.pub", 
258                        "%s/.ssh/identity.pub"]:
259                    try_key = k % pw[5];
260                    if os.access(try_key, os.R_OK):
261                        access_keys.append(access_method(file=try_key,
262                            type=access_method.type_ssh))
263                        break
264        return (user, try_cert)
265
266    def do_rpc(self, req_dict, url, transport, cert, trusted, tracefile=None,
267            serialize_only=False):
268        """
269        The work of sending and parsing the RPC as either XMLRPC or SOAP
270        """
271
272        context = None
273        while context == None:
274            try:
275                context = fedd_ssl_context(cert, trusted)
276            except SSL.SSLError, e:
277                # Yes, doing this on message type is not ideal.  The string
278                # comes from OpenSSL, so check there is this stops working.
279                if str(e) == "bad decrypt": 
280                    print >>sys.stderr, "Bad Passphrase given."
281                else: raise
282
283        if transport == "soap":
284            if serialize_only:
[a94cb0a]285                print self.caller.serialize_soap(req_dict) 
[03e0290]286                sys.exit(0)
[058f58e]287            else:
288                try:
289                    resp = self.caller.call_soap_service(url, req_dict, 
290                            context=context, tracefile=tracefile)
291                except service_error, e:
[cfabc40]292                    raise self.RPCException( {\
293                            'code': e.code, 
294                            'desc': e.desc, 
295                            'errstr': e.code_string()\
296                        })
[03e0290]297        elif transport == "xmlrpc":
298            if serialize_only:
299                ser = dumps((req_dict,))
300                print ser
301                sys.exit(0)
[058f58e]302            else:
303                try:
304                    resp = self.caller.call_xmlrpc_service(url, req_dict, 
305                            context=context, tracefile=tracefile)
306                except service_error, e:
[cfabc40]307                    raise self.RPCException( {\
308                            'code': e.code, 
309                            'desc': e.desc, 
310                            'errstr': e.code_string()\
311                        })
[03e0290]312
313        else:
314            raise RuntimeError("Unknown RPC transport: %s" % transport)
315
[058f58e]316        if resp.has_key(self.ResponseBody):
317            return resp[self.ResponseBody]
318        else:
319            raise RuntimeError("No body in response??")
320
[03e0290]321# Querying experiment data follows the same control flow regardless of the
322# specific data retrieved.  This class encapsulates that control flow.
323class exp_data(fedd_rpc):
324    def __init__(self, op): 
325        """
326        Specialize the class for the type of data requested (op)
327        """
328
329        fedd_rpc.__init__(self, op)
330        if op =='Vtopo':
331            self.key="vtopo"
332            self.xml='experiment'
333        elif op == 'Vis':
334            self.key="vis"
335            self.xml='vis'
[c52c48d]336        elif op == 'Info': pass
[03e0290]337        else:
338            raise TypeError("Bad op: %s" % op)
339
340    def print_xml(self, d, out=sys.stdout):
341        """
342        Print the retrieved data is a simple xml representation of the dict.
343        """
344        str = "<%s>\n" % self.xml
345        for t in ('node', 'lan'):
346            if d.has_key(t): 
347                for x in d[t]:
348                    str += "<%s>" % t
349                    for k in x.keys():
350                        str += "<%s>%s</%s>" % (k, x[k],k)
351                    str += "</%s>\n" % t
352        str+= "</%s>" % self.xml
353        print >>out, str
354
355    def __call__(self):
356        """
357        The control flow.  Compose the request and print the response.
358        """
359        # Process the options using the customized option parser defined above
360        parser = fedd_exp_data_opts()
361
362        (opts, args) = parser.parse_args()
363
364        if opts.trusted != None:
365            if ( not os.access(opts.trusted, os.R_OK) ) :
366                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
367        else:
368            parser.error("--trusted is required")
[6ff0b91]369
[03e0290]370        if opts.debug > 0: opts.tracefile=sys.stderr
[6ff0b91]371
[03e0290]372        if opts.cert != None: cert = opts.cert
[6ff0b91]373
[03e0290]374        if cert == None:
375            sys.exit("No certificate given (--cert) or found")
[6ff0b91]376
[03e0290]377        if os.access(cert, os.R_OK):
378            fid = fedid(file=cert)
379        else:
380            sys.exit("Cannot read certificate (%s)" % cert)
381
[e40c7ee]382        if opts.exp_name and opts.exp_certfile:
383            sys.exit("Only one of --experiment_cert and " +\
384                    "--experiment_name permitted");
385
[03e0290]386        if opts.exp_certfile:
[e40c7ee]387            exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
388
389        if opts.exp_name:
390            exp_id = { 'localname' : opts.exp_name }
391
392        req = { 'experiment': exp_id }
[03e0290]393
394        try:
[e40c7ee]395            resp_dict = self.do_rpc(req,
[03e0290]396                    opts.url, opts.transport, cert, opts.trusted, 
397                    serialize_only=opts.serialize_only,
398                    tracefile=opts.tracefile)
399        except self.RPCException, e:
400            exit_with_fault(\
401                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
402        except RuntimeError, e:
[e40c7ee]403            print e
404            sys.exit("Error processing RPC: %s" % e)
[03e0290]405
[c52c48d]406        if getattr(self, 'key', None):
407            try:
408                if resp_dict.has_key(self.key):
409                    self.print_xml(resp_dict[self.key])
410            except RuntimeError, e:
411                sys.exit("Bad response. %s" % e.message)
412        else:
413            print resp_dict
[03e0290]414
[7a8d667]415class terminate(fedd_rpc):
416    def __init__(self): 
417        """
418        Termination request
419        """
420
421        fedd_rpc.__init__(self, "Terminate")
422
423    def __call__(self):
424        """
425        The control flow.  Compose the request and print the response.
426        """
427        # Process the options using the customized option parser defined above
428        parser = fedd_exp_data_opts()
429
430        (opts, args) = parser.parse_args()
431
432        if opts.trusted != None:
433            if ( not os.access(opts.trusted, os.R_OK) ) :
434                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
435        else:
436            parser.error("--trusted is required")
437
438        if opts.debug > 0: opts.tracefile=sys.stderr
439
440        if opts.cert != None: cert = opts.cert
441
442        if cert == None:
443            sys.exit("No certificate given (--cert) or found")
444
445        if os.access(cert, os.R_OK):
446            fid = fedid(file=cert)
447        else:
448            sys.exit("Cannot read certificate (%s)" % cert)
449
450        if opts.exp_name and opts.exp_certfile:
451            sys.exit("Only one of --experiment_cert and " +\
452                    "--experiment_name permitted");
453
454        if opts.exp_certfile:
455            exp_id = { 'fedid': fedid(file=opts.exp_certfile) }
456
457        if opts.exp_name:
458            exp_id = { 'localname' : opts.exp_name }
459
460        req = { 'experiment': exp_id }
461
462        try:
463            resp_dict = self.do_rpc(req,
464                    opts.url, opts.transport, cert, opts.trusted, 
465                    serialize_only=opts.serialize_only,
466                    tracefile=opts.tracefile)
467        except self.RPCException, e:
468            exit_with_fault(\
469                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
470        except RuntimeError, e:
471            print e
472            sys.exit("Error processing RPC: %s" % e)
473
474        eid = resp_dict.get('experimentID', None)
475        if eid:
476            for id in eid:
477                for k in id.keys():
478                    if k == 'fedid': print "%s: %s" % (k,fedid(bits=id[k]))
479                    else: print "%s: %s" % (k, id[k])
480
[03e0290]481class create(fedd_rpc):
482    def __init__(self): 
483        fedd_rpc.__init__(self, "Create")
484    def __call__(self):
485        access_keys = []
486        # Process the options using the customized option parser defined above
487        parser = fedd_create_opts(access_keys, self.add_ssh_key,
488                self.add_x509_cert)
489
490        (opts, args) = parser.parse_args()
491
492        if opts.trusted != None:
493            if ( not os.access(opts.trusted, os.R_OK) ) :
494                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
495        else:
496            parser.error("--trusted is required")
497
[5576a47]498        if not opts.project :
499            parser.error('--project is required')
500
[03e0290]501        if opts.debug > 0: opts.tracefile=sys.stderr
502
503        (user, cert) = self.get_user_info(access_keys)
504
505        if opts.user: user = opts.user
506
507        if opts.cert != None: cert = opts.cert
508
509        if cert == None:
510            sys.exit("No certificate given (--cert) or found")
511
512        if os.access(cert, os.R_OK):
513            fid = fedid(file=cert)
514            if opts.use_fedid == True:
515                user = fid
516        else:
517            sys.exit("Cannot read certificate (%s)" % cert)
518
519        if opts.file:
520            exp_desc = ""
521            try:
522                f = open(opts.file, 'r')
523                for line in f:
524                    exp_desc += line
525                f.close()
526            except IOError:
527                sys.exit("Cannot read description file (%s)" %opts.file)
528        else:
529            sys.exit("Must specify an experiment description (--file)")
530
531        if not opts.master:
532            sys.exit("Must specify a master testbed (--master)")
533
534        out_certfile = opts.out_certfile
535
536        msg = {
[3925b50]537                'experimentdescription': { 'ns2description': exp_desc },
[03e0290]538                'master': opts.master,
[5576a47]539                'exportProject': { 'localname': opts.project },
[03e0290]540                'user' : [ {\
541                        'userID': pack_id(user), \
542                        'access': [ { a.type: a.buf } for a in access_keys]\
543                        } ]
[6ff0b91]544                }
[03e0290]545
[e40c7ee]546        if opts.exp_name:
547            msg['experimentID'] = { 'localname': opts.exp_name }
548
[03e0290]549        if opts.debug > 1: print >>sys.stderr, msg
550
551        try:
552            resp_dict = self.do_rpc(msg, 
553                    opts.url, opts.transport, cert, opts.trusted, 
554                    serialize_only=opts.serialize_only,
555                    tracefile=opts.tracefile)
556        except self.RPCException, e:
557            exit_with_fault(\
558                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
559        except RuntimeError, e:
[0b466d1]560            sys.exit("Error processing RPC: %s" % e)
[03e0290]561
562        if opts.debug > 1: print >>sys.stderr, resp_dict
563
564        ea = resp_dict.get('experimentAccess', None)
565        if out_certfile and ea and ea.has_key('X509'):
[0c0b13c]566            try:
[03e0290]567                f = open(out_certfile, "w")
568                print >>f, ea['X509']
569                f.close()
570            except IOError:
571                sys.exit('Could not write to %s' %  out_certfile)
[e40c7ee]572        eid = resp_dict.get('experimentID', None)
573        if eid:
574            for id in eid:
575                for k in id.keys():
[058f58e]576                    print "%s: %s" % (k, id[k])
[03e0290]577
[f4f4117]578class split(fedd_rpc):
579    def __init__(self): 
580        fedd_rpc.__init__(self, "Ns2Split")
581    def __call__(self):
582        access_keys = []
583        # Process the options using the customized option parser defined above
[2c6128f]584        parser = fedd_split_opts(access_keys, self.add_ssh_key,
[f4f4117]585                self.add_x509_cert)
586
587        (opts, args) = parser.parse_args()
588
589        if opts.trusted != None:
590            if ( not os.access(opts.trusted, os.R_OK) ) :
591                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
592        else:
593            parser.error("--trusted is required")
594
595        if opts.debug > 0: opts.tracefile=sys.stderr
596
597        if opts.cert != None: cert = opts.cert
[2c6128f]598        else: cert = None
[f4f4117]599
600        if cert == None:
601            sys.exit("No certificate given (--cert) or found")
602
603        if os.access(cert, os.R_OK):
604            fid = fedid(file=cert)
605            if opts.use_fedid == True:
606                user = fid
607        else:
608            sys.exit("Cannot read certificate (%s)" % cert)
609
610        if opts.file:
611            exp_desc = ""
612            try:
613                f = open(opts.file, 'r')
614                for line in f:
615                    exp_desc += line
616                f.close()
617            except IOError:
618                sys.exit("Cannot read description file (%s)" %opts.file)
619        else:
620            sys.exit("Must specify an experiment description (--file)")
621
622        if not opts.master:
623            sys.exit("Must specify a master testbed (--master)")
624
625        out_certfile = opts.out_certfile
626
627        msg = {
628                'description': { 'ns2description': exp_desc },
629                'master': opts.master,
[2c6128f]630                'include_fedkit': opts.fedkit,
[f4f4117]631                }
632
633        if opts.debug > 1: print >>sys.stderr, msg
634
635        try:
636            resp_dict = self.do_rpc(msg, 
637                    opts.url, opts.transport, cert, opts.trusted, 
638                    serialize_only=opts.serialize_only,
639                    tracefile=opts.tracefile)
640        except self.RPCException, e:
641            exit_with_fault(\
642                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
643        except RuntimeError, e:
644            sys.exit("Error processing RPC: %s" % e)
645
646        if opts.debug > 1: print >>sys.stderr, resp_dict
647
648        out = resp_dict.get('output', None)
649
650        for line in out.splitlines():
651            print "%s" % line
652
[03e0290]653class access(fedd_rpc):
654    def __init__(self):
655        fedd_rpc.__init__(self, "RequestAccess")
656
657    def print_response_as_testbed(self, resp, label, out=sys.stdout):
658        """Print the response as input to the splitter script"""
659
660        e = resp['emulab']
661        p = e['project']
662        fields = { 
663                "Boss": e['boss'],
664                "OpsNode": e['ops'],
665                "Domain": e['domain'],
666                "FileServer": e['fileServer'],
667                "EventServer": e['eventServer'],
668                "Project": unpack_id(p['name'])
669                }
670        if (label != None): print >> out, "[%s]" % label
671
672        for l, v in fields.iteritems():
673            print >>out, "%s: %s" % (l, v)
674
675        for u in p['user']:
676            print >>out, "User: %s" % unpack_id(u['userID'])
677
678        for a in e['fedAttr']:
679            print >>out, "%s: %s" % (a['attribute'], a['value'])
680
681    def __call__(self):
682        access_keys = []
683        node_descs = []
684        proj = None
685
686        # Process the options using the customized option parser defined above
687        parser = fedd_access_opts(access_keys, node_descs, self.add_ssh_key,
688                self.add_x509_cert, self.add_node_desc)
689
690        (opts, args) = parser.parse_args()
691
692        if opts.testbed == None:
693            parser.error("--testbed is required")
694
695        if opts.trusted != None:
696            if ( not os.access(opts.trusted, os.R_OK) ) :
697                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
698        else:
699            parser.error("--trusted is required")
700
701        if opts.debug > 0: opts.tracefile=sys.stderr
702
703        (user, cert) = self.get_user_info(access_keys)
704
705        if opts.user: user = opts.user
706
707        if opts.cert != None: cert = opts.cert
708
709        if cert == None:
710            sys.exit("No certificate given (--cert) or found")
711
712        if os.access(cert, os.R_OK):
713            fid = fedid(file=cert)
714            if opts.use_fedid == True:
715                user = fid
716        else:
717            sys.exit("Cannot read certificate (%s)" % cert)
718
719        msg = {
720                'allocID': pack_id('test alloc'),
721                'destinationTestbed': pack_id(opts.testbed),
[72ed6e4]722                'serviceAccess' : [ { a.type: a.buf } for a in access_keys ],
723                'createAccess' : [ { a.type: a.buf } for a in access_keys ],
[03e0290]724                }
725
726        if len(node_descs) > 0:
727            msg['resources'] = { 
728                    'node': [ 
729                        { 
730                            'image':  n.image ,
731                            'hardware':  n.hardware,
732                            'count': n.count,
733                        } for n in node_descs],
734                    }
735
736        if opts.project != None:
737            if not opts.anonymous and user != None:
738                msg['project'] = {
739                        'name': pack_id(opts.project),
740                        'user': [ { 'userID': pack_id(user) } ],
741                        }
742            else:
743                msg['project'] = { 'name': pack_id(opts.project) }
744        else:
745            if not opts.anonymous and user != None:
746                msg['user'] = [ { 'userID': pack_id(user) } ]
747            else:
748                msg['user'] = [];
749
750        if opts.debug > 1: print >>sys.stderr, msg
751
752        try:
753            resp_dict = self.do_rpc(msg, 
754                    opts.url, opts.transport, cert, opts.trusted, 
755                    serialize_only=opts.serialize_only,
756                    tracefile=opts.tracefile)
757        except self.RPCException, e:
758            exit_with_fault(\
759                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
760        except RuntimeError, e:
761            sys.exit("Error processing RPC: %s" % e.message)
762
763        if opts.debug > 1: print >>sys.stderr, resp_dict
764        self.print_response_as_testbed(resp_dict, opts.label)
765
766cmds = {\
767        'create': create(),\
[f4f4117]768        'split': split(),\
[03e0290]769        'access': access(),\
770        'vtopo': exp_data('Vtopo'),\
771        'vis': exp_data('Vis'),\
[c52c48d]772        'info': exp_data('Info'),\
[7a8d667]773        'terminate': terminate(),\
[03e0290]774    }
775
776operation = cmds.get(sys.argv[1], None)
777if operation:
778    del sys.argv[1]
779    operation()
780else:
781    sys.exit("Bad command: %s.  Valid ones are: %s" % \
782            (sys.argv[1], ", ".join(cmds.keys())))
783
Note: See TracBrowser for help on using the repository browser.