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
Line 
1#!/usr/local/bin/python
2
3import sys
4import os
5import pwd
6
7from fedd_services import *
8from fedd_internal_services import *
9
10from M2Crypto import SSL, X509
11from M2Crypto.m2xmlrpclib import SSL_Transport
12import M2Crypto.httpslib
13
14from xmlrpclib import ServerProxy, Error, dumps, loads
15from ZSI.TC import QName, String, URI, AnyElement, UNBOUNDED, Any
16from ZSI.wstools.Namespaces import SOAP
17from ZSI.fault import FaultType, Detail
18
19import xmlrpclib
20
21from fedd_util import fedd_ssl_context, pack_id, unpack_id
22from fedid import fedid
23from remote_service import service_caller
24from service_error import *
25
26from optparse import OptionParser, OptionValueError
27
28import parse_detail
29
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", 
83                default=0, help="Set debug.  Repeat for more information")
84        self.add_option("-s", "--serializeOnly", action="store_true", 
85                dest="serialize_only", default=False,
86                help="Print the SOAP request that would be sent and exit")
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",
90                type="string",default="https://localhost:23235", 
91                help="URL to connect to (default %default)")
92        self.add_option("-x","--transport", action="store", type="choice",
93                choices=("xmlrpc", "soap"), default="soap",
94                help="Transport for request (xmlrpc|soap) (Default: %default)")
95        self.add_option("--trace", action="store_const", dest="tracefile", 
96                const=sys.stderr, help="Print SOAP exchange to stderr")
97
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")
104        self.add_option("-E", "--experiment_name", dest="exp_name",
105                type="string", help="output certificate file")
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")
111        self.add_option("-p", "--project", action="store", dest="project", 
112                type="string",
113                help="Project to export from master")
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")
128
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
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)")
159
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
168def exit_with_fault(dict, out=sys.stderr):
169    """ Print an error message and exit.
170
171    The dictionary contains the FeddFaultBody elements."""
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))
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)
191            self.code = fb.get('code', -1)
192            self.errstr = fb.get('errstr', None)
193
194    def __init__(self, pre): 
195        """
196        Specialize the class for the pre method
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
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
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:
285                print self.caller.serialize_soap(req_dict) 
286                sys.exit(0)
287            else:
288                try:
289                    resp = self.caller.call_soap_service(url, req_dict, 
290                            context=context, tracefile=tracefile)
291                except service_error, e:
292                    raise self.RPCException( {\
293                            'code': e.code, 
294                            'desc': e.desc, 
295                            'errstr': e.code_string()\
296                        })
297        elif transport == "xmlrpc":
298            if serialize_only:
299                ser = dumps((req_dict,))
300                print ser
301                sys.exit(0)
302            else:
303                try:
304                    resp = self.caller.call_xmlrpc_service(url, req_dict, 
305                            context=context, tracefile=tracefile)
306                except service_error, e:
307                    raise self.RPCException( {\
308                            'code': e.code, 
309                            'desc': e.desc, 
310                            'errstr': e.code_string()\
311                        })
312
313        else:
314            raise RuntimeError("Unknown RPC transport: %s" % transport)
315
316        if resp.has_key(self.ResponseBody):
317            return resp[self.ResponseBody]
318        else:
319            raise RuntimeError("No body in response??")
320
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'
336        elif op == 'Info': pass
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")
369
370        if opts.debug > 0: opts.tracefile=sys.stderr
371
372        if opts.cert != None: cert = opts.cert
373
374        if cert == None:
375            sys.exit("No certificate given (--cert) or found")
376
377        if os.access(cert, os.R_OK):
378            fid = fedid(file=cert)
379        else:
380            sys.exit("Cannot read certificate (%s)" % cert)
381
382        if opts.exp_name and opts.exp_certfile:
383            sys.exit("Only one of --experiment_cert and " +\
384                    "--experiment_name permitted");
385
386        if opts.exp_certfile:
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 }
393
394        try:
395            resp_dict = self.do_rpc(req,
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:
403            print e
404            sys.exit("Error processing RPC: %s" % e)
405
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
414
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
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
498        if not opts.project :
499            parser.error('--project is required')
500
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 = {
537                'experimentdescription': { 'ns2description': exp_desc },
538                'master': opts.master,
539                'exportProject': { 'localname': opts.project },
540                'user' : [ {\
541                        'userID': pack_id(user), \
542                        'access': [ { a.type: a.buf } for a in access_keys]\
543                        } ]
544                }
545
546        if opts.exp_name:
547            msg['experimentID'] = { 'localname': opts.exp_name }
548
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:
560            sys.exit("Error processing RPC: %s" % e)
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'):
566            try:
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)
572        eid = resp_dict.get('experimentID', None)
573        if eid:
574            for id in eid:
575                for k in id.keys():
576                    print "%s: %s" % (k, id[k])
577
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
584        parser = fedd_split_opts(access_keys, self.add_ssh_key,
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
598        else: cert = None
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,
630                'include_fedkit': opts.fedkit,
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
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),
722                'serviceAccess' : [ { a.type: a.buf } for a in access_keys ],
723                'createAccess' : [ { a.type: a.buf } for a in access_keys ],
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(),\
768        'split': split(),\
769        'access': access(),\
770        'vtopo': exp_data('Vtopo'),\
771        'vis': exp_data('Vis'),\
772        'info': exp_data('Info'),\
773        'terminate': terminate(),\
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.