Changeset 4064742
- Timestamp:
- Nov 23, 2008 8:20:05 PM (16 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
- Children:
- bf0a80e
- Parents:
- 0df6015
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd_experiment_control.py
r0df6015 r4064742 178 178 self.trusted_certs = config.get(s, "trusted_certs") 179 179 180 180 181 self.exp_stem = "fed-stem" 181 182 self.log = logging.getLogger("fedd.experiment_control") … … 190 191 self.ssh_identity_file = None 191 192 193 # XXX remove if/else? 192 194 if config.has_section("experiment_control"): 193 195 self.debug = config.get("experiment_control", "create_debug") … … 196 198 self.splitter_url = config.get("experiment_control", "splitter_url") 197 199 self.fedkit = config.get("experiment_control", "fedkit") 200 accessdb_file = config.get("experiment_control", "accessdb") 198 201 else: 199 202 self.debug = False … … 236 239 if self.ssh_pubkey_file: 237 240 try: 238 print "reading %s" % self.ssh_pubkey_file239 241 f = open(self.ssh_pubkey_file, 'r') 240 242 self.ssh_pubkey = f.read() … … 252 254 253 255 set_log_level(config, "experiment_control", self.log) 256 257 if auth: 258 self.auth = auth 259 else: 260 self.log.error(\ 261 "[access]: No authorizer initialized, creating local one.") 262 auth = authorizer() 263 264 if accessdb_file: 265 try: 266 self.accessdb = self.read_accessdb(accessdb_file) 267 except IOError: 268 raise service_error(service_error.internal, 269 "Error opening %s as experiment control accessdb" % \ 270 accessdb_file) 271 for fid in self.accessdb.keys(): 272 self.auth.set_attribute(fid, 'create') 273 else: 274 raise service_error(service_error.internal, 275 "No accessdb specified in config") 254 276 255 277 # Grab saved state. OK to do this w/o locking because it's read only … … 360 382 self.log.warning(("[read_state]: No saved state: " + \ 361 383 "Unpickling failed: %s") % e) 384 385 for k in self.state.keys(): 386 try: 387 # This list should only have one element in it, but phrasing it 388 # as a for loop doesn't cost much, really. We have to find the 389 # fedid elements anyway. 390 for eid in [ f['fedid'] \ 391 for f in self.state[k]['experimentID']\ 392 if f.has_key('fedid') ]: 393 self.auth.set_attribute(self.state[k]['owner'], eid) 394 except KeyError, e: 395 self.log.warning("[read_state]: State ownership or identity " +\ 396 "misformatted in %s: %s" % (self.state_filename, e)) 397 398 399 def read_accessdb(self, accessdb_file): 400 access = {} 401 name_expr = "[" + string.ascii_letters + string.digits + "\.\-]+" 402 project_line = re.compile("^\s*fedid:([" + string.hexdigits + "]+)"+ \ 403 "\s*->\(\s*("+name_expr+")\s*,\s*("+name_expr+")\s*\)\s*$") 404 user_line = re.compile("^\s*fedid:([" + string.hexdigits + "]+)"+ \ 405 "\s*->\s*(" + name_expr + ")\s*$") 406 lineno = 0 407 408 f = open(accessdb_file, "r") 409 for line in f: 410 lineno += 1 411 line.strip() 412 if len(line) == 0 or line.startswith('#'): 413 continue 414 m = project_line.match(line) 415 if m: 416 fid = fedid(hexstr=m.group(1)) 417 project, user = m.group(2,3) 418 if not access.has_key(fid): 419 access[fid] = [] 420 access[fid].append((project, user)) 421 continue 422 423 m = user_line.match(line) 424 if m: 425 fid = fedid(hexstr=m.group(1)) 426 project = None 427 user = m.group(2) 428 if not access.has_key(fid): 429 access[fid] = [] 430 access[fid].append((project, user)) 431 continue 432 raise service_error(service_error.internal, 433 "Error parsing access db %s at line %d" % \ 434 (accessdb_file, lineno)) 435 f.close() 436 return access 437 362 438 363 439 def scp_file(self, file, user, host, dest=""): … … 793 869 else: return None 794 870 795 def get_access(self, tb, nodes, user, tbparam, master, export_project): 871 def get_access(self, tb, nodes, user, tbparam, master, export_project, 872 access_user): 796 873 """ 797 874 Get access to testbed through fedd and set the parameters for that tb … … 824 901 825 902 826 # The basic request 827 req = {\ 828 'destinationTestbed' : { 'uri' : uri }, 829 'user': user, 830 'allocID' : { 'localname': 'test' }, 831 'createAccess' : [ { 'sshPubkey' : self.ssh_pubkey } ], 832 'serviceAccess' : service_keys 833 } 834 835 print "service %s" % service_keys 836 print "ssh pubkey %s" % self.ssh_pubkey 837 print "ssh pubkey file %s" % self.ssh_pubkey_file 838 839 if tb == master: 840 # NB, the export_project parameter is a dict that includes 841 # the type 842 req['exportProject'] = export_project 843 844 # node resources if any 845 if nodes != None and len(nodes) > 0: 846 rnodes = [ ] 847 for n in nodes: 848 rn = { } 849 image, hw, count = n.split(":") 850 if image: rn['image'] = [ image ] 851 if hw: rn['hardware'] = [ hw ] 852 if count: rn['count'] = int(count) 853 rnodes.append(rn) 854 req['resources']= { } 855 req['resources']['node'] = rnodes 856 857 r = self.call_RequestAccess(uri, req, 858 self.cert_file, self.cert_pwd, self.trusted_certs) 859 860 if r.has_key('RequestAccessResponseBody'): 861 r = r['RequestAccessResponseBody'] 862 else: 863 raise service_error(service_error.protocol, 864 "Bad proxy response") 903 for p, u in access_user: 904 905 if p: 906 # Request with user and project specified 907 req = {\ 908 'destinationTestbed' : { 'uri' : uri }, 909 'project': { 910 'name': {'localname': p}, 911 'user': [ {'userID': { 'localname': u } } ], 912 }, 913 'user': user, 914 'allocID' : { 'localname': 'test' }, 915 'createAccess' : [ { 'sshPubkey' : self.ssh_pubkey } ], 916 'serviceAccess' : service_keys 917 } 918 else: 919 # Request with only user specified 920 req = {\ 921 'destinationTestbed' : { 'uri' : uri }, 922 'user': [ {'userID': { 'localname': u } } ], 923 'allocID' : { 'localname': 'test' }, 924 'createAccess' : [ { 'sshPubkey' : self.ssh_pubkey } ], 925 'serviceAccess' : service_keys 926 } 927 928 if tb == master: 929 # NB, the export_project parameter is a dict that includes 930 # the type 931 req['exportProject'] = export_project 932 933 # node resources if any 934 if nodes != None and len(nodes) > 0: 935 rnodes = [ ] 936 for n in nodes: 937 rn = { } 938 image, hw, count = n.split(":") 939 if image: rn['image'] = [ image ] 940 if hw: rn['hardware'] = [ hw ] 941 if count: rn['count'] = int(count) 942 rnodes.append(rn) 943 req['resources']= { } 944 req['resources']['node'] = rnodes 945 946 try: 947 r = self.call_RequestAccess(uri, req, 948 self.cert_file, self.cert_pwd, self.trusted_certs) 949 except service_error, e: 950 if e.code == service_error.access: 951 r = None 952 continue 953 else: 954 raise e 955 956 if r.has_key('RequestAccessResponseBody'): 957 r = r['RequestAccessResponseBody'] 958 else: 959 raise service_error(service_error.protocol, 960 "Bad proxy response") 961 962 if not r: 963 raise service_error(service_error.access, 964 "Access denied by %s (%s)" % (tb, uri)) 865 965 866 966 e = r['emulab'] … … 1031 1131 self.get_access = get_access 1032 1132 1033 def __call__(self, line, user, tbparams, master, export_project): 1133 def __call__(self, line, user, tbparams, master, export_project, 1134 access_user): 1034 1135 # Testbed access parameters 1035 1136 if not self.in_allbeds: … … 1046 1147 tb = nodes.pop(0) 1047 1148 self.get_access(tb, nodes, user, tbparams, master, 1048 export_project )1149 export_project, access_user) 1049 1150 return True 1050 1151 … … 1355 1456 to instantiate them and start it all up. 1356 1457 """ 1458 1459 if not self.auth.check_attribute(fid, 'create'): 1460 raise service_error(service_error.access, "Create access denied") 1461 1357 1462 try: 1358 1463 tmpdir = tempfile.mkdtemp(prefix="split-") … … 1366 1471 tclfile = tmpdir + "/experiment.tcl" 1367 1472 tbparams = { } 1473 try: 1474 access_user = self.accessdb[fid] 1475 except KeyError: 1476 raise service_error(service_error.internal, 1477 "Access map and authorizer out of sync in " + \ 1478 "create_experiment for fedid %s" % fid) 1368 1479 1369 1480 pid = "dummy" … … 1479 1590 if parse_current_testbed(line, master, allocated, tbparams): 1480 1591 continue 1481 elif parse_allbeds(line, user, tbparams, master, export_project): 1592 elif parse_allbeds(line, user, tbparams, master, export_project, 1593 access_user): 1482 1594 continue 1483 1595 elif parse_gateways(line, allocated, tbparams): … … 1620 1732 'vtopo': vtopo,\ 1621 1733 'vis' : vis, 1734 'owner': fid, 1622 1735 'experimentID' : [\ 1623 1736 { 'fedid': expid }, { 'localname': eid },\ … … 1628 1741 self.state_lock.release() 1629 1742 1743 self.auth.set_attribute(fid, expid) 1744 self.auth.set_attribute(expid, expid) 1745 1630 1746 if not failed: 1631 1747 return resp … … 1633 1749 raise service_error(service_error.partial, \ 1634 1750 "Partial swap in on %s" % ",".join(succeeded)) 1751 1752 def check_experiment_access(self, fid, key): 1753 """ 1754 Confirm that the fid has access to the experiment. Though a request 1755 may be made in terms of a local name, the access attribute is always 1756 the experiment's fedid. 1757 """ 1758 if not isinstance(key, fedid): 1759 self.state_lock.acquire() 1760 if self.state.has_key(key): 1761 try: 1762 kl = [ f['fedid'] for f in self.state[key]['experimentID']\ 1763 if f.has_key('fedid') ] 1764 except KeyError: 1765 self.state_lock.release() 1766 raise service_error(service_error.internal, 1767 "No fedid for experiment %s when checking " +\ 1768 "access(!?)" % key) 1769 if len(kl) == 1: 1770 key = kl[0] 1771 else: 1772 self.state_lock.release() 1773 raise service_error(service_error.internal, 1774 "multiple fedids for experiment %s when " +\ 1775 "checking access(!?)" % key) 1776 else: 1777 self.state_lock.release() 1778 raise service_error(service_error.access, "Access Denied") 1779 self.state_lock.release() 1780 1781 if self.auth.check_attribute(fid, key): 1782 return True 1783 else: 1784 raise service_error(service_error.access, "Access Denied") 1785 1635 1786 1636 1787 … … 1658 1809 raise service_error(service_error.req, "No request?") 1659 1810 1811 self.check_experiment_access(fid, key) 1812 1660 1813 self.state_lock.acquire() 1661 1814 if self.state.has_key(key): … … 1691 1844 raise service_error(service_error.req, "No request?") 1692 1845 1846 self.check_experiment_access(fid, key) 1847 1693 1848 self.state_lock.acquire() 1694 1849 if self.state.has_key(key): … … 1723 1878 else: 1724 1879 raise service_error(service_error.req, "No request?") 1880 1881 self.check_experiment_access(fid, key) 1725 1882 1726 1883 # The state may be massaged by the service function that called … … 1758 1915 else: 1759 1916 raise service_error(service_error.req, "No request?") 1917 1918 self.check_experiment_access(fid, key) 1760 1919 1761 1920 self.state_lock.acquire()
Note: See TracChangeset
for help on using the changeset viewer.