source: fedd/fedd_client.py @ f8b118e

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

clean up service classes a bit

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