Changeset d81971a for fedd/fedd_access.py
- Timestamp:
- Nov 17, 2008 6:19:40 PM (15 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-1.30, version-2.00, version-3.01, version-3.02
- Children:
- 7583a62
- Parents:
- afa43a8
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/fedd_access.py
rafa43a8 rd81971a 14 14 import string 15 15 import copy 16 import pickle 16 17 17 18 from fedd_access_project import access_project … … 224 225 self.restricted = [ ] 225 226 self.fedid_category = { } 227 self.projects = { } 228 self.keys = { } 229 self.allocation = { } 230 self.state = { 231 'projects': self.projects, 232 'allocation' : self.allocation, 233 'keys' : self.keys 234 } 226 235 self.fedid_default = "testbed" 227 236 if config.has_option("access", "accessdb"): … … 230 239 self.read_trust(config.get("access", "trustdb")) 231 240 241 self.state_filename = config.get("access", "access_state", "") 232 242 self.log = logging.getLogger("fedd.access") 243 self.read_state() 244 233 245 234 246 # Certs are promoted from the generic to the specific, so without a … … 279 291 RequestAccessRequestMessage.typecode,\ 280 292 self.RequestAccess, RequestAccessResponseMessage,\ 281 "RequestAccessResponseBody")\ 293 "RequestAccessResponseBody"), \ 294 'ReleaseAccess': make_soap_handler(\ 295 ReleaseAccessRequestMessage.typecode,\ 296 self.ReleaseAccess, ReleaseAccessResponseMessage,\ 297 "ReleaseAccessResponseBody")\ 282 298 } 283 299 self.xmlrpc_services = {\ 284 300 'RequestAccess': make_xmlrpc_handler(\ 285 self.RequestAccess, "RequestAccessResponseBody")\ 301 self.RequestAccess, "RequestAccessResponseBody"),\ 302 'ReleaseAccess': make_xmlrpc_handler(\ 303 self.ReleaseAccess, "ReleaseAccessResponseBody")\ 286 304 } 287 305 … … 326 344 else: 327 345 return None 346 347 def write_state(self): 348 try: 349 f = open(self.state_filename, 'w') 350 pickle.dump(self.state, f) 351 except IOError, e: 352 self.log.error("Can't write file %s: %s" % \ 353 (self.state_filename, e)) 354 except pickle.PicklingError, e: 355 self.log.error("Pickling problem: %s" % e) 356 except TypeError, e: 357 self.log.error("Pickling problem (TypeError): %s" % e) 358 359 360 def read_state(self): 361 """ 362 Read a new copy of access state. Old state is overwritten. 363 364 State format is a simple pickling of the state dictionary. 365 """ 366 try: 367 f = open(self.state_filename, "r") 368 self.state = pickle.load(f) 369 370 self.allocation = self.state['allocation'] 371 self.projects = self.state['projects'] 372 self.keys = self.state['keys'] 373 374 self.log.debug("[read_state]: Read state from %s" % \ 375 self.state_filename) 376 except IOError, e: 377 self.log.warning("[read_state]: No saved state: Can't open %s: %s"\ 378 % (self.state_filename, e)) 379 except EOFError, e: 380 self.log.warning("[read_state]: Empty or damaged state file: %s:"\ 381 % self.state_filename) 382 except pickle.UnpicklingError, e: 383 self.log.warning(("[read_state]: No saved state: " + \ 384 "Unpickling failed: %s") % e) 385 328 386 329 387 def proxy_xmlrpc_request(self, dt, req): … … 649 707 ap = self.allocate_project.dynamic_project(preq) 650 708 else: 651 # XXX ssh key additions652 709 preq = {'StaticProjectRequestBody' : \ 653 710 { 'project': \ … … 677 734 raise service_error(service_error.req, 678 735 "SSH access parameters required") 679 736 # keep track of what's been added 737 if req['allocID'].has_key('fedid'): 738 aid = unicode(req['allocId']['fedid']) 739 elif req['allocID'].has_key('localname'): 740 aid = req['allocID']['localname'] 741 else: 742 raise service_error(service_error.req, "Bad allocation ID") 743 744 self.allocation[aid] = { } 745 if dyn[1]: 746 try: 747 pname = ap['project']['name']['localname'] 748 except KeyError: 749 raise service_error(service_error.internal, 750 "Misformed allocation response?") 751 if self.projects.has_key(pname): self.projects[pname] += 1 752 else: self.projects[pname] = 1 753 self.allocation[aid]['project'] = pname 754 755 self.allocation[aid]['keys'] = [ ] 756 757 try: 758 for u in ap['project']['user']: 759 uname = u['userID']['localname'] 760 for k in [ k['sshPubkey'] for k in u['access'] \ 761 if k.has_key('sshPubkey') ]: 762 kv = "%s:%s" % (uname, k) 763 if self.keys.has_key(kv): self.keys[kv] += 1 764 else: self.keys[kv] = 1 765 self.allocation[aid]['keys'].append((uname, k)) 766 except KeyError: 767 raise service_error(service_error.internal, 768 "Misformed allocation response?") 769 770 self.write_state() 680 771 resp = self.build_response(req['allocID'], ap) 681 772 return resp … … 707 798 service_error.proxy, 708 799 "Undefined fault from proxy??"); 800 801 def ReleaseAccess(self, req, fid): 802 # The dance to get into the request body 803 if req.has_key('ReleaseAccessRequestBody'): 804 req = req['ReleaseAccessRequestBody'] 805 else: 806 raise service_error(service_error.req, "No request!?") 807 808 print req 809 try: 810 if req['allocID'].has_key('localname'): 811 aid = req['allocID']['localname'] 812 elif req['allocID'].has_key('fedid'): 813 aid = unicode(req['allocID']['fedid']) 814 else: 815 raise service_error(service_error.req, 816 "Only localnames and fedids are understood") 817 except KeyError: 818 raise service_error(service_error.req, "Badly formed request") 819 820 # If we know this allocation, reduce the reference counts and remove 821 # the local allocations. Otherwise report an error. If there is an 822 # allocation to delete, del_users will be a dictonary of sets where the 823 # key is the user that owns the keys in the set. We use a set to avoid 824 # duplicates. del_project is just the name of any dynamic project to 825 # delete. 826 del_users = { } 827 del_project = None 828 if self.allocation.has_key(aid): 829 for k in self.allocation[aid]['keys']: 830 kk = "%s:%s" % k 831 self.keys[kk] -= 1 832 if self.keys[kk] == 0: 833 if not del_users.has_key(k[0]): 834 del_users[k[0]] = set() 835 del_users[k[0]].add(k[1]) 836 del self.keys[kk] 837 838 if self.allocation[aid].has_key('project'): 839 pname = self.allocation[aid]['project'] 840 self.projects[pname] -= 1 841 if self.projects[pname] == 0: 842 del_project = pname 843 del self.projects[pname] 844 845 del self.allocation[aid] 846 # If we actually have resources to deallocate, prepare the call. 847 if del_project or del_users: 848 msg = { 'project': { }} 849 if del_project: 850 msg['project']['name']['localname'] = del_project 851 users = [ ] 852 for u in del_users.keys(): 853 users.append({ 'userID': { 'localname': u },\ 854 'access' : \ 855 [ {'sshPubkey' : s } for s in del_users[u]]\ 856 }) 857 if users: 858 msg['project']['user'] = users 859 print msg 860 self.write_state() 861 return { 'allocID': req['allocID'] } 862 else: 863 raise service_error(service_error.req, "No such allocation") 864 865 866
Note: See TracChangeset
for help on using the changeset viewer.