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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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,
Note: See TracChangeset for help on using the changeset viewer.