source: fedd/fedd_client.py @ 0ea5050

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

remove option conflict

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