source: fedd/fedd_client.py @ 51cc9df

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

split fedid out

  • 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
[51cc9df]22from fedd_util import fedd_ssl_context, pack_id, unpack_id
23from fedid import fedid
[9460b1e]24from remote_service import service_caller
[058f58e]25from service_error import *
[6ff0b91]26
27from optparse import OptionParser, OptionValueError
28
[bb3769a]29import parse_detail
30
[6ff0b91]31# Turn off the matching of hostname to certificate ID
32SSL.Connection.clientPostConnectionCheck = None
33
34class IDFormatException(RuntimeError): pass
35
36class access_method:
37    """Encapsulates an access method generically."""
38    (type_ssh, type_x509, type_pgp) = ('sshPubkey', 'X509', 'pgpPubkey')
39    default_type = type_ssh
40    def __init__(self, buf=None, type=None, file=None):
41        self.buf = buf
42
43        if type != None: self.type = type
44        else: self.type = access_method.default_type
45
46        if file != None:
47            self.readfile(file)
48   
49    def readfile(self, file, type=None):
50        f = open(file, "r")
51        self.buf = f.read();
52        f.close()
53        if type == None:
54            if self.type == None:
55                self.type = access_method.default_type
56        else:
57            self.type = type;
58   
59class node_desc:
60    def __init__(self, image, hardware, count=1):
61        if getattr(image, "__iter__", None) == None:
62            if image == None: self.image = [ ]
63            else: self.image = [ image ]
64        else:
65            self.image = image
66
67        if getattr(hardware, "__iter__", None) == None: 
68            if hardware == None: self.hardware = [ ]
69            else: self.hardware = [ hardware ]
70        else:
71            self.hardware = hardware
72        if count != None: self.count = int(count)
73        else: self.count = 1
74
75class fedd_client_opts(OptionParser):
76    """Encapsulate option processing in this class, rather than in main"""
77    def __init__(self):
78        OptionParser.__init__(self, usage="%prog [opts] (--help for details)",
79                version="0.1")
80
81        self.add_option("-c","--cert", action="store", dest="cert",
82                type="string", help="my certificate file")
83        self.add_option("-d", "--debug", action="count", dest="debug", 
[03e0290]84                default=0, help="Set debug.  Repeat for more information")
[8f91e66]85        self.add_option("-s", "--serializeOnly", action="store_true", 
[03e0290]86                dest="serialize_only", default=False,
[8f91e66]87                help="Print the SOAP request that would be sent and exit")
[6ff0b91]88        self.add_option("-T","--trusted", action="store", dest="trusted",
89                type="string", help="Trusted certificates (required)")
90        self.add_option("-u", "--url", action="store", dest="url",
[03e0290]91                type="string",default="https://localhost:23235", 
[6ff0b91]92                help="URL to connect to (default %default)")
[329f61d]93        self.add_option("-x","--transport", action="store", type="choice",
[03e0290]94                choices=("xmlrpc", "soap"), default="soap",
[329f61d]95                help="Transport for request (xmlrpc|soap) (Default: %default)")
[6ff0b91]96        self.add_option("--trace", action="store_const", dest="tracefile", 
97                const=sys.stderr, help="Print SOAP exchange to stderr")
98
[03e0290]99class fedd_create_opts(fedd_client_opts):
100    def __init__(self, access_keys, add_key_callback=None, 
101            add_cert_callback=None):
102        fedd_client_opts.__init__(self)
103        self.add_option("-e", "--experiment_cert", dest="out_certfile",
104                type="string", help="output certificate file")
[e40c7ee]105        self.add_option("-E", "--experiment_name", dest="exp_name",
106                type="string", help="output certificate file")
[03e0290]107        self.add_option("-F","--useFedid", action="store_true",
108                dest="use_fedid", default=False,
109                help="Use a fedid derived from my certificate as user identity")
110        self.add_option("-f", "--file", dest="file", 
111                help="experiment description file")
112        if add_key_callback:
113            self.add_option("-k", "--sshKey", action="callback", type="string", 
114                    callback=add_key_callback, callback_args=(access_keys,),
115                    help="ssh key for access (can be supplied more than once")
116        if add_cert_callback:
117            self.add_option("-K", "--x509Key", action="callback",
118                    type="string", callback=add_cert_callback,
119                    callback_args=(access_keys,),
120                    help="X509 certificate for access " + \
121                        "(can be supplied more than once")
122        self.add_option("-m", "--master", dest="master",
123                help="Master testbed in the federation")
124        self.add_option("-U", "--username", action="store", dest="user",
125                type="string", help="Use this username instead of the uid")
[6ff0b91]126
[2c6128f]127class fedd_split_opts(fedd_create_opts):
128    def __init__(self, access_keys, add_key_callback=None, 
129            add_cert_callback=None):
130        fedd_create_opts.__init__(self, access_keys, add_key_callback,
131                add_cert_callback)
132        self.add_option('-t','--fedkit', action='store_true', dest='fedkit',
133                default=False,
134                help="get output suitable for federation kit install")
135
136
[03e0290]137class fedd_access_opts(fedd_create_opts):
138    def __init__(self, access_keys, node_descs, add_key_callback=None, 
139            add_cert_callback=None, add_node_callback=None):
140        fedd_create_opts.__init__(self, access_keys, add_key_callback,
141                add_cert_callback)
142        self.add_option("-a","--anonymous", action="store_true",
143                dest="anonymous", default=False,
144                help="Do not include a user in the request")
145        self.add_option("-l","--label", action="store", dest="label",
146                type="string", help="Label for output")
147        if add_node_callback:
148            self.add_option("-n", "--node", action="callback", type="string", 
149                    callback=add_node_callback, callback_args=(node_descs,),
150                    help="Node description: image:hardware[:count]")
151        self.add_option("-p", "--project", action="store", dest="project", 
152                type="string",
153                help="Use a project request with this project name")
154        self.add_option("-t", "--testbed", action="store", dest="testbed",
155                type="string",
156                help="Testbed identifier (URI) to contact (required)")
[6ff0b91]157
[e40c7ee]158class fedd_exp_data_opts(fedd_client_opts):
159    def __init__(self):
160        fedd_client_opts.__init__(self)
161        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
162                type="string", help="output certificate file")
163        self.add_option("-E", "--experiment_name", dest="exp_name",
164                type="string", help="output certificate file")
165
[0c0b13c]166def exit_with_fault(dict, out=sys.stderr):
167    """ Print an error message and exit.
168
[2d5c8b6]169    The dictionary contains the FeddFaultBody elements."""
[0c0b13c]170    codestr = ""
171
172    if dict.has_key('errstr'):
173        codestr = "Error: %s" % dict['errstr']
174
175    if dict.has_key('code'):
176        if len(codestr) > 0 : 
177            codestr += " (%d)" % dict['code']
178        else:
179            codestr = "Error Code: %d" % dict['code']
180
181    print>>out, codestr
182    print>>out, "Description: %s" % dict['desc']
183    sys.exit(dict.get('code', 20))
[03e0290]184# Base class that will do a the SOAP/XMLRPC exchange for a request.
185class fedd_rpc:
186    class RPCException:
187        def __init__(self, fb):
188            self.desc = fb.get('desc', None)
[e40c7ee]189            self.code = fb.get('code', -1)
[03e0290]190            self.errstr = fb.get('errstr', None)
191
192    def __init__(self, pre): 
193        """
[058f58e]194        Specialize the class for the pre method
[03e0290]195        """
196        self.RequestMessage = globals()["%sRequestMessage" % pre]
197        self.ResponseMessage = globals()["%sResponseMessage" % pre]
198        self.RequestBody="%sRequestBody" % pre
199        self.ResponseBody="%sResponseBody" % pre
200        self.method = pre
[058f58e]201
202        method_call = getattr(feddServiceLocator().getfeddPortType(),
203                self.method, None)
204        if method_call:
205            # The pre method is a fedd external service
206            self.caller = service_caller(self.method, 'getfeddPortType', 
207                    feddServiceLocator, self.RequestMessage, self.RequestBody)
208        else:
209            # The pre method is a fedd internal service
210            self.caller = service_caller(self.method, 
211                    'getfeddInternalPortType', feddInternalServiceLocator,
212                    self.RequestMessage, self.RequestBody)
213
[03e0290]214        self.RPCException = fedd_rpc.RPCException
215
216
217    def add_ssh_key(self, option, opt_str, value, parser, access_keys):
218        try:
219            access_keys.append(access_method(file=value,
220                type=access_method.type_ssh))
221        except IOError, (errno, strerror):
222            raise OptionValueError("Cannot generate sshPubkey from %s: "\
223                    "%s (%d)" % (value,strerror,errno))
224
225    def add_x509_cert(self, option, opt_str, value, parser, access_keys):
226        try:
227            access_keys.append(access_method(file=value,
228                type=access_method.type_x509))
229        except IOError, (errno, strerror):
230            raise OptionValueError("Cannot read x509 cert from %s: %s (%d)" %
231                    (value,strerror,errno))
232    def add_node_desc(self, option, opt_str, value, parser, node_descs):
233        def none_if_zero(x):
234            if len(x) > 0: return x
235            else: return None
236
237        params = map(none_if_zero, value.split(":"));
238       
239        if len(params) < 4 and len(params) > 1:
240            node_descs.append(node_desc(*params))
241        else:
242            raise OptionValueError("Bad node description: %s" % value)
243
244    def get_user_info(self, access_keys):
245        pw = pwd.getpwuid(os.getuid());
246        try_cert=None
247        user = None
248
249        if pw != None:
250            user = pw[0]
251            try_cert = "%s/.ssl/emulab.pem" % pw[5];
252            if not os.access(try_cert, os.R_OK):
253                try_cert = None
254            if len(access_keys) == 0:
255                for k in ["%s/.ssh/id_rsa.pub", "%s/.ssh/id_dsa.pub", 
256                        "%s/.ssh/identity.pub"]:
257                    try_key = k % pw[5];
258                    if os.access(try_key, os.R_OK):
259                        access_keys.append(access_method(file=try_key,
260                            type=access_method.type_ssh))
261                        break
262        return (user, try_cert)
263
264    def do_rpc(self, req_dict, url, transport, cert, trusted, tracefile=None,
265            serialize_only=False):
266        """
267        The work of sending and parsing the RPC as either XMLRPC or SOAP
268        """
269
270        context = None
271        while context == None:
272            try:
273                context = fedd_ssl_context(cert, trusted)
274            except SSL.SSLError, e:
275                # Yes, doing this on message type is not ideal.  The string
276                # comes from OpenSSL, so check there is this stops working.
277                if str(e) == "bad decrypt": 
278                    print >>sys.stderr, "Bad Passphrase given."
279                else: raise
280
281        if transport == "soap":
282            if serialize_only:
283                sw = SoapWriter()
284                sw.serialize(req)
285                print str(sw)
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
498        if opts.debug > 0: opts.tracefile=sys.stderr
499
500        (user, cert) = self.get_user_info(access_keys)
501
502        if opts.user: user = opts.user
503
504        if opts.cert != None: cert = opts.cert
505
506        if cert == None:
507            sys.exit("No certificate given (--cert) or found")
508
509        if os.access(cert, os.R_OK):
510            fid = fedid(file=cert)
511            if opts.use_fedid == True:
512                user = fid
513        else:
514            sys.exit("Cannot read certificate (%s)" % cert)
515
516        if opts.file:
517            exp_desc = ""
518            try:
519                f = open(opts.file, 'r')
520                for line in f:
521                    exp_desc += line
522                f.close()
523            except IOError:
524                sys.exit("Cannot read description file (%s)" %opts.file)
525        else:
526            sys.exit("Must specify an experiment description (--file)")
527
528        if not opts.master:
529            sys.exit("Must specify a master testbed (--master)")
530
531        out_certfile = opts.out_certfile
532
533        msg = {
[3925b50]534                'experimentdescription': { 'ns2description': exp_desc },
[03e0290]535                'master': opts.master,
536                'user' : [ {\
537                        'userID': pack_id(user), \
538                        'access': [ { a.type: a.buf } for a in access_keys]\
539                        } ]
[6ff0b91]540                }
[03e0290]541
[e40c7ee]542        if opts.exp_name:
543            msg['experimentID'] = { 'localname': opts.exp_name }
544
[03e0290]545        if opts.debug > 1: print >>sys.stderr, msg
546
547        try:
548            resp_dict = self.do_rpc(msg, 
549                    opts.url, opts.transport, cert, opts.trusted, 
550                    serialize_only=opts.serialize_only,
551                    tracefile=opts.tracefile)
552        except self.RPCException, e:
553            exit_with_fault(\
554                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
555        except RuntimeError, e:
[0b466d1]556            sys.exit("Error processing RPC: %s" % e)
[03e0290]557
558        if opts.debug > 1: print >>sys.stderr, resp_dict
559
560        ea = resp_dict.get('experimentAccess', None)
561        if out_certfile and ea and ea.has_key('X509'):
[0c0b13c]562            try:
[03e0290]563                f = open(out_certfile, "w")
564                print >>f, ea['X509']
565                f.close()
566            except IOError:
567                sys.exit('Could not write to %s' %  out_certfile)
[e40c7ee]568        eid = resp_dict.get('experimentID', None)
569        if eid:
570            for id in eid:
571                for k in id.keys():
[058f58e]572                    print "%s: %s" % (k, id[k])
[03e0290]573
[f4f4117]574class split(fedd_rpc):
575    def __init__(self): 
576        fedd_rpc.__init__(self, "Ns2Split")
577    def __call__(self):
578        access_keys = []
579        # Process the options using the customized option parser defined above
[2c6128f]580        parser = fedd_split_opts(access_keys, self.add_ssh_key,
[f4f4117]581                self.add_x509_cert)
582
583        (opts, args) = parser.parse_args()
584
585        if opts.trusted != None:
586            if ( not os.access(opts.trusted, os.R_OK) ) :
587                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
588        else:
589            parser.error("--trusted is required")
590
591        if opts.debug > 0: opts.tracefile=sys.stderr
592
593        if opts.cert != None: cert = opts.cert
[2c6128f]594        else: cert = None
[f4f4117]595
596        if cert == None:
597            sys.exit("No certificate given (--cert) or found")
598
599        if os.access(cert, os.R_OK):
600            fid = fedid(file=cert)
601            if opts.use_fedid == True:
602                user = fid
603        else:
604            sys.exit("Cannot read certificate (%s)" % cert)
605
606        if opts.file:
607            exp_desc = ""
608            try:
609                f = open(opts.file, 'r')
610                for line in f:
611                    exp_desc += line
612                f.close()
613            except IOError:
614                sys.exit("Cannot read description file (%s)" %opts.file)
615        else:
616            sys.exit("Must specify an experiment description (--file)")
617
618        if not opts.master:
619            sys.exit("Must specify a master testbed (--master)")
620
621        out_certfile = opts.out_certfile
622
623        msg = {
624                'description': { 'ns2description': exp_desc },
625                'master': opts.master,
[2c6128f]626                'include_fedkit': opts.fedkit,
[f4f4117]627                }
628
629        if opts.debug > 1: print >>sys.stderr, msg
630
631        try:
632            resp_dict = self.do_rpc(msg, 
633                    opts.url, opts.transport, cert, opts.trusted, 
634                    serialize_only=opts.serialize_only,
635                    tracefile=opts.tracefile)
636        except self.RPCException, e:
637            exit_with_fault(\
638                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
639        except RuntimeError, e:
640            sys.exit("Error processing RPC: %s" % e)
641
642        if opts.debug > 1: print >>sys.stderr, resp_dict
643
644        out = resp_dict.get('output', None)
645
646        for line in out.splitlines():
647            print "%s" % line
648
[03e0290]649class access(fedd_rpc):
650    def __init__(self):
651        fedd_rpc.__init__(self, "RequestAccess")
652
653    def print_response_as_testbed(self, resp, label, out=sys.stdout):
654        """Print the response as input to the splitter script"""
655
656        e = resp['emulab']
657        p = e['project']
658        fields = { 
659                "Boss": e['boss'],
660                "OpsNode": e['ops'],
661                "Domain": e['domain'],
662                "FileServer": e['fileServer'],
663                "EventServer": e['eventServer'],
664                "Project": unpack_id(p['name'])
665                }
666        if (label != None): print >> out, "[%s]" % label
667
668        for l, v in fields.iteritems():
669            print >>out, "%s: %s" % (l, v)
670
671        for u in p['user']:
672            print >>out, "User: %s" % unpack_id(u['userID'])
673
674        for a in e['fedAttr']:
675            print >>out, "%s: %s" % (a['attribute'], a['value'])
676
677    def __call__(self):
678        access_keys = []
679        node_descs = []
680        proj = None
681
682        # Process the options using the customized option parser defined above
683        parser = fedd_access_opts(access_keys, node_descs, self.add_ssh_key,
684                self.add_x509_cert, self.add_node_desc)
685
686        (opts, args) = parser.parse_args()
687
688        if opts.testbed == None:
689            parser.error("--testbed is required")
690
691        if opts.trusted != None:
692            if ( not os.access(opts.trusted, os.R_OK) ) :
693                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
694        else:
695            parser.error("--trusted is required")
696
697        if opts.debug > 0: opts.tracefile=sys.stderr
698
699        (user, cert) = self.get_user_info(access_keys)
700
701        if opts.user: user = opts.user
702
703        if opts.cert != None: cert = opts.cert
704
705        if cert == None:
706            sys.exit("No certificate given (--cert) or found")
707
708        if os.access(cert, os.R_OK):
709            fid = fedid(file=cert)
710            if opts.use_fedid == True:
711                user = fid
712        else:
713            sys.exit("Cannot read certificate (%s)" % cert)
714
715        msg = {
716                'allocID': pack_id('test alloc'),
717                'destinationTestbed': pack_id(opts.testbed),
[72ed6e4]718                'serviceAccess' : [ { a.type: a.buf } for a in access_keys ],
719                'createAccess' : [ { a.type: a.buf } for a in access_keys ],
[03e0290]720                }
721
722        if len(node_descs) > 0:
723            msg['resources'] = { 
724                    'node': [ 
725                        { 
726                            'image':  n.image ,
727                            'hardware':  n.hardware,
728                            'count': n.count,
729                        } for n in node_descs],
730                    }
731
732        if opts.project != None:
733            if not opts.anonymous and user != None:
734                msg['project'] = {
735                        'name': pack_id(opts.project),
736                        'user': [ { 'userID': pack_id(user) } ],
737                        }
738            else:
739                msg['project'] = { 'name': pack_id(opts.project) }
740        else:
741            if not opts.anonymous and user != None:
742                msg['user'] = [ { 'userID': pack_id(user) } ]
743            else:
744                msg['user'] = [];
745
746        if opts.debug > 1: print >>sys.stderr, msg
747
748        try:
749            resp_dict = self.do_rpc(msg, 
750                    opts.url, opts.transport, cert, opts.trusted, 
751                    serialize_only=opts.serialize_only,
752                    tracefile=opts.tracefile)
753        except self.RPCException, e:
754            exit_with_fault(\
755                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
756        except RuntimeError, e:
757            sys.exit("Error processing RPC: %s" % e.message)
758
759        if opts.debug > 1: print >>sys.stderr, resp_dict
760        self.print_response_as_testbed(resp_dict, opts.label)
761
762cmds = {\
763        'create': create(),\
[f4f4117]764        'split': split(),\
[03e0290]765        'access': access(),\
766        'vtopo': exp_data('Vtopo'),\
767        'vis': exp_data('Vis'),\
[c52c48d]768        'info': exp_data('Info'),\
[7a8d667]769        'terminate': terminate(),\
[03e0290]770    }
771
772operation = cmds.get(sys.argv[1], None)
773if operation:
774    del sys.argv[1]
775    operation()
776else:
777    sys.exit("Bad command: %s.  Valid ones are: %s" % \
778            (sys.argv[1], ", ".join(cmds.keys())))
779
Note: See TracBrowser for help on using the repository browser.