Changeset f8582c9


Ignore:
Timestamp:
Nov 18, 2008 8:32:05 PM (15 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:
dab4d56
Parents:
fd729b9
Message:

Resource allocation and deallocation really working
Access handler selects allocation ID
Fedid allocation IDs work
Revamp of util code for maodifying messages (e.g. binaries)
Handlers now see fedids as objects in messages
Fedid bug in handlers in fedd_util

This should have been multiple commits

Location:
fedd
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_access.py

    rfd729b9 rf8582c9  
    1616import pickle
    1717
     18from threading import *
     19
    1820from fedd_access_project import access_project
    1921from fedd_services import *
     
    4951            "dynamic_projects_cert_pwd", "dynamic_projects_trusted_certs")
    5052    id_list_attrs = ("restricted",)
     53
     54    def __init__(self, config=None):
     55        """
     56        Initializer.  Pulls parameters out of the ConfigParser's access section.
     57        """
     58
     59        # Make sure that the configuration is in place
     60        if config:
     61            if not config.has_section("access"):
     62                config.add_section("access")
     63            if not config.has_section("globals"):
     64                config.add_section("globals")
     65        else:
     66            raise RunTimeError("No config to fedd_access")
     67
     68
     69        # Create instance attributes from the static lists
     70        for a in fedd_access.bool_attrs:
     71            if config.has_option("access", a):
     72                setattr(self, a, config.get("access", a))
     73            else:
     74                setattr(self, a, False)
     75
     76        for a in fedd_access.emulab_attrs + fedd_access.id_attrs:
     77            if config.has_option("access", a):
     78                setattr(self, a, config.get("access",a))
     79            else:
     80                setattr(self, a, None)
     81
     82        self.attrs = { }
     83        self.access = { }
     84        self.restricted = [ ]
     85        self.fedid_category = { }
     86        self.projects = { }
     87        self.keys = { }
     88        self.allocation = { }
     89        self.state = {
     90            'projects': self.projects,
     91            'allocation' : self.allocation,
     92            'keys' : self.keys
     93        }
     94        self.state_lock = Lock()
     95        self.fedid_default = "testbed"
     96        if config.has_option("access", "accessdb"):
     97            self.read_access(config.get("access", "accessdb"))
     98        if config.has_option("access", "trustdb"):
     99            self.read_trust(config.get("access", "trustdb"))
     100
     101        self.state_filename = config.get("access", "access_state", "")
     102        self.log = logging.getLogger("fedd.access")
     103        set_log_level(config, "access", self.log)
     104        self.read_state()
     105
     106
     107        # Certs are promoted from the generic to the specific, so without a
     108        # specific proxy certificate, the main certificates are used for
     109        # proxy interactions. If no dynamic project certificates, then
     110        # proxy certs are used, and if none of those the main certs.
     111
     112        if config.has_option("globals", "proxy_cert_file"):
     113            if not self.dynamic_projects_cert_file:
     114                self.dynamic_projects_cert_file = \
     115                        config.get("globals", "proxy_cert_file")
     116                if config.has_option("globals", "porxy_cert_pwd"):
     117                    self.dynamic_projects_cert_pwd = \
     118                            config.get("globals", "proxy_cert_pwd")
     119
     120        if config.has_option("globals", "proxy_trusted_certs"):
     121            if not self.dynamic_projects_trusted_certs:
     122                self.dynamic_projects_trusted_certs =\
     123                        config.get("globals", proxy_trusted_certs)
     124
     125        if config.has_option("globals", "cert_file"):
     126            has_pwd = config.has_option("globals", "cert_pwd")
     127            if not self.dynamic_projects_cert_file:
     128                self.dynamic_projects_cert_file = \
     129                        config.get("globals", "cert_file")
     130                if has_pwd:
     131                    self.dynamic_projects_cert_pwd = \
     132                            config.get("globals", "cert_pwd")
     133            if not self.proxy_cert_file:
     134                self.proxy_cert_file = config.get("globals", "cert_file")
     135                if has_pwd:
     136                    self.proxy_cert_pwd = config.get("globals", "cert_pwd")
     137
     138        if config.get("globals", "trusted_certs"):
     139            if not self.proxy_trusted_certs:
     140                self.proxy_trusted_certs = \
     141                        config.get("globals", "trusted_certs")
     142            if not self.dynamic_projects_trusted_certs:
     143                self.dynamic_projects_trusted_certs = \
     144                        config.get("globals", "trusted_certs")
     145
     146        proj_certs = (self.dynamic_projects_cert_file,
     147                self.dynamic_projects_trusted_certs,
     148                self.dynamic_projects_cert_pwd)
     149
     150        self.soap_services = {\
     151            'RequestAccess': make_soap_handler(\
     152                RequestAccessRequestMessage.typecode,\
     153                self.RequestAccess, RequestAccessResponseMessage,\
     154                "RequestAccessResponseBody"), \
     155            'ReleaseAccess': make_soap_handler(\
     156                ReleaseAccessRequestMessage.typecode,\
     157                self.ReleaseAccess, ReleaseAccessResponseMessage,\
     158                "ReleaseAccessResponseBody")\
     159            }
     160        self.xmlrpc_services =  {\
     161            'RequestAccess': make_xmlrpc_handler(\
     162                self.RequestAccess, "RequestAccessResponseBody"),\
     163            'ReleaseAccess': make_xmlrpc_handler(\
     164                self.ReleaseAccess, "ReleaseAccessResponseBody")\
     165            }
     166
     167
     168        if not config.has_option("access", "dynamic_projects_url"):
     169            self.allocate_project = \
     170                fedd_allocate_project_local(config)
     171        else:
     172            self.allocate_project = \
     173                fedd_allocate_project_remote(config)
     174
     175        # If the project allocator exports services, put them in this object's
     176        # maps so that classes that instantiate this can call the services.
     177        self.soap_services.update(self.allocate_project.soap_services)
     178        self.xmlrpc_services.update(self.allocate_project.xmlrpc_services)
    51179
    52180    def read_trust(self, trust):
     
    192320        f.close()
    193321
    194 
    195     def __init__(self, config=None):
    196         """
    197         Initializer.  Pulls parameters out of the ConfigParser's access section.
    198         """
    199 
    200         # Make sure that the configuration is in place
    201         if config:
    202             if not config.has_section("access"):
    203                 config.add_section("access")
    204             if not config.has_section("globals"):
    205                 config.add_section("globals")
    206         else:
    207             raise RunTimeError("No config to fedd_access")
    208 
    209 
    210         # Create instance attributes from the static lists
    211         for a in fedd_access.bool_attrs:
    212             if config.has_option("access", a):
    213                 setattr(self, a, config.get("access", a))
    214             else:
    215                 setattr(self, a, False)
    216 
    217         for a in fedd_access.emulab_attrs + fedd_access.id_attrs:
    218             if config.has_option("access", a):
    219                 setattr(self, a, config.get("access",a))
    220             else:
    221                 setattr(self, a, None)
    222 
    223         self.attrs = { }
    224         self.access = { }
    225         self.restricted = [ ]
    226         self.fedid_category = { }
    227         self.projects = { }
    228         self.keys = { }
    229         self.allocation = { }
    230         self.state = {
    231             'projects': self.projects,
    232             'allocation' : self.allocation,
    233             'keys' : self.keys
    234         }
    235         self.fedid_default = "testbed"
    236         if config.has_option("access", "accessdb"):
    237             self.read_access(config.get("access", "accessdb"))
    238         if config.has_option("access", "trustdb"):
    239             self.read_trust(config.get("access", "trustdb"))
    240 
    241         self.state_filename = config.get("access", "access_state", "")
    242         self.log = logging.getLogger("fedd.access")
    243         self.read_state()
    244 
    245 
    246         # Certs are promoted from the generic to the specific, so without a
    247         # specific proxy certificate, the main certificates are used for
    248         # proxy interactions. If no dynamic project certificates, then
    249         # proxy certs are used, and if none of those the main certs.
    250 
    251         if config.has_option("globals", "proxy_cert_file"):
    252             if not self.dynamic_projects_cert_file:
    253                 self.dynamic_projects_cert_file = \
    254                         config.get("globals", "proxy_cert_file")
    255                 if config.has_option("globals", "porxy_cert_pwd"):
    256                     self.dynamic_projects_cert_pwd = \
    257                             config.get("globals", "proxy_cert_pwd")
    258 
    259         if config.has_option("globals", "proxy_trusted_certs"):
    260             if not self.dynamic_projects_trusted_certs:
    261                 self.dynamic_projects_trusted_certs =\
    262                         config.get("globals", proxy_trusted_certs)
    263 
    264         if config.has_option("globals", "cert_file"):
    265             has_pwd = config.has_option("globals", "cert_pwd")
    266             if not self.dynamic_projects_cert_file:
    267                 self.dynamic_projects_cert_file = \
    268                         config.get("globals", "cert_file")
    269                 if has_pwd:
    270                     self.dynamic_projects_cert_pwd = \
    271                             config.get("globals", "cert_pwd")
    272             if not self.proxy_cert_file:
    273                 self.proxy_cert_file = config.get("globals", "cert_file")
    274                 if has_pwd:
    275                     self.proxy_cert_pwd = config.get("globals", "cert_pwd")
    276 
    277         if config.get("globals", "trusted_certs"):
    278             if not self.proxy_trusted_certs:
    279                 self.proxy_trusted_certs = \
    280                         config.get("globals", "trusted_certs")
    281             if not self.dynamic_projects_trusted_certs:
    282                 self.dynamic_projects_trusted_certs = \
    283                         config.get("globals", "trusted_certs")
    284 
    285         proj_certs = (self.dynamic_projects_cert_file,
    286                 self.dynamic_projects_trusted_certs,
    287                 self.dynamic_projects_cert_pwd)
    288 
    289         self.soap_services = {\
    290             'RequestAccess': make_soap_handler(\
    291                 RequestAccessRequestMessage.typecode,\
    292                 self.RequestAccess, RequestAccessResponseMessage,\
    293                 "RequestAccessResponseBody"), \
    294             'ReleaseAccess': make_soap_handler(\
    295                 ReleaseAccessRequestMessage.typecode,\
    296                 self.ReleaseAccess, ReleaseAccessResponseMessage,\
    297                 "ReleaseAccessResponseBody")\
    298             }
    299         self.xmlrpc_services =  {\
    300             'RequestAccess': make_xmlrpc_handler(\
    301                 self.RequestAccess, "RequestAccessResponseBody"),\
    302             'ReleaseAccess': make_xmlrpc_handler(\
    303                 self.ReleaseAccess, "ReleaseAccessResponseBody")\
    304             }
    305 
    306 
    307         if not config.has_option("access", "dynamic_projects_url"):
    308             self.allocate_project = \
    309                 fedd_allocate_project_local(config)
    310         else:
    311             self.allocate_project = \
    312                 fedd_allocate_project_remote(config)
    313 
    314         # If the project allocator exports services, put them in this object's
    315         # maps so that classes that instantiate this can call the services.
    316         self.soap_services.update(self.allocate_project.soap_services)
    317         self.xmlrpc_services.update(self.allocate_project.xmlrpc_services)
    318322
    319323    def dump_state(self):
     
    735739                        "SSH access parameters required")
    736740            # keep track of what's been added
    737             if req['allocID'].has_key('fedid'):
    738                 aid = unicode(req['allocId']['fedid'])
    739             elif req['allocID'].has_key('localname'):
    740                 aid = req['allocID']['localname']
    741             else:
    742                 raise service_error(service_error.req, "Bad allocation ID")
    743 
     741            allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log)
     742            aid = unicode(allocID)
     743
     744            self.state_lock.acquire()
    744745            self.allocation[aid] = { }
    745746            if dyn[1]:
     
    747748                    pname = ap['project']['name']['localname']
    748749                except KeyError:
     750                    self.state_lock.release()
    749751                    raise service_error(service_error.internal,
    750752                            "Misformed allocation response?")
     
    765767                        self.allocation[aid]['keys'].append((uname, k))
    766768            except KeyError:
     769                self.state_lock.release()
    767770                raise service_error(service_error.internal,
    768771                        "Misformed allocation response?")
    769772
    770773            self.write_state()
    771             resp = self.build_response(req['allocID'], ap)
     774            self.state_lock.release()
     775            resp = self.build_response({ 'fedid': allocID } , ap)
    772776            return resp
    773777        else:
     
    806810            raise service_error(service_error.req, "No request!?")
    807811
    808         print req
    809812        try:
    810813            if req['allocID'].has_key('localname'):
     
    827830        del_project = None
    828831        if self.allocation.has_key(aid):
     832            self.state_lock.acquire()
    829833            for k in self.allocation[aid]['keys']:
    830834                kk = "%s:%s" % k
     
    844848
    845849            del self.allocation[aid]
     850            self.write_state()
     851            self.state_lock.release()
    846852            # If we actually have resources to deallocate, prepare the call.
    847853            if del_project or del_users:
    848854                msg = { 'project': { }}
    849855                if del_project:
    850                     msg['project']['name']['localname'] =  del_project
     856                    msg['project']['name']= {'localname': del_project}
    851857                users = [ ]
    852858                for u in del_users.keys():
     
    860866                    msg = { 'ReleaseProjectRequestBody' : msg}
    861867                    self.allocate_project.release_project(msg)
    862             self.write_state()
    863868            return { 'allocID': req['allocID'] }
    864869        else:
  • fedd/fedd_allocate_project.py

    rfd729b9 rf8582c9  
    2020from fedd_internal_services import *
    2121from fedd_util import *
    22 import fixed_key
    23 import parse_detail
     22from fixed_resource import read_key_db, read_project_db
    2423from service_error import *
    2524import logging
     
    6059        fixed_key_db = config.get("access", "fixed_keys", None)
    6160        fixed_project_db = config.get("access", "fixed_projects", None)
    62         if fixed_key_db:
    63             try:
    64                 self.fixed_keys = fixed_key.read_db(fixed_key_db)
    65             except:
    66                 log.debug("Can't read fixed_key_db from %s" % fixed_key_db)
    67         else:
    68             self.fixed_keys = set()
    69 
    70         if fixed_project_db:
    71             try:
    72                 f = open(fixed_project_db, "r")
    73                 for line in f:
    74                     self.fixed_projects.add(line.rstrip())
    75                 f.close()
    76             except:
    77                 log.debug("Can't read fixed_project_db from %s" % \
    78                         fixed_project_db)
    79         else:
    80             self.fixed_projects = set()
    81 
    82 
     61        self.fixed_keys = set()
     62        self.fixed_projects = set()
     63
     64        # initialize the fixed resource sets
     65        for db, rset, fcn in (\
     66                (fixed_key_db, self.fixed_keys, read_key_db), \
     67                (fixed_project_db, self.fixed_projects, read_project_db)):
     68            if db:
     69                try:
     70                    rset.update(fcn(db))
     71                except:
     72                    self.log.debug("Can't read resources from %s" % db)
     73       
    8374        # Internal services are SOAP only
    8475        self.soap_services = {\
     
    9182                self.static_project, StaticProjectResponseMessage,\
    9283                "StaticProjectResponseBody"),\
    93                 #"ReleaseProject": make_soap_handler(\
    94                 #ReleaseProjectRequestMessage.typecode,\
    95                 #self.release_project, ReleaseProjectResponseMessage,\
    96                 #"ReleaseProjectResponseBody")\
     84                "ReleaseProject": make_soap_handler(\
     85                ReleaseProjectRequestMessage.typecode,\
     86                self.release_project, ReleaseProjectResponseMessage,\
     87                "ReleaseProjectResponseBody")\
    9788                }
    9889        self.xmlrpc_services = { }
     
    290281                    rc = subprocess.call(cmd)
    291282                except OSError, e:
    292                     print "Static project subprocess creation error "+ \
    293                                     "[%s] (%s)" %  (cmd[0], e.strerror)
    294283                    raise service_error(service_error.internal,
    295284                            "Static project subprocess creation error "+ \
     
    315304        users = []
    316305
    317         print "release %s" % req
    318306        try:
    319307            if req['ReleaseProjectRequestBody']['project'].has_key('name'):
     
    332320            for sk in [ k['sshPubkey'] for k in u.get('access', []) \
    333321                    if k.has_key('sshPubkey')]:
    334                 if (name, sk) not in self.fixed_keys:
     322                if (name.rstrip(), sk.rstrip()) not in self.fixed_keys:
    335323                    cmds.append((self.wap, self.addpubkey, '-R', '-w', \
    336324                            '-u', name, '-k', sk))
    337         if pname and pname not in fixed_projects:
     325        if pname and pname not in self.fixed_projects:
    338326            cmds.append((self.wap, self.rmproj, pname))
    339327
     
    346334                    rc = subprocess.call(cmd)
    347335                except OSError, e:
    348                     print "Release project subprocess creation error "+ \
    349                                     "[%s] (%s)" %  (cmd[0], e.strerror)
    350336                    raise service_error(service_error.internal,
    351337                            "Release project subprocess creation error "+ \
     
    425411            "StaticProjectRequestBody", StaticProjectRequestMessage,
    426412            "StaticProjectResponseBody")
     413    release_project = make_proxy("ReleaseProject",
     414            "ReleaseProjectRequestBody", ReleaseProjectRequestMessage,
     415            "ReleaseProjectResponseBody")
    427416
    428417    def __init__(self, config):
     
    468457        self.log = logging.getLogger("fedd.allocate.remote")
    469458        set_log_level(config, "access", self.log)
    470         self.release_project = None
  • fedd/fedd_experiment_control.py

    rfd729b9 rf8582c9  
    852852        # case, making all the subclasses of basestring into unicode strings
    853853        # unifies the response format and solves the problem.
    854         r = make_unicode(unpack_soap(resp))
     854        r = make_unicode(fedids_to_obj(unpack_soap(resp)))
    855855
    856856        if r.has_key('RequestAccessResponseBody'):
     
    896896        # The basic request
    897897        req = { 'allocID' : aid }
    898        
     898
    899899        # No retry loop here.  Proxy servers must correctly authenticate
    900900        # themselves without help
    901 
    902901        try:
    903902            ctx = fedd_ssl_context(self.cert_file,
     
    926925
    927926        # better error coding
    928 
    929 
    930927
    931928    def remote_splitter(self, uri, desc, master):
     
    16441641        os.rmdir(tmpdir)
    16451642
    1646         resp = { 'federant' : [ tbparams[tb]['federant'] \
     1643        # The deepcopy prevents the allocation ID and other binaries from being
     1644        # translated into other formats
     1645        resp = { 'federant' : [ copy.deepcopy(tbparams[tb]['federant']) \
    16471646                for tb in tbparams.keys() \
    16481647                    if tbparams[tb].has_key('federant') ],\
     
    16911690        if exp:
    16921691            if exp.has_key('fedid'):
    1693                 key = fedid(bits=exp['fedid'])
     1692                key = exp['fedid']
    16941693                keytype = "fedid"
    16951694            elif exp.has_key('localname'):
     
    17241723        if exp:
    17251724            if exp.has_key('fedid'):
    1726                 key = fedid(bits=exp['fedid'])
     1725                key = exp['fedid']
    17271726                keytype = "fedid"
    17281727            elif exp.has_key('localname'):
     
    17571756        if exp:
    17581757            if exp.has_key('fedid'):
    1759                 key = fedid(bits=exp['fedid'])
     1758                key = exp['fedid']
    17601759                keytype = "fedid"
    17611760            elif exp.has_key('localname'):
     
    17921791        if exp:
    17931792            if exp.has_key('fedid'):
    1794                 key = fedid(bits=exp['fedid'])
     1793                key = exp['fedid']
    17951794                keytype = "fedid"
    17961795            elif exp.has_key('localname'):
  • fedd/fedd_internal_bindings.wsdl

    rfd729b9 rf8582c9  
    5858        </fault>
    5959      </operation>
     60      <operation name="ReleaseProject">
     61        <documentation>
     62          The bindings of this operation are straightforward SOAP RPC 1.1.
     63        </documentation>
     64        <soap:operation soapAction="ReleaseProject"/>
     65        <input>
     66          <soap:body use="encoded" parts="tns:ReleaseProjectRequestBody"
     67            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     68            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     69        </input>
     70        <output>
     71          <soap:body use="encoded" parts="tns:ReleaseProjectResponseBody"
     72            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     73            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     74        </output>
     75        <fault>
     76          <soap:fault use="encoded"  name="tns:ReleaseProjectFault"
     77            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     78            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     79        </fault>
     80      </operation>
    6081      <operation name="Ns2Split">
    6182        <documentation>
  • fedd/fedd_internal_messages.wsdl

    rfd729b9 rf8582c9  
    3535  </message>
    3636
     37  <message name="ReleaseProjectRequestMessage">
     38    <part name="ReleaseProjectRequestBody" type="xsd1:projectAllocType"/>
     39  </message>
     40
     41  <message name="ReleaseProjectResponseMessage">
     42    <part name="ReleaseProjectResponseBody"
     43      type="xsd1:projectAllocResponseType"/>
     44  </message>
     45
    3746  <message name="Ns2SplitRequestMessage">
    3847    <part name="Ns2SplitRequestBody" type="xsd1:ns2SplitRequestType"/>
     
    6574      <fault name="InternalFault" message="tns:FaultMessage"/>
    6675    </operation>
     76    <operation name="ReleaseProject">
     77      <documentation>
     78        This internal interface allows the part of a fedd running on a machine
     79        other than the boss node of the emulab in question to release resources
     80        allocated to either a static or dynamic project.
     81      </documentation>
     82      <input message="tns:ReleaseProjectRequestMessage"/>
     83      <output message="tns:ReleaseProjectResponseMessage"/>
     84      <fault name="InternalFault" message="tns:FaultMessage"/>
     85    </operation>
    6786    <operation name="Ns2Split">
    6887      <documentation>
  • fedd/fedd_util.py

    rfd729b9 rf8582c9  
    192192        if attr: obj = attr()
    193193        else:
    194             print dir(container)
    195194            raise TypeError("%s does not have a new_%s attribute" % \
    196195                    (container, name))
     
    233232    else:
    234233        return element
     234def apply_to_tags(e, map):
     235    """
     236    Map is an iterable of ordered pairs (tuples) that map a key to a function.
     237    This function walks the given message and replaces any object with a key in
     238    the map with the result of applying that function to the object.
     239    """
     240    dict_type = type(dict())
     241    list_type = type(list())
     242    str_type = type(str())
     243
     244    if isinstance(e, dict_type):
     245        for k in e.keys():
     246            for tag, fcn in map:
     247                if k == tag:
     248                    if isinstance(e[k], list_type):
     249                        e[k] = [ fcn(b) for b in e[k]]
     250                    else:
     251                        e[k] = fcn(e[k])
     252                elif isinstance(e[k], dict_type):
     253                    apply_to_tags(e[k], map)
     254                elif isinstance(e[k], list_type):
     255                    for ee in e[k]:
     256                        apply_to_tags(ee, map)
     257    # Other types end the recursion - they should be leaves
     258    return e
     259
     260# These are all just specializations of apply_to_tags
     261def fedids_to_obj(e, tags=('fedid',)):
     262    """
     263    Turn the fedids in a message that are encoded as bitstrings into fedid
     264    objects.
     265    """
     266    map = [ (t, lambda x: fedid(bits=x)) for t in tags]
     267    return apply_to_tags(e, map)
    235268
    236269def encapsulate_binaries(e, tags):
    237270    """Walk through a message and encapsulate any dictionary entries in
    238271    tags into a binary object."""
    239     dict_type = type(dict())
    240     list_type = type(list())
    241     str_type = type(str())
    242 
    243     if isinstance(e, dict_type):
    244         for k in e.keys():
    245             if k in tags:
    246                 if isinstance(e[k], list_type):
    247                     bin_list = []
    248                     for ee in e[k]:
    249                         if getattr(ee, 'pack_xmlrpc', None):
    250                             bin_list.append(Binary(ee.pack_xmlrpc()))
    251                         else:
    252                             bin_list.append(Binary(ee))
    253                     e[k] = bin_list
    254                 elif getattr(e[k],'pack_xmlrpc', None):
    255                     e[k] = Binary(e[k].pack_xmlrpc())
    256                 else:
    257                     e[k] = Binary(e[k])
    258             elif isinstance(e[k], dict_type):
    259                 encapsulate_binaries(e[k], tags)
    260             elif isinstance(e[k], list_type):
    261                 for ee in e[k]:
    262                     encapsulate_binaries(ee, tags)
    263     # Other types end the recursion - they should be leaves
    264     return e
     272
     273    def to_binary(o):
     274        pack = getattr(o, 'pack_xmlrpc', None)
     275        if callable(pack): return Binary(pack())
     276        else: return Binary(o)
     277
     278    map = [ (t, to_binary) for t in tags]
     279    return apply_to_tags(e, map)
    265280
    266281def decapsulate_binaries(e, tags):
    267282    """Walk through a message and encapsulate any dictionary entries in
    268283    tags into a binary object."""
    269     dict_type = type(dict())
    270     list_type = type(list())
    271     str_type = type(str())
    272 
    273     if isinstance(e, dict_type):
    274         for k in e.keys():
    275             if k in tags:
    276                 if isinstance(e[k], list_type):
    277                     e[k] = [ b.data for b in e[k]]
    278                 else:
    279                     e[k] = e[k].data
    280             elif isinstance(e[k], dict_type):
    281                 decapsulate_binaries(e[k], tags)
    282             elif isinstance(e[k], list_type):
    283                 for ee in e[k]:
    284                     decapsulate_binaries(ee, tags)
    285     # Other types end the recursion - they should be leaves
    286     return e
    287 
     284
     285    map = [ (t, lambda x: x.data) for t in tags]
     286    return apply_to_tags(e, map)
     287#end of tag specializations
    288288
    289289def strip_unicode(obj):
     
    318318    Create a new certificate and derive a fedid from it.
    319319
    320     The fedid and the certificte are returned as a tuple.
     320    The fedid and the certificate are returned as a tuple.
    321321    """
    322322
     
    340340            if trace: call_out = trace
    341341            else:
    342                 log.debug("set to dev/null")
    343342                call_out = open("/dev/null", "w")
    344343
     
    382381        req = ps.Parse(typecode)
    383382
    384         msg = method(unpack_soap(req), fedid)
     383        msg = method(fedids_to_obj(unpack_soap(req)), fid)
    385384
    386385        resp = constructor()
     
    397396    return handler
    398397
    399 def make_xmlrpc_handler(method, body_name, input_binaries=('fedid',),
    400         output_binaries=('fedid',)):
     398def make_xmlrpc_handler(method, body_name):
    401399    """
    402400    Generate the handler code to unpack and pack SOAP requests and responses
     
    405403    The code to marshall and unmarshall XMLRPC parameters to and from a fedd
    406404    service is largely the same.  This helper creates such a handler.  The
    407     parameters are the method name, the name of the body struct that contains
    408     the response asn the list of fields that are encoded as Binary objects in
    409     the input and in the output.  A handler is created that takes the params
    410     response from an xm,lrpclib.loads on the incoming rpc and a fedid and
    411     responds with a hash representing the struct ro be returned to the other
    412     side.  On error None is returned.
     405    parameters are the method name, and the name of the body struct that
     406    contains the response.  A handler is created that takes the params response
     407    from an xmlrpclib.loads on the incoming rpc and a fedid and responds with
     408    a hash representing the struct ro be returned to the other side.  On error
     409    None is returned.  Fedid fields are decapsulated from binary and converted
     410    to fedid objects on input and encapsulated as Binaries on output.
    413411    """
    414412    def handler(params, fid):
    415         p = decapsulate_binaries(params[0], input_binaries)
    416         msg = method(p, fedid)
     413        decap_fedids = (('fedid', lambda x: fedid(bits=x.data)),)
     414
     415        #p = decapsulate_binaries(params[0], input_binaries)
     416        p = apply_to_tags(params[0], decap_fedids)
     417        msg = method(p, fid)
    417418
    418419        if msg != None:
    419             return encapsulate_binaries({ body_name: msg }, output_binaries)
     420            return encapsulate_binaries({ body_name: msg }, ('fedid',))
    420421        else:
    421422            return None
  • fedd/fixed_resource.py

    rfd729b9 rf8582c9  
    6868
    6969    class key_opts(OptionParser):
     70        """
     71        Options to the command line, pretty self describing
     72        """
    7073        def __init__(self):
    7174            OptionParser.__init__(self, usage="%prog " + \
     
    9093    parser = key_opts()
    9194    action = sys.argv[1]
    92     keys = set()
    9395
    9496    # Check the action
     
    9698    else: sys.exit("Bad action, must be one of %s" % ", ".join(actions))
    9799
    98     # Parse the options
     100    # Parse and check the the options for consistency
    99101    (opts, args) = parser.parse_args()
    100102    if not opts.file:
     
    149151                print >>sys.stderr, "Cannot delete (%s, %s): not in db" % \
    150152                        (user, key)
     153        # init action falls through to write an empty DB
    151154        write_key_db(opts.file, keys)
    152155    else:
     
    176179            else:
    177180                print >>sys.stderr, "Cannot delete %s: not in db" % project
     181
     182        # init action falls through to write an empty DB
    178183        write_project_db(opts.file, projects)
    179184
Note: See TracChangeset for help on using the changeset viewer.