source: fedd/federation/experiment_control_legacy.py @ 1d73342

axis_examplecompt_changesinfo-ops
Last change on this file since 1d73342 was 1d73342, checked in by Ted Faber <faber@…>, 13 years ago

Move non ABAC code out

  • Property mode set to 100644
File size: 6.5 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, access_user, masters, tbmap):
51        """
52        Get access to testbed through fedd and set the parameters for that tb
53        """
54        def get_export_project(svcs):
55            """
56            Look through for the list of federated_service for this testbed
57            objects for a project_export service, and extract the project
58            parameter.
59            """
60
61            pe = [s for s in svcs if s.name=='project_export']
62            if len(pe) == 1:
63                return pe[0].params.get('project', None)
64            elif len(pe) == 0:
65                return None
66            else:
67                raise service_error(service_error.req,
68                        "More than one project export is not supported")
69
70        uri = tbmap.get(testbed_base(tb), None)
71        if not uri:
72            raise service_error(service_error.server_config, 
73                    "Unknown testbed: %s" % tb)
74
75        export_svcs = masters.get(tb,[])
76        import_svcs = [ s for m in masters.values() \
77                for s in m \
78                    if tb in s.importers ]
79
80        export_project = get_export_project(export_svcs)
81
82        # Tweak search order so that if there are entries in access_user that
83        # have a project matching the export project, we try them first
84        if export_project: 
85            access_sequence = [ (p, u) for p, u in access_user \
86                    if p == export_project] 
87            access_sequence.extend([(p, u) for p, u in access_user \
88                    if p != export_project]) 
89        else: 
90            access_sequence = access_user
91
92        for p, u in access_sequence: 
93            self.log.debug(("[get_access] Attempting access from (%s, %s) " + \
94                    "to %s") %  ((p or "None"), u, uri))
95
96            if p:
97                # Request with user and project specified
98                req = {\
99                        'credential': [ "project: %s" % p, "user: %s"  % u],
100                    }
101            else:
102                # Request with only user specified
103                req = {\
104                        'credential': [ 'user: %s' % u ],
105                    }
106
107            # Make the service request from the services we're importing and
108            # exporting.  Keep track of the export request ids so we can
109            # collect the resulting info from the access response.
110            e_keys = { }
111            if import_svcs or export_svcs:
112                req['service'] = [ ]
113
114                for i, s in enumerate(import_svcs):
115                    idx = 'import%d' % i
116                    sr = {'id': idx, 'name': s.name, 'visibility': 'import' }
117                    if s.params:
118                        sr['fedAttr'] = [ { 'attribute': k, 'value': v } \
119                                for k, v in s.params.items()]
120                    req['service'].append(sr)
121
122                for i, s in enumerate(export_svcs):
123                    idx = 'export%d' % i
124                    e_keys[idx] = s
125                    sr = {'id': idx, 'name': s.name, 'visibility': 'export' }
126                    if s.params:
127                        sr['fedAttr'] = [ { 'attribute': k, 'value': v } 
128                                for k, v in s.params.items()]
129                    req['service'].append(sr)
130            try:
131                if self.local_access.has_key(uri):
132                    # Local access call
133                    req = { 'RequestAccessRequestBody' : req }
134                    r = self.local_access[uri].RequestAccess(req, 
135                            fedid(file=self.cert_file))
136                    r = { 'RequestAccessResponseBody' : r }
137                else:
138                    r = self.call_RequestAccess(uri, req, 
139                            self.cert_file, self.cert_pwd, self.trusted_certs)
140            except service_error, e:
141                if e.code == service_error.access:
142                    self.log.debug("[get_access] Access denied")
143                    r = None
144                    continue
145                else:
146                    raise e
147
148            if r.has_key('RequestAccessResponseBody'):
149                # Through to here we have a valid response, not a fault.
150                # Access denied is a fault, so something better or worse than
151                # access denied has happened.
152                r = r['RequestAccessResponseBody']
153                self.log.debug("[get_access] Access granted")
154                break
155            else:
156                raise service_error(service_error.protocol,
157                        "Bad proxy response")
158       
159        if not r:
160            raise service_error(service_error.access, 
161                    "Access denied by %s (%s)" % (tb, uri))
162
163        tbparam[tb] = { 
164                "allocID" : r['allocID'],
165                "uri": uri,
166                }
167
168        # Collect the responses corresponding to the services this testbed
169        # exports.  These will be the service requests that we will include in
170        # the start segment requests (with appropriate visibility values) to
171        # import and export the segments.
172        for s in r.get('service', []):
173            id = s.get('id', None)
174            if id and id in e_keys:
175                e_keys[id].reqs.append(s)
176
177        # Add attributes to parameter space.  We don't allow attributes to
178        # overlay any parameters already installed.
179        for a in r.get('fedAttr', []):
180            try:
181                if a['attribute'] and \
182                        isinstance(a['attribute'], basestring)\
183                        and not tbparam[tb].has_key(a['attribute'].lower()):
184                    tbparam[tb][a['attribute'].lower()] = a['value']
185            except KeyError:
186                self.log.error("Bad attribute in response: %s" % a)
187
188
189    def get_legacy_access_to_testbeds(self, testbeds, access_user, allocated, 
190            tbparams, masters, tbmap):
191        """
192        Request access to the various testbeds required for this instantiation
193        (passed in as testbeds).  User, access_user, expoert_project and master
194        are used to construct the correct requests.  Per-testbed parameters are
195        returned in tbparams.
196        """
197        for tb in testbeds:
198            self.get_access(tb, tbparams, access_user, masters, tbmap)
199            allocated[tb] = 1
200
Note: See TracBrowser for help on using the repository browser.