source: fedd/federation/experiment_control_legacy.py @ de2ef5c

compt_changesinfo-ops
Last change on this file since de2ef5c was 5ecb9a3, checked in by Ted Faber <faber@…>, 14 years ago

Checkpoint along the path to #10

Several create_experiment subtasks have been brokern out and the
get_access and get_legacy access signatures have been unified.

Part of #10

  • Property mode set to 100644
File size: 6.3 KB
Line 
1#!/usr/local/bin/python
2
3import os,sys
4
5import re
6import random
7import string
8import subprocess
9import tempfile
10import copy
11import pickle
12import logging
13import signal
14import time
15
16import traceback
17# For parsing visualization output and splitter output
18import xml.parsers.expat
19
20from threading import Lock, Thread, Condition
21from subprocess import call, Popen, PIPE
22from string import join
23
24from urlparse import urlparse
25from urllib2 import urlopen
26
27from util import *
28from fedid import fedid, generate_fedid
29from remote_service import xmlrpc_handler, soap_handler, service_caller
30from service_error import service_error
31from synch_store import synch_store
32from experiment_partition import experiment_partition
33from authorizer import abac_authorizer
34from thread_pool import thread_pool, pooled_thread
35
36import topdl
37import list_log
38from ip_allocator import ip_allocator
39from ip_addr import ip_addr
40
41
42class experiment_control_legacy:
43    """
44    This contains the legacy access control requests that can be included in
45    the experiment control component.  This will eventually be completely
46    removed.  It is also only functional in the context of an experiment
47    control object.
48    """
49
50    def get_legacy_access(self, tb, tbparam, fid, masters, tbmap, expid=None,
51            expcert=None):
52        """
53        Get access to testbed through fedd and set the parameters for that tb
54        """
55        def get_export_project(svcs):
56            """
57            Look through for the list of federated_service for this testbed
58            objects for a project_export service, and extract the project
59            parameter.
60            """
61
62            pe = [s for s in svcs if s.name=='project_export']
63            if len(pe) == 1:
64                return pe[0].params.get('project', None)
65            elif len(pe) == 0:
66                return None
67            else:
68                raise service_error(service_error.req,
69                        "More than one project export is not supported")
70
71        try:
72            access_user = self.accessdb[fid]
73        except KeyError:
74            raise service_error(service_error.internal,
75                    "Access map and authorizer out of sync in " + \
76                            "create_experiment for fedid %s"  % fid)
77
78        uri = tbmap.get(testbed_base(tb), None)
79        if not uri:
80            raise service_error(service_error.server_config, 
81                    "Unknown testbed: %s" % tb)
82
83        export_svcs = masters.get(tb,[])
84        import_svcs = [ s for m in masters.values() \
85                for s in m \
86                    if tb in s.importers ]
87
88        export_project = get_export_project(export_svcs)
89
90        # Tweak search order so that if there are entries in access_user that
91        # have a project matching the export project, we try them first
92        if export_project: 
93            access_sequence = [ (p, u) for p, u in access_user \
94                    if p == export_project] 
95            access_sequence.extend([(p, u) for p, u in access_user \
96                    if p != export_project]) 
97        else: 
98            access_sequence = access_user
99
100        for p, u in access_sequence: 
101            self.log.debug(("[get_access] Attempting access from (%s, %s) " + \
102                    "to %s") %  ((p or "None"), u, uri))
103
104            if p:
105                # Request with user and project specified
106                req = {\
107                        'credential': [ "project: %s" % p, "user: %s"  % u],
108                    }
109            else:
110                # Request with only user specified
111                req = {\
112                        'credential': [ 'user: %s' % u ],
113                    }
114
115            # Make the service request from the services we're importing and
116            # exporting.  Keep track of the export request ids so we can
117            # collect the resulting info from the access response.
118            e_keys = { }
119            if import_svcs or export_svcs:
120                req['service'] = [ ]
121
122                for i, s in enumerate(import_svcs):
123                    idx = 'import%d' % i
124                    sr = {'id': idx, 'name': s.name, 'visibility': 'import' }
125                    if s.params:
126                        sr['fedAttr'] = [ { 'attribute': k, 'value': v } \
127                                for k, v in s.params.items()]
128                    req['service'].append(sr)
129
130                for i, s in enumerate(export_svcs):
131                    idx = 'export%d' % i
132                    e_keys[idx] = s
133                    sr = {'id': idx, 'name': s.name, 'visibility': 'export' }
134                    if s.params:
135                        sr['fedAttr'] = [ { 'attribute': k, 'value': v } 
136                                for k, v in s.params.items()]
137                    req['service'].append(sr)
138            try:
139                if self.local_access.has_key(uri):
140                    # Local access call
141                    req = { 'RequestAccessRequestBody' : req }
142                    r = self.local_access[uri].RequestAccess(req, 
143                            fedid(file=self.cert_file))
144                    r = { 'RequestAccessResponseBody' : r }
145                else:
146                    r = self.call_RequestAccess(uri, req, 
147                            self.cert_file, self.cert_pwd, self.trusted_certs)
148            except service_error, e:
149                if e.code == service_error.access:
150                    self.log.debug("[get_access] Access denied")
151                    r = None
152                    continue
153                else:
154                    raise e
155
156            if r.has_key('RequestAccessResponseBody'):
157                # Through to here we have a valid response, not a fault.
158                # Access denied is a fault, so something better or worse than
159                # access denied has happened.
160                r = r['RequestAccessResponseBody']
161                self.log.debug("[get_access] Access granted")
162                break
163            else:
164                raise service_error(service_error.protocol,
165                        "Bad proxy response")
166       
167        if not r:
168            raise service_error(service_error.access, 
169                    "Access denied by %s (%s)" % (tb, uri))
170
171        tbparam[tb] = { 
172                "allocID" : r['allocID'],
173                "uri": uri,
174                }
175
176        # Collect the responses corresponding to the services this testbed
177        # exports.  These will be the service requests that we will include in
178        # the start segment requests (with appropriate visibility values) to
179        # import and export the segments.
180        for s in r.get('service', []):
181            id = s.get('id', None)
182            if id and id in e_keys:
183                e_keys[id].reqs.append(s)
184
185        # Add attributes to parameter space.  We don't allow attributes to
186        # overlay any parameters already installed.
187        for a in r.get('fedAttr', []):
188            try:
189                if a['attribute'] and \
190                        isinstance(a['attribute'], basestring)\
191                        and not tbparam[tb].has_key(a['attribute'].lower()):
192                    tbparam[tb][a['attribute'].lower()] = a['value']
193            except KeyError:
194                self.log.error("Bad attribute in response: %s" % a)
195
196
Note: See TracBrowser for help on using the repository browser.