Changeset 4ed10ae for fedd


Ignore:
Timestamp:
Nov 14, 2008 5:13:10 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:
afa43a8
Parents:
2dafa0c
Message:

Proxy key additions working

Location:
fedd
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd.py

    r2dafa0c r4ed10ae  
    110110    def send_fault(self, f, code=500):
    111111        """Send a SOAP encoded fault as reply"""
     112        print f
    112113        self.send_xml(f.AsSOAP(processContents="lax"), code)
    113114
  • fedd/fedd_access.py

    r2dafa0c r4ed10ae  
    3838    dynamically.  This implements both direct requests and proxies.
    3939    """
     40
     41    class parse_error(RuntimeError): pass
    4042
    4143    bool_attrs = ("dynamic_projects", "project_priority")
     
    8284                    self.fedid_category[fedid(hexstr=m.string)] = cat
    8385                else:
    84                     raise parse_error(\
     86                    raise self.parse_error(\
    8587                            "Bad fedid in trust file (%s) line: %d" % \
    8688                            (trust, lineno))
     
    9395            # Nothing matched - bad line, raise exception
    9496            f.close()
    95             raise parse_error(\
     97            raise self.parse_error(\
    9698                    "Unparsable line in trustfile %s line %d" % (trust, lineno))
    9799        f.close()
     
    121123        with a # are ignored.
    122124
    123         Parsing errors result in a parse_error exception being raised.
     125        Parsing errors result in a self.parse_error exception being raised.
    124126        """
    125127        lineno=0
     
    138140        access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+
    139141                key_name+'\s*\)\s*->\s*\('+access_proj + '\s*,\s*' +
    140                 access_name + '\s*\)', re.IGNORECASE)
     142                access_name + '\s*,\s*' + access_name + '\s*\)', re.IGNORECASE)
    141143
    142144        def parse_name(n):
     
    165167                continue
    166168
    167             # Access line (t, p, u) -> (ap, au) line
     169            # Access line (t, p, u) -> (ap, cu, su) line
    168170            m = access_re.match(line)
    169171            if m != None:
     
    174176                    aps[0] = fedid(hexstr=aps[0])
    175177
    176                 au = m.group(5)
    177                 if au.startswith("fedid:"):
    178                     au = fedid(hexstr=aus[len("fedid:"):])
    179 
    180                 access_val = (access_project(aps[0], aps[1:]), au)
     178                cu = parse_name(m.group(5))
     179                su = parse_name(m.group(6))
     180
     181                access_val = (access_project(aps[0], aps[1:]),
     182                        parse_name(m.group(5)), parse_name(m.group(6)))
    181183
    182184                self.access[access_key] = access_val
     
    185187            # Nothing matched to here: unknown line - raise exception
    186188            f.close()
    187             raise parse_error("Unknown statement at line %d of %s" % \
     189            raise self.parse_error("Unknown statement at line %d of %s" % \
    188190                    (lineno, config))
    189191        f.close()
     
    287289        if not config.has_option("access", "dynamic_projects_url"):
    288290            self.allocate_project = \
    289                 fedd_allocate_project_local(self.dynamic_projects,
    290                         None, proj_certs)
     291                fedd_allocate_project_local(config)
    291292        else:
    292293            self.allocate_project = \
    293                 fedd_allocate_project_remote(self.dynamic_projects,
    294                         config.get("access", "dynamic_projects_url"),
    295                         proj_certs)
     294                fedd_allocate_project_remote(config)
    296295
    297296        # If the project allocator exports services, put them in this object's
     
    328327            return None
    329328
    330     def strip_unicode(self, obj):
    331         """Loosly de-unicode an object"""
    332         if isinstance(obj, dict):
    333             for k in obj.keys():
    334                 obj[k] = self.strip_unicode(obj[k])
    335             return obj
    336         elif isinstance(obj, basestring):
    337             return str(obj)
    338         elif getattr(obj, "__iter__", None):
    339             return [ self.strip_unicode(x) for x in obj]
    340         else:
    341             return obj
    342 
    343329    def proxy_xmlrpc_request(self, dt, req):
    344330        """Send an XMLRPC proxy request.  Called if the SOAP RPC fails"""
     
    360346        else: url = str(dt)
    361347
    362         r = copy.deepcopy(req)
    363         self.strip_unicode(r)
     348        r = strip_unicode(copy.deepcopy(req))
    364349       
    365350        transport = SSL_Transport(ctx)
     
    517502        # resolve <dynamic> and <same> in found
    518503        dyn_proj = False
    519         dyn_user = False
     504        dyn_create_user = False
     505        dyn_service_user = False
    520506
    521507        if found[0].name == "<same>":
     
    535521        if found[1] == "<same>":
    536522            if user_match == "<any>":
    537                 if user != None: ru = user[0]
     523                if user != None: rcu = user[0]
    538524                else: raise service_error(\
    539525                        service_error.server_config,
    540526                        "Matched <same> on anonymous request")
    541527            else:
    542                 ru = user_match
     528                rcu = user_match
    543529        elif found[1] == "<dynamic>":
    544             ru = None
    545             dyn_user = True
     530            rcu = None
     531            dyn_create_user = True
    546532       
    547         return (rp, ru), (dyn_user, dyn_proj)
     533        if found[2] == "<same>":
     534            if user_match == "<any>":
     535                if user != None: rsu = user[0]
     536                else: raise service_error(\
     537                        service_error.server_config,
     538                        "Matched <same> on anonymous request")
     539            else:
     540                rsu = user_match
     541        elif found[2] == "<dynamic>":
     542            rsu = None
     543            dyn_service_user = True
     544
     545        return (rp, rcu, rsu), (dyn_create_user, dyn_service_user, dyn_proj)
    548546
    549547    def build_response(self, alloc_id, ap):
     
    612610                            "Access denied (nodetypes %s)" % \
    613611                            str(', ').join(inaccessible))
    614             # XXX: This allocates a single user for both service and creation.
    615             # This needs to be made more nuanced.
    616             tmp_ssh = [ x['sshPubkey'] \
    617                     for x in req['serviceAccess'] + req['createAccess'] \
    618                         if x.has_key('sshPubkey')]
    619 
    620             # Converting to a set collapses duplicates
    621             ssh = set(tmp_ssh)
    622 
    623             if len(ssh) > 0:
     612            # These collect the keys for teh two roles into single sets, one
     613            # for creation and one for service.  The sets are a simple way to
     614            # eliminate duplicates
     615            create_ssh = set([ x['sshPubkey'] \
     616                    for x in req['createAccess'] \
     617                        if x.has_key('sshPubkey')])
     618
     619            service_ssh = set([ x['sshPubkey'] \
     620                    for x in req['serviceAccess'] \
     621                        if x.has_key('sshPubkey')])
     622
     623            if len(create_ssh) > 0 and len(service_ssh) >0:
    624624                if dyn[1]:
    625625                    # Compose the dynamic project request
     
    628628                                { 'project' : {\
    629629                                    'user': [ \
    630                                     { 'access': [ { 'sshPubkey': s } ] } \
    631                                         for s in ssh ] \
     630                                    { \
     631                                        'access': [ { 'sshPubkey': s } \
     632                                            for s in service_ssh ],
     633                                         'role': "serviceAccess",\
     634                                    }, \
     635                                    { \
     636                                        'access': [ { 'sshPubkey': s } \
     637                                            for s in create_ssh ],
     638                                         'role': "experimentCreation",\
     639                                    }, \
     640                                    ], \
    632641                                    }\
    633642                                }\
     
    641650                else:
    642651                    # XXX ssh key additions
    643                     ap = { 'project': \
    644                             { 'name' : { 'localname' : found[0].name },\
    645                               'user' : [ {\
    646                                 'userID': { 'localname' : found[1] }, \
    647                                 'access': [ { 'sshPubkey': s } for s in ssh]}\
    648                                 ]\
     652                    preq = {'StaticProjectRequestBody' : \
     653                            { 'project': \
     654                                { 'name' : { 'localname' : found[0].name },\
     655                                  'user' : [ \
     656                                    {\
     657                                        'userID': { 'localname' : found[1] }, \
     658                                        'access': [ { 'sshPubkey': s }
     659                                            for s in create_ssh ],
     660                                        'role': 'experimentCreation'\
     661                                    },\
     662                                    {\
     663                                        'userID': { 'localname' : found[2] }, \
     664                                        'access': [ { 'sshPubkey': s }
     665                                            for s in service_ssh ],
     666                                        'role': 'serviceAccess'\
     667                                    },\
     668                                ]}\
    649669                            }\
    650670                    }
     671                    if restricted != None and len(restricted) > 0:
     672                        preq['StaticProjectRequestBody']['resources'] = \
     673                            [ {'node': { 'hardware' :  [ h ] } } \
     674                                    for h in restricted ]
     675                    ap = self.allocate_project.static_project(preq)
    651676            else:
    652677                raise service_error(service_error.req,
  • fedd/fedd_allocate_project.py

    r2dafa0c r4ed10ae  
    3535fl.addHandler(nullHandler())
    3636
     37
    3738class fedd_allocate_project_local:
    3839    """
    3940    Allocate projects on this machine in response to an access request.
    4041    """
    41     def __init__(self, dp=False, url=None, certs=None):
     42    def __init__(self, config):
    4243        """
    4344        Initializer.  Parses a configuration if one is given.
    4445        """
    4546
    46         self.dynamic_projects = dp
    47         self.wap = '/usr/testbed/sbin/wap'
    48         self.newproj = '/usr/testbed/sbin/newproj'
    49         self.mkproj = '/usr/testbed/sbin/mkproj'
    50         self.grantnodetype = '/usr/testbed/sbin/grantnodetype'
     47        self.debug = config.get("access", "debug_project", False)
     48        self.wap = config.get('access', 'wap', '/usr/testbed/sbin/wap')
     49        self.newproj = config.get('access', 'newproj',
     50                '/usr/testbed/sbin/newproj')
     51        self.mkproj = config.get('access', 'mkproj', '/usr/testbed/sbin/mkproj')
     52        self.addpubkey = config.get('access', 'addpubkey',
     53                '/usr/testbed/sbin/taddpubkey')
     54        self.grantnodetype = config.get('access', 'grantnodetype',
     55                '/usr/testbed/sbin/grantnodetype')
    5156        self.log = logging.getLogger("fedd.allocate.local")
     57        set_log_level(config, "access", self.log)
    5258
    5359        # Internal services are SOAP only
     
    5662                AllocateProjectRequestMessage.typecode,\
    5763                self.dynamic_project, AllocateProjectResponseMessage,\
    58                 "AllocateProjectResponseBody")\
     64                "AllocateProjectResponseBody"),
     65                "StaticProject": make_soap_handler(\
     66                StaticProjectRequestMessage.typecode,\
     67                self.static_project, StaticProjectResponseMessage,\
     68                "StaticProjectResponseBody")\
    5969                }
    6070        self.xmlrpc_services = { }
     
    179189        for cmd in cmds:
    180190            self.log.debug("[dynamic_project]: %s" % ' '.join(cmd))
    181             if self.dynamic_projects:
     191            if not self.debug:
    182192                try:
    183193                    rc = subprocess.call(cmd)
    184194                except OSerror, e:
    185                     raise fedd_proj.service_error(\
    186                             fedd_proj.service_error.internal,
     195                    raise service_error(service_error.internal,
    187196                            "Dynamic project subprocess creation error "+ \
    188197                                    "[%s] (%s)" %  (cmd[1], e.strerror))
    189198
    190199            if rc != 0:
    191                 raise fedd_proj.service_error(\
    192                         fedd_proj.service_error.internal,
     200                raise service_error(service_error.internal,
    193201                        "Dynamic project subprocess error " +\
    194202                                "[%s] (%d)" % (cmd[1], rc))
     
    207215        return rv
    208216
    209 
    210 class fedd_allocate_project_remote:
    211     """
    212     Allocate projects on a remote machine using the internal SOAP interface
    213     """
    214     def __init__(self, dp=False, url=None, certs=None):
    215         """
    216         Initializer.  Parses a configuration if one is given.
    217         """
    218 
    219         self.dynamic_projects = dp
    220         self.url = url
    221 
    222         if certs != None and isinstance(certs, type(tuple())):
    223             self.cert_file, self.trusted_certs, self.cert_pwd = certs
    224         else:
    225             self.cert_file, self.trusted_certs, self.cert_pwd = \
    226                     (None, None, None)
    227         self.soap_services = { }
    228         self.xmlrpc_services = { }
     217    def static_project(self, req, fedid=None):
     218        """
     219        Be certain that the local project in the request has access to the
     220        proper resources and users have correct keys.  Add them if necessary.
     221        """
     222
     223        cmds =  []
     224
     225        # While we should be more careful about this, for the short term, add
     226        # the keys to the specified users.
     227
     228        try:
     229            users = req['StaticProjectRequestBody']['project']['user']
     230            pname = req['StaticProjectRequestBody']['project']\
     231                    ['name']['localname']
     232            resources = req['StaticProjectRequestBody'].get('resources', [])
     233        except KeyError:
     234            raise service_error(service_error.req, "Badly formed request")
     235
     236
     237        for u in users:
     238            try:
     239                name = u['userID']['localname']
     240            except KeyError:
     241                raise service_error(service_error.req, "Badly formed user")
     242            for sk in [ k['sshPubkey'] for k in u.get('access', []) \
     243                    if k.has_key('sshPubkey')]:
     244                cmds.append((self.addpubkey, '-w', '-u', name, '-k', sk))
    229245       
    230     def dynamic_project(self, req, fedid=None):
     246
     247        # Add commands to grant access to any resources in the request.  The
     248        # list comprehension pulls out the hardware types in the node entries
     249        # in the resources list.
     250        for nt in [ h for r in resources \
     251                if r.has_key('node') and r['node'].has_key('hardware')\
     252                    for h in r['node']['hardware'] ] :
     253            cmds.append((self.wap, self.grantnodetype, '-p', pname, nt))
     254
     255        # Run the commands
     256        rc = 0
     257        for cmd in cmds:
     258            self.log.debug("[static_project]: %s" % ' '.join(cmd))
     259            if not self.debug:
     260                try:
     261                    rc = subprocess.call(cmd)
     262                except OSError, e:
     263                    print "Static project subprocess creation error "+ \
     264                                    "[%s] (%s)" %  (cmd[0], e.strerror)
     265                    raise service_error(service_error.internal,
     266                            "Static project subprocess creation error "+ \
     267                                    "[%s] (%s)" %  (cmd[0], e.strerror))
     268
     269            if rc != 0:
     270                raise service_error(service_error.internal,
     271                        "Static project subprocess error " +\
     272                                "[%s] (%d)" % (cmd[0], rc))
     273
     274        return { 'project': req['StaticProjectRequestBody']['project']}
     275
     276def make_proxy(method, req_name, req_alloc, resp_name):
     277    """
     278    Construct the proxy calling function from the given parameters.
     279    """
     280
     281    # Define the proxy, NB, the parameters to make_proxy are visible to the
     282    # definition of proxy.
     283    def proxy(self, req, fedid=None):
    231284        """
    232285        Send req on to a remote project instantiator.
    233286
    234         Req is just the projectAllocType object.  This function re-wraps it.
     287        Req is just the message to be sent.  This function re-wraps it.
    235288        It also rethrows any faults.
    236289        """
     290
    237291        # No retry loop here.  Proxy servers must correctly authenticate
    238292        # themselves without help
     
    249303                transdict={ 'ssl_context' : ctx })
    250304
    251         if req.has_key('AllocateProjectRequestBody'):
    252             req = req['AllocateProjectRequestBody']
     305        if req.has_key(req_name):
     306            req = req[req_name]
    253307        else:
    254308            raise service_error(service_error.req, "Bad formated request");
    255309
    256310        # Reconstruct the full request message
    257         msg = AllocateProjectRequestMessage()
    258         msg.set_element_AllocateProjectRequestBody(
    259                 pack_soap(msg, "AllocateProjectRequestBody", req))
     311        msg = req_alloc()
     312        set_elem = getattr(msg, "set_element_%s" % req_name)
     313        set_elem(pack_soap(msg, req_name, req))
    260314        try:
    261             resp = port.AllocateProject(msg)
     315            mattr = getattr(port, method)
     316            resp = mattr(msg)
    262317        except ZSI.ParseException, e:
    263318            raise service_error(service_error.proxy,
    264319                    "Bad format message (XMLRPC??): %s" % str(e))
     320        except ZSI.FaultException, e:
     321            resp = e.fault.detail[0]
     322
    265323        r = unpack_soap(resp)
    266324
    267         if r.has_key('AllocateProjectResponseBody'):
    268             return r['AllocateProjectResponseBody']
     325        if r.has_key(resp_name):
     326            return r[resp_name]
    269327        else:
    270328            raise service_error(service_error.proxy, "Bad proxy response")
    271 
     329    # NB: end of proxy function definition     
     330    return proxy
     331
     332class fedd_allocate_project_remote:
     333    """
     334    Allocate projects on a remote machine using the internal SOAP interface
     335    """
     336    dynamic_project = make_proxy("AllocateProject",
     337            "AllocateProjectRequestBody", AllocateProjectRequestMessage,
     338            "AllocateProjectResponseBody")
     339    static_project = make_proxy("StaticProject",
     340            "StaticProjectRequestBody", StaticProjectRequestMessage,
     341            "StaticProjectResponseBody")
     342
     343    def __init__(self, config):
     344        """
     345        Initializer.  Parses a configuration if one is given.
     346        """
     347
     348        self.debug = config.get("access", "debug_project", False)
     349        self.url = config.get("access", "dynamic_projects_url", "")
     350
     351        self.cert_file = config.get("access", "cert_file", None)
     352        self.cert_pwd = config.get("access", "cert_pwd", None)
     353        self.trusted_certs = config.get("access", "trusted_certs", None)
     354
     355        # Certs are promoted from the generic to the specific, so without a if
     356        # no dynamic project certificates, then proxy certs are used, and if
     357        # none of those the main certs.
     358
     359        if config.has_option("globals", "proxy_cert_file"):
     360            if not self.cert_file:
     361                self.cert_file = config.get("globals", "proxy_cert_file")
     362                if config.has_option("globals", "porxy_cert_pwd"):
     363                    self.cert_pwd = config.get("globals", "proxy_cert_pwd")
     364
     365        if config.has_option("globals", "proxy_trusted_certs") and \
     366                not self.trusted_certs:
     367                self.trusted_certs = \
     368                        config.get("globals", "proxy_trusted_certs")
     369
     370        if config.has_option("globals", "cert_file"):
     371            has_pwd = config.has_option("globals", "cert_pwd")
     372            if not self.cert_file:
     373                self.cert_file = config.get("globals", "cert_file")
     374                if has_pwd:
     375                    self.cert_pwd = config.get("globals", "cert_pwd")
     376
     377        if config.get("globals", "trusted_certs") and not self.trusted_certs:
     378                self.trusted_certs = \
     379                        config.get("globals", "trusted_certs")
     380
     381        self.soap_services = { }
     382        self.xmlrpc_services = { }
     383        self.log = logging.getLogger("fedd.allocate.remote")
     384        set_log_level(config, "access", self.log)
     385        #self.dynamic_project = fedd_allocate_project_remote.dynamic_project
     386        #self.static_project = fedd_allocate_project_remote.static_project
  • fedd/fedd_experiment_control.py

    r2dafa0c r4ed10ae  
    320320        except pickle.PicklingError, e:
    321321            self.log.error("Pickling problem: %s" % e)
     322        except TypeError, e:
     323            self.log.error("Pickling problem (TypeError): %s" % e)
    322324
    323325    # Call while holding self.state_lock
     
    441443            self.log.error("[start_segment]: can't open /dev/null: %s" %e)
    442444
    443         status = Popen(cmd, stdout=PIPE, stderr=dev_null)
    444         for line in status.stdout:
    445             m = state_re.match(line)
    446             if m: state = m.group(1)
    447             else:
    448                 m = no_exp_re.match(line)
    449                 if m: state = "none"
    450         rv = status.wait()
     445        if self.debug:
     446            state = 'swapped'
     447            rv = 0
     448        else:
     449            status = Popen(cmd, stdout=PIPE, stderr=dev_null)
     450            for line in status.stdout:
     451                m = state_re.match(line)
     452                if m: state = m.group(1)
     453                else:
     454                    m = no_exp_re.match(line)
     455                    if m: state = "none"
     456            rv = status.wait()
    451457
    452458        # If the experiment is not present the subcommand returns a non-zero
     
    766772        else: return None
    767773
    768 
    769774    def get_access(self, tb, nodes, user, tbparam):
    770775        """
     
    835840        except ZSI.ParseException, e:
    836841            raise service_error(service_error.req,
    837                     "Bad format message (XMLRPC??): %s" %
    838                     str(e))
    839         r = unpack_soap(resp)
     842                    "Bad format message (XMLRPC??): %s" % str(e))
     843        except ZSI.FaultException, e:
     844            resp = e.fault.detail[0]
     845
     846        # Again, weird incompatibilities rear their head.  userRoles, which are
     847        # restricted strings, seem to be encoded by ZSI as non-unicode strings
     848        # in a way that confuses the pickling and XMLRPC sending systems.
     849        # Explicitly unicoding them seems to fix this, though it concerns me
     850        # some.  It may be that these things are actually a ZSI string
     851        # subclass, and the character encoding is not the major issue.  In any
     852        # case, making all the subclasses of basestring into unicode strings
     853        # unifies the response format and solves the problem.
     854        r = make_unicode(unpack_soap(resp))
    840855
    841856        if r.has_key('RequestAccessResponseBody'):
     
    844859            raise service_error(service_error.proxy,
    845860                    "Bad proxy response")
    846 
    847861
    848862        e = r['emulab']
     
    868882                if key:
    869883                    tbparam[tb][key]= a['value']
    870 
     884       
    871885    def remote_splitter(self, uri, desc, master):
    872886
  • fedd/fedd_internal_bindings.wsdl

    r2dafa0c r4ed10ae  
    3737        </fault>
    3838      </operation>
     39      <operation name="StaticProject">
     40        <documentation>
     41          The bindings of this operation are straightforward SOAP RPC 1.1.
     42        </documentation>
     43        <soap:operation soapAction="StaticProject"/>
     44        <input>
     45          <soap:body use="encoded" parts="tns:StaticProjectRequestBody"
     46            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     47            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     48        </input>
     49        <output>
     50          <soap:body use="encoded" parts="tns:StaticProjectResponseBody"
     51            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     52            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     53        </output>
     54        <fault>
     55          <soap:fault use="encoded"  name="tns:StaticProjectFault"
     56            namespace="http://www.isi.edu/faber/fedd_internal.wsdl"
     57            encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
     58        </fault>
     59      </operation>
    3960      <operation name="Ns2Split">
    4061        <documentation>
  • fedd/fedd_internal_messages.wsdl

    r2dafa0c r4ed10ae  
    2626  </message>
    2727
     28  <message name="StaticProjectRequestMessage">
     29    <part name="StaticProjectRequestBody" type="xsd1:projectAllocType"/>
     30  </message>
     31
     32  <message name="StaticProjectResponseMessage">
     33    <part name="StaticProjectResponseBody"
     34      type="xsd1:projectAllocResponseType"/>
     35  </message>
     36
    2837  <message name="Ns2SplitRequestMessage">
    2938    <part name="Ns2SplitRequestBody" type="xsd1:ns2SplitRequestType"/>
     
    4352      <input message="tns:AllocateProjectRequestMessage"/>
    4453      <output message="tns:AllocateProjectResponseMessage"/>
    45       <fault name="AllocateProjectFault" message="tns:FaultMessage"/>
     54      <fault name="InternalFault" message="tns:FaultMessage"/>
     55    </operation>
     56    <operation name="StaticProject">
     57      <documentation>
     58        This internal interface allows the part of a fedd running on a machine
     59        other than the boss node of the emulab in question to request
     60        modification of a static project.  For example keys can be added or
     61        node access granted.
     62      </documentation>
     63      <input message="tns:StaticProjectRequestMessage"/>
     64      <output message="tns:StaticProjectResponseMessage"/>
     65      <fault name="InternalFault" message="tns:FaultMessage"/>
    4666    </operation>
    4767    <operation name="Ns2Split">
     
    5373      <input message="tns:Ns2SplitRequestMessage"/>
    5474      <output message="tns:Ns2SplitResponseMessage"/>
    55       <fault name="Ns2SplitFault" message="tns:FaultMessage"/>
     75      <fault name="InternalFault" message="tns:FaultMessage"/>
    5676    </operation>
    5777  </portType>
  • fedd/fedd_util.py

    r2dafa0c r4ed10ae  
    287287
    288288
     289def strip_unicode(obj):
     290    """Walk through a message and convert all strings to non-unicode strings"""
     291    if isinstance(obj, dict):
     292        for k in obj.keys():
     293            obj[k] = strip_unicode(obj[k])
     294        return obj
     295    elif isinstance(obj, basestring):
     296        return str(obj)
     297    elif getattr(obj, "__iter__", None):
     298        return [ strip_unicode(x) for x in obj]
     299    else:
     300        return obj
     301
     302def make_unicode(obj):
     303    """Walk through a message and convert all strings to unicode"""
     304    if isinstance(obj, dict):
     305        for k in obj.keys():
     306            obj[k] = make_unicode(obj[k])
     307        return obj
     308    elif isinstance(obj, basestring):
     309        return unicode(obj)
     310    elif getattr(obj, "__iter__", None):
     311        return [ make_unicode(x) for x in obj]
     312    else:
     313        return obj
     314
     315
    289316def generate_fedid(subj, bits=2048, log=None, dir=None, trace=sys.stderr):
    290317    """
     
    396423    return handler
    397424
     425
    398426def set_log_level(config, sect, log):
    399427    """ Set the logging level to the value passed in sect of config."""
Note: See TracChangeset for help on using the changeset viewer.