Ignore:
Timestamp:
Sep 9, 2008 5:59:55 PM (16 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
Children:
e40c7ee
Parents:
45ebc4d
Message:

single client

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_client.py

    r45ebc4d r03e0290  
    2020
    2121from fedd_util import fedid, fedd_ssl_context, pack_soap, unpack_soap, \
    22         pack_id, unpack_id
     22        pack_id, unpack_id, encapsulate_binaries, decapsulate_binaries
    2323
    2424from optparse import OptionParser, OptionValueError
     
    7676                version="0.1")
    7777
    78         self.set_defaults(url="https://localhost:23235", anonymous=False,
    79                 serialize_only=False, transport="soap", use_fedid=False,
    80                 debug=0)
    81 
    82         self.add_option("-a","--anonymous", action="store_true",
    83                 dest="anonymous", help="Do not include a user in the request")
    8478        self.add_option("-c","--cert", action="store", dest="cert",
    8579                type="string", help="my certificate file")
    8680        self.add_option("-d", "--debug", action="count", dest="debug",
    87                 help="Set debug.  Repeat for more information")
    88         self.add_option("-f","--useFedid", action="store_true",
    89                 dest="use_fedid",
     81                default=0, help="Set debug.  Repeat for more information")
     82        self.add_option("-s", "--serializeOnly", action="store_true",
     83                dest="serialize_only", default=False,
     84                help="Print the SOAP request that would be sent and exit")
     85        self.add_option("-T","--trusted", action="store", dest="trusted",
     86                type="string", help="Trusted certificates (required)")
     87        self.add_option("-u", "--url", action="store", dest="url",
     88                type="string",default="https://localhost:23235", 
     89                help="URL to connect to (default %default)")
     90        self.add_option("-x","--transport", action="store", type="choice",
     91                choices=("xmlrpc", "soap"), default="soap",
     92                help="Transport for request (xmlrpc|soap) (Default: %default)")
     93        self.add_option("--trace", action="store_const", dest="tracefile",
     94                const=sys.stderr, help="Print SOAP exchange to stderr")
     95
     96class fedd_create_opts(fedd_client_opts):
     97    def __init__(self, access_keys, add_key_callback=None,
     98            add_cert_callback=None):
     99        fedd_client_opts.__init__(self)
     100        self.add_option("-e", "--experiment_cert", dest="out_certfile",
     101                type="string", help="output certificate file")
     102        self.add_option("-F","--useFedid", action="store_true",
     103                dest="use_fedid", default=False,
    90104                help="Use a fedid derived from my certificate as user identity")
    91         self.add_option("-k", "--sshKey", action="callback", type="string",
    92                 callback=add_ssh_key, callback_args=(access_keys,),
    93                 help="ssh key for access (can be supplied more than once")
    94         self.add_option("-K", "--x509Key", action="callback", type="string",
    95                 callback=add_x509_cert, callback_args=(access_keys,),
    96                 help="X509 certificate for access " + \
     105        self.add_option("-f", "--file", dest="file",
     106                help="experiment description file")
     107        if add_key_callback:
     108            self.add_option("-k", "--sshKey", action="callback", type="string",
     109                    callback=add_key_callback, callback_args=(access_keys,),
     110                    help="ssh key for access (can be supplied more than once")
     111        if add_cert_callback:
     112            self.add_option("-K", "--x509Key", action="callback",
     113                    type="string", callback=add_cert_callback,
     114                    callback_args=(access_keys,),
     115                    help="X509 certificate for access " + \
    97116                        "(can be supplied more than once")
     117        self.add_option("-m", "--master", dest="master",
     118                help="Master testbed in the federation")
     119        self.add_option("-U", "--username", action="store", dest="user",
     120                type="string", help="Use this username instead of the uid")
     121
     122class fedd_access_opts(fedd_create_opts):
     123    def __init__(self, access_keys, node_descs, add_key_callback=None,
     124            add_cert_callback=None, add_node_callback=None):
     125        fedd_create_opts.__init__(self, access_keys, add_key_callback,
     126                add_cert_callback)
     127        self.add_option("-a","--anonymous", action="store_true",
     128                dest="anonymous", default=False,
     129                help="Do not include a user in the request")
    98130        self.add_option("-l","--label", action="store", dest="label",
    99131                type="string", help="Label for output")
    100         self.add_option("-n", "--node", action="callback", type="string",
    101                 callback=add_node_desc, callback_args=(node_descs,),
    102                 help="Node description: image:hardware[:count]")
     132        if add_node_callback:
     133            self.add_option("-n", "--node", action="callback", type="string",
     134                    callback=add_node_callback, callback_args=(node_descs,),
     135                    help="Node description: image:hardware[:count]")
    103136        self.add_option("-p", "--project", action="store", dest="project",
    104137                type="string",
    105138                help="Use a project request with this project name")
    106         self.add_option("-s", "--serializeOnly", action="store_true",
    107                 dest="serialize_only",
    108                 help="Print the SOAP request that would be sent and exit")
    109139        self.add_option("-t", "--testbed", action="store", dest="testbed",
    110140                type="string",
    111141                help="Testbed identifier (URI) to contact (required)")
    112         self.add_option("-T","--trusted", action="store", dest="trusted",
    113                 type="string", help="Trusted certificates (required)")
    114         self.add_option("-u", "--url", action="store", dest="url",
    115                 type="string",
    116                 help="URL to connect to (default %default)")
    117         self.add_option("-U", "--username", action="store", dest="user",
    118                 type="string", help="Use this username instead of the uid")
    119         self.add_option("-x","--transport", action="store", type="choice",
    120                 choices=("xmlrpc", "soap"),
    121                 help="Transport for request (xmlrpc|soap) (Default: %default)")
    122         self.add_option("--trace", action="store_const", dest="tracefile",
    123                 const=sys.stderr, help="Print SOAP exchange to stderr")
    124 
    125 def print_response_as_testbed(resp, label, out=sys.stdout):
    126     """Print the response as input to the splitter script"""
    127 
    128     e = resp['emulab']
    129     p = e['project']
    130     fields = {
    131             "Boss": e['boss'],
    132             "OpsNode": e['ops'],
    133             "Domain": e['domain'],
    134             "FileServer": e['fileServer'],
    135             "EventServer": e['eventServer'],
    136             "Project": unpack_id(p['name'])
    137             }
    138     if (label != None): print >> out, "[%s]" % label
    139 
    140     for l, v in fields.iteritems():
    141         print >>out, "%s: %s" % (l, v)
    142 
    143     for u in p['user']:
    144         print >>out, "User: %s" % unpack_id(u['userID'])
    145 
    146     for a in e['fedAttr']:
    147         print >>out, "%s: %s" % (a['attribute'], a['value'])
    148142
    149143def exit_with_fault(dict, out=sys.stderr):
     
    166160    sys.exit(dict.get('code', 20))
    167161
    168 def add_ssh_key(option, opt_str, value, parser, access_keys):
    169     try:
    170         access_keys.append(access_method(file=value,
    171             type=access_method.type_ssh))
    172     except IOError, (errno, strerror):
    173         raise OptionValueError("Cannot generate sshPubkey from %s: %s (%d)" %
    174                 (value,strerror,errno))
    175 
    176 def add_x509_cert(option, opt_str, value, parser, access_keys):
    177     try:
    178         access_keys.append(access_method(file=value,
    179             type=access_method.type_x509))
    180     except IOError, (errno, strerror):
    181         raise OptionValueError("Cannot read x509 cert from %s: %s (%d)" %
    182                 (value,strerror,errno))
    183 
    184 def add_node_desc(option, opt_str, value, parser, node_descs):
    185     def none_if_zero(x):
    186         if len(x) > 0: return x
    187         else: return None
    188 
    189     params = map(none_if_zero, value.split(":"));
    190    
    191     if len(params) < 4 and len(params) > 1:
    192         node_descs.append(node_desc(*params))
    193     else:
    194         raise OptionValueError("Bad node description: %s" % value)
    195 
    196 def get_user_info(access_keys):
    197     pw = pwd.getpwuid(os.getuid());
    198     try_cert=None
    199     user = None
    200 
    201     if pw != None:
    202         user = pw[0]
    203         try_cert = "%s/.ssl/emulab.pem" % pw[5];
    204         if not os.access(try_cert, os.R_OK):
    205             try_cert = None
    206         if len(access_keys) == 0:
    207             for k in ["%s/.ssh/id_rsa.pub", "%s/.ssh/id_dsa.pub",
    208                     "%s/.ssh/identity.pub"]:
    209                 try_key = k % pw[5];
    210                 if os.access(try_key, os.R_OK):
    211                     access_keys.append(access_method(file=try_key,
    212                         type=access_method.type_ssh))
    213                     break
    214     return (user, try_cert)
    215 
    216 access_keys = []
    217 node_descs = []
    218 proj = None
    219 
    220 # Process the options using the customized option parser defined above
    221 parser = fedd_client_opts()
    222 
    223 (opts, args) = parser.parse_args()
    224 
    225 if opts.testbed == None:
    226     parser.error("--testbed is required")
    227 
    228 if opts.trusted != None:
    229     if ( not os.access(opts.trusted, os.R_OK) ) :
    230         sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     162class fedd_exp_data_opts(fedd_client_opts):
     163    def __init__(self):
     164        fedd_client_opts.__init__(self)
     165        self.add_option("-e", "--experiment_cert", dest="exp_certfile",
     166                type="string", help="output certificate file")
     167
     168# Base class that will do a the SOAP/XMLRPC exchange for a request.
     169class fedd_rpc:
     170    class RPCException:
     171        def __init__(self, fb):
     172            self.desc = fb.get('desc', None)
     173            self.code = fb.get('code', None)
     174            self.errstr = fb.get('errstr', None)
     175
     176    def __init__(self, pre):
     177        """
     178        Specialize the class for the prc method
     179        """
     180        self.RequestMessage = globals()["%sRequestMessage" % pre]
     181        self.ResponseMessage = globals()["%sResponseMessage" % pre]
     182        self.RequestBody="%sRequestBody" % pre
     183        self.ResponseBody="%sResponseBody" % pre
     184        self.method = pre
     185        self.RPCException = fedd_rpc.RPCException
     186
     187
     188    def add_ssh_key(self, option, opt_str, value, parser, access_keys):
     189        try:
     190            access_keys.append(access_method(file=value,
     191                type=access_method.type_ssh))
     192        except IOError, (errno, strerror):
     193            raise OptionValueError("Cannot generate sshPubkey from %s: "\
     194                    "%s (%d)" % (value,strerror,errno))
     195
     196    def add_x509_cert(self, option, opt_str, value, parser, access_keys):
     197        try:
     198            access_keys.append(access_method(file=value,
     199                type=access_method.type_x509))
     200        except IOError, (errno, strerror):
     201            raise OptionValueError("Cannot read x509 cert from %s: %s (%d)" %
     202                    (value,strerror,errno))
     203    def add_node_desc(self, option, opt_str, value, parser, node_descs):
     204        def none_if_zero(x):
     205            if len(x) > 0: return x
     206            else: return None
     207
     208        params = map(none_if_zero, value.split(":"));
     209       
     210        if len(params) < 4 and len(params) > 1:
     211            node_descs.append(node_desc(*params))
     212        else:
     213            raise OptionValueError("Bad node description: %s" % value)
     214
     215    def get_user_info(self, access_keys):
     216        pw = pwd.getpwuid(os.getuid());
     217        try_cert=None
     218        user = None
     219
     220        if pw != None:
     221            user = pw[0]
     222            try_cert = "%s/.ssl/emulab.pem" % pw[5];
     223            if not os.access(try_cert, os.R_OK):
     224                try_cert = None
     225            if len(access_keys) == 0:
     226                for k in ["%s/.ssh/id_rsa.pub", "%s/.ssh/id_dsa.pub",
     227                        "%s/.ssh/identity.pub"]:
     228                    try_key = k % pw[5];
     229                    if os.access(try_key, os.R_OK):
     230                        access_keys.append(access_method(file=try_key,
     231                            type=access_method.type_ssh))
     232                        break
     233        return (user, try_cert)
     234
     235    def do_rpc(self, req_dict, url, transport, cert, trusted, tracefile=None,
     236            serialize_only=False):
     237        """
     238        The work of sending and parsing the RPC as either XMLRPC or SOAP
     239        """
     240
     241        context = None
     242        while context == None:
     243            try:
     244                context = fedd_ssl_context(cert, trusted)
     245            except SSL.SSLError, e:
     246                # Yes, doing this on message type is not ideal.  The string
     247                # comes from OpenSSL, so check there is this stops working.
     248                if str(e) == "bad decrypt":
     249                    print >>sys.stderr, "Bad Passphrase given."
     250                else: raise
     251
     252        if transport == "soap":
     253            loc = feddServiceLocator();
     254            port = loc.getfeddPortType(url,
     255                    transport=M2Crypto.httpslib.HTTPSConnection,
     256                    transdict={ 'ssl_context' : context },
     257                    tracefile=tracefile)
     258
     259            req = self.RequestMessage()
     260
     261            set_req = getattr(req, "set_element_%s" % self.RequestBody, None)
     262            set_req(pack_soap(req, self.RequestBody, req_dict))
     263
     264            if serialize_only:
     265                sw = SoapWriter()
     266                sw.serialize(req)
     267                print str(sw)
     268                sys.exit(0)
     269
     270            try:
     271                method_call = getattr(port, self.method, None)
     272                resp = method_call(req)
     273            except ZSI.ParseException, e:
     274                raise RuntimeError("Malformed response (XMLPRC?): %s" % e)
     275            except ZSI.FaultException, e:
     276                resp = e.fault.detail[0]
     277
     278            if resp:
     279                resp_call = getattr(resp, "get_element_%s" %self.ResponseBody,
     280                        None)
     281                if resp_call:
     282                    resp_body = resp_call()
     283                    if ( resp_body != None):
     284                        try:
     285                            return unpack_soap(resp_body)
     286                        except RuntimeError, e:
     287                            raise RuntimeError("Bad response. %s" % e.message)
     288                elif 'get_element_FeddFaultBody' in dir(resp):
     289                    resp_body = resp.get_element_FeddFaultBody()
     290                    if resp_body != None:
     291                        try:
     292                            fb = unpack_soap(resp_body)
     293                        except RuntimeError, e:
     294                            raise RuntimeError("Bad response. %s" % e.message)
     295                        raise self.RPCException(fb)
     296                else:
     297                    raise RuntimeError("No body in response!?")
     298            else:
     299                raise RuntimeError("No response?!?")
     300        elif transport == "xmlrpc":
     301            if serialize_only:
     302                ser = dumps((req_dict,))
     303                print ser
     304                sys.exit(0)
     305
     306            xtransport = SSL_Transport(context)
     307            port = ServerProxy(url, transport=xtransport)
     308
     309            try:
     310                method_call = getattr(port, self.method, None)
     311                resp = method_call(
     312                        encapsulate_binaries({ self.RequestBody: msg},\
     313                            ('fedid',)))
     314            except Error, e:
     315                resp = { 'FeddFaultBody': \
     316                        { 'errstr' : e.faultCode, 'desc' : e.faultString } }
     317            if resp:
     318                if resp.has_key(self.ResponseBody):
     319                    return resp[self.ResponseBody]
     320                elif resp.has_key('FeddFaultBody'):
     321                    raise self.RPCException(resp['FeddFaultBody'])
     322                else:
     323                    raise RuntimeError("No body in response!?")
     324            else:
     325                raise RuntimeError("No response?!?")
     326        else:
     327            raise RuntimeError("Unknown RPC transport: %s" % transport)
     328
     329# Querying experiment data follows the same control flow regardless of the
     330# specific data retrieved.  This class encapsulates that control flow.
     331class exp_data(fedd_rpc):
     332    def __init__(self, op):
     333        """
     334        Specialize the class for the type of data requested (op)
     335        """
     336
     337        fedd_rpc.__init__(self, op)
     338        if op =='Vtopo':
     339            self.key="vtopo"
     340            self.xml='experiment'
     341        elif op == 'Vis':
     342            self.key="vis"
     343            self.xml='vis'
     344        else:
     345            raise TypeError("Bad op: %s" % op)
     346
     347    def print_xml(self, d, out=sys.stdout):
     348        """
     349        Print the retrieved data is a simple xml representation of the dict.
     350        """
     351        str = "<%s>\n" % self.xml
     352        for t in ('node', 'lan'):
     353            if d.has_key(t):
     354                for x in d[t]:
     355                    str += "<%s>" % t
     356                    for k in x.keys():
     357                        str += "<%s>%s</%s>" % (k, x[k],k)
     358                    str += "</%s>\n" % t
     359        str+= "</%s>" % self.xml
     360        print >>out, str
     361
     362    def __call__(self):
     363        """
     364        The control flow.  Compose the request and print the response.
     365        """
     366        # Process the options using the customized option parser defined above
     367        parser = fedd_exp_data_opts()
     368
     369        (opts, args) = parser.parse_args()
     370
     371        if opts.trusted != None:
     372            if ( not os.access(opts.trusted, os.R_OK) ) :
     373                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     374        else:
     375            parser.error("--trusted is required")
     376
     377        if opts.debug > 0: opts.tracefile=sys.stderr
     378
     379        if opts.cert != None: cert = opts.cert
     380
     381        if cert == None:
     382            sys.exit("No certificate given (--cert) or found")
     383
     384        if os.access(cert, os.R_OK):
     385            fid = fedid(file=cert)
     386        else:
     387            sys.exit("Cannot read certificate (%s)" % cert)
     388
     389        if opts.exp_certfile:
     390            exp_fedid = fedid(file=opts.exp_certfile)
     391        else:
     392            sys.exit("Experiment certfile required")
     393
     394        try:
     395            resp_dict = self.do_rpc({ 'experiment': { 'fedid': exp_fedid } },
     396                    opts.url, opts.transport, cert, opts.trusted,
     397                    serialize_only=opts.serialize_only,
     398                    tracefile=opts.tracefile)
     399        except self.RPCException, e:
     400            exit_with_fault(\
     401                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     402        except RuntimeError, e:
     403            sys.exit("Error processing RPC: %s" % e.message)
     404
     405        try:
     406            if resp_dict.has_key(self.key):
     407                self.print_xml(resp_dict[self.key])
     408        except RuntimeError, e:
     409            sys.exit("Bad response. %s" % e.message)
     410
     411class create(fedd_rpc):
     412    def __init__(self):
     413        fedd_rpc.__init__(self, "Create")
     414    def __call__(self):
     415        access_keys = []
     416        # Process the options using the customized option parser defined above
     417        parser = fedd_create_opts(access_keys, self.add_ssh_key,
     418                self.add_x509_cert)
     419
     420        (opts, args) = parser.parse_args()
     421
     422        if opts.trusted != None:
     423            if ( not os.access(opts.trusted, os.R_OK) ) :
     424                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     425        else:
     426            parser.error("--trusted is required")
     427
     428        if opts.debug > 0: opts.tracefile=sys.stderr
     429
     430        (user, cert) = self.get_user_info(access_keys)
     431
     432        if opts.user: user = opts.user
     433
     434        if opts.cert != None: cert = opts.cert
     435
     436        if cert == None:
     437            sys.exit("No certificate given (--cert) or found")
     438
     439        if os.access(cert, os.R_OK):
     440            fid = fedid(file=cert)
     441            if opts.use_fedid == True:
     442                user = fid
     443        else:
     444            sys.exit("Cannot read certificate (%s)" % cert)
     445
     446        if opts.file:
     447            exp_desc = ""
     448            try:
     449                f = open(opts.file, 'r')
     450                for line in f:
     451                    exp_desc += line
     452                f.close()
     453            except IOError:
     454                sys.exit("Cannot read description file (%s)" %opts.file)
     455        else:
     456            sys.exit("Must specify an experiment description (--file)")
     457
     458        if not opts.master:
     459            sys.exit("Must specify a master testbed (--master)")
     460
     461        out_certfile = opts.out_certfile
     462
     463        msg = {
     464                'experimentdescription': exp_desc,
     465                'master': opts.master,
     466                'user' : [ {\
     467                        'userID': pack_id(user), \
     468                        'access': [ { a.type: a.buf } for a in access_keys]\
     469                        } ]
     470                }
     471
     472        if opts.debug > 1: print >>sys.stderr, msg
     473
     474        try:
     475            resp_dict = self.do_rpc(msg,
     476                    opts.url, opts.transport, cert, opts.trusted,
     477                    serialize_only=opts.serialize_only,
     478                    tracefile=opts.tracefile)
     479        except self.RPCException, e:
     480            exit_with_fault(\
     481                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     482        except RuntimeError, e:
     483            sys.exit("Error processing RPC: %s" % e.message)
     484
     485        if opts.debug > 1: print >>sys.stderr, resp_dict
     486
     487        ea = resp_dict.get('experimentAccess', None)
     488        if out_certfile and ea and ea.has_key('X509'):
     489            try:
     490                f = open(out_certfile, "w")
     491                print >>f, ea['X509']
     492                f.close()
     493            except IOError:
     494                sys.exit('Could not write to %s' %  out_certfile)
     495
     496class access(fedd_rpc):
     497    def __init__(self):
     498        fedd_rpc.__init__(self, "RequestAccess")
     499
     500    def print_response_as_testbed(self, resp, label, out=sys.stdout):
     501        """Print the response as input to the splitter script"""
     502
     503        e = resp['emulab']
     504        p = e['project']
     505        fields = {
     506                "Boss": e['boss'],
     507                "OpsNode": e['ops'],
     508                "Domain": e['domain'],
     509                "FileServer": e['fileServer'],
     510                "EventServer": e['eventServer'],
     511                "Project": unpack_id(p['name'])
     512                }
     513        if (label != None): print >> out, "[%s]" % label
     514
     515        for l, v in fields.iteritems():
     516            print >>out, "%s: %s" % (l, v)
     517
     518        for u in p['user']:
     519            print >>out, "User: %s" % unpack_id(u['userID'])
     520
     521        for a in e['fedAttr']:
     522            print >>out, "%s: %s" % (a['attribute'], a['value'])
     523
     524    def __call__(self):
     525        access_keys = []
     526        node_descs = []
     527        proj = None
     528
     529        # Process the options using the customized option parser defined above
     530        parser = fedd_access_opts(access_keys, node_descs, self.add_ssh_key,
     531                self.add_x509_cert, self.add_node_desc)
     532
     533        (opts, args) = parser.parse_args()
     534
     535        if opts.testbed == None:
     536            parser.error("--testbed is required")
     537
     538        if opts.trusted != None:
     539            if ( not os.access(opts.trusted, os.R_OK) ) :
     540                sys.exit("Cannot read trusted certificates (%s)" % opts.trusted)
     541        else:
     542            parser.error("--trusted is required")
     543
     544        if opts.debug > 0: opts.tracefile=sys.stderr
     545
     546        (user, cert) = self.get_user_info(access_keys)
     547
     548        if opts.user: user = opts.user
     549
     550        if opts.cert != None: cert = opts.cert
     551
     552        if cert == None:
     553            sys.exit("No certificate given (--cert) or found")
     554
     555        if os.access(cert, os.R_OK):
     556            fid = fedid(file=cert)
     557            if opts.use_fedid == True:
     558                user = fid
     559        else:
     560            sys.exit("Cannot read certificate (%s)" % cert)
     561
     562        msg = {
     563                'allocID': pack_id('test alloc'),
     564                'destinationTestbed': pack_id(opts.testbed),
     565                'access' : [ { a.type: a.buf } for a in access_keys ],
     566                }
     567
     568        if len(node_descs) > 0:
     569            msg['resources'] = {
     570                    'node': [
     571                        {
     572                            'image':  n.image ,
     573                            'hardware':  n.hardware,
     574                            'count': n.count,
     575                        } for n in node_descs],
     576                    }
     577
     578        if opts.project != None:
     579            if not opts.anonymous and user != None:
     580                msg['project'] = {
     581                        'name': pack_id(opts.project),
     582                        'user': [ { 'userID': pack_id(user) } ],
     583                        }
     584            else:
     585                msg['project'] = { 'name': pack_id(opts.project) }
     586        else:
     587            if not opts.anonymous and user != None:
     588                msg['user'] = [ { 'userID': pack_id(user) } ]
     589            else:
     590                msg['user'] = [];
     591
     592        if opts.debug > 1: print >>sys.stderr, msg
     593
     594        try:
     595            resp_dict = self.do_rpc(msg,
     596                    opts.url, opts.transport, cert, opts.trusted,
     597                    serialize_only=opts.serialize_only,
     598                    tracefile=opts.tracefile)
     599        except self.RPCException, e:
     600            exit_with_fault(\
     601                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
     602        except RuntimeError, e:
     603            sys.exit("Error processing RPC: %s" % e.message)
     604
     605        if opts.debug > 1: print >>sys.stderr, resp_dict
     606        self.print_response_as_testbed(resp_dict, opts.label)
     607
     608cmds = {\
     609        'create': create(),\
     610        'access': access(),\
     611        'vtopo': exp_data('Vtopo'),\
     612        'vis': exp_data('Vis'),\
     613    }
     614
     615operation = cmds.get(sys.argv[1], None)
     616if operation:
     617    del sys.argv[1]
     618    operation()
    231619else:
    232     parser.error("--trusted is required")
    233 
    234 if opts.debug > 0: opts.tracefile=sys.stderr
    235 
    236 (user, cert) = get_user_info(access_keys)
    237 
    238 if opts.user: user = opts.user
    239 
    240 if opts.cert != None: cert = opts.cert
    241 
    242 if cert == None:
    243     sys.exit("No certificate given (--cert) or found")
    244 
    245 if os.access(cert, os.R_OK):
    246     fid = fedid(file=cert)
    247     if opts.use_fedid == True:
    248         user = fid
    249 else:
    250     sys.exit("Cannot read certificate (%s)" % cert)
    251 
    252 context = None
    253 while context == None:
    254     try:
    255         context = fedd_ssl_context(cert, opts.trusted)
    256     except SSL.SSLError, e:
    257         # Yes, doing this on message type is not ideal.  The string comes from
    258         # OpenSSL, so check there is this stops working.
    259         if str(e) == "bad decrypt":
    260             print >>sys.stderr, "Bad Passphrase given."
    261         else: raise
    262 
    263 msg = {
    264         'allocID': pack_id('test alloc'),
    265         'destinationTestbed': pack_id(opts.testbed),
    266         'access' : [ { a.type: a.buf } for a in access_keys ],
    267         }
    268 
    269 if len(node_descs) > 0:
    270     msg['resources'] = {
    271             'node': [
    272                 {
    273                     'image':  n.image ,
    274                     'hardware':  n.hardware,
    275                     'count': n.count,
    276                 } for n in node_descs],
    277             }
    278 
    279 if opts.project != None:
    280     if not opts.anonymous and user != None:
    281         msg['project'] = {
    282                 'name': pack_id(opts.project),
    283                 'user': [ { 'userID': pack_id(user) } ],
    284                 }
    285     else:
    286         msg['project'] = { 'name': pack_id(opts.project) }
    287 else:
    288     if not opts.anonymous and user != None:
    289         msg['user'] = [ { 'userID': pack_id(user) } ]
    290     else:
    291         msg['user'] = [];
    292 
    293 if opts.debug > 1: print >>sys.stderr, msg
    294 
    295 if opts.transport == "soap":
    296     loc = feddServiceLocator();
    297     port = loc.getfeddPortType(opts.url,
    298             transport=M2Crypto.httpslib.HTTPSConnection,
    299             transdict={ 'ssl_context' : context },
    300             tracefile=opts.tracefile)
    301 
    302     req = RequestAccessRequestMessage()
    303 
    304     req.set_element_RequestAccessRequestBody(
    305             pack_soap(req, "RequestAccessRequestBody", msg))
    306 
    307     if opts.serialize_only:
    308         sw = SoapWriter()
    309         sw.serialize(req)
    310         print str(sw)
    311         sys.exit(0)
    312 
    313     try:
    314         resp = port.RequestAccess(req)
    315     except ZSI.ParseException, e:
    316         sys.exit("Malformed response (XMLPRC?): %s" % e)
    317     except ZSI.FaultException, e:
    318         resp = e.fault.detail[0]
    319 
    320     if (resp != None):
    321         if 'get_element_RequestAccessResponseBody' in dir(resp):
    322             resp_body = resp.get_element_RequestAccessResponseBody()
    323             if ( resp_body != None):
    324                 try:
    325                     resp_dict = unpack_soap(resp_body)
    326                     if opts.debug > 1: print >>sys.stderr, resp_dict
    327                     print_response_as_testbed(resp_dict, opts.label)
    328                 except RuntimeError, e:
    329                     sys.exit("Bad response. %s" % e.message)
    330         elif 'get_element_FeddFaultBody' in dir(resp):
    331             resp_body = resp.get_element_FeddFaultBody()
    332             if resp_body != None:
    333                 exit_with_fault(unpack_soap(resp_body))
    334         else: sys.exit("No body in response!?")
    335     else: sys.exit("No response?!?")
    336 elif opts.transport == "xmlrpc":
    337     if opts.serialize_only:
    338         ser = dumps((msg,))
    339         sys.exit(0)
    340 
    341     transport = SSL_Transport(context)
    342     port = ServerProxy(opts.url, transport=transport)
    343 
    344     try:
    345         resp = port.RequestAccess({ 'RequestAccessRequestBody': msg})
    346         resp, method = loads(resp)
    347     except Error, e:
    348         resp = { 'FeddFaultBody': \
    349                 { 'errstr' : e.faultCode, 'desc' : e.faultString } }
    350 
    351 
    352     if (resp != None):
    353         if resp.has_key('RequestAccessReponseBody'):
    354             try:
    355                 resp_dict = resp[0]['RequestAccessResponseBody']
    356                 if opts.debug > 1: print >>sys.stderr, resp_dict
    357                 print_response_as_testbed(resp_dict, opts.label)
    358             except RuntimeError, e:
    359                 sys.exit("Bad response. %s" % e.messgae)
    360         elif resp.has_key('FeddFaultBody'):
    361             exit_with_fault(resp['FeddFaultBody'])
    362         else: sys.exit("No body in response!?")
    363 
    364     else: sys.exit("No response?!?")
     620    sys.exit("Bad command: %s.  Valid ones are: %s" % \
     621            (sys.argv[1], ", ".join(cmds.keys())))
     622
Note: See TracChangeset for help on using the changeset viewer.