bug fix in upcalls
[plcapi.git] / PLC / SFA.py
1 import traceback
2 from types import StringTypes
3 from PLC.Sites import Sites
4 try:
5     from sfa.plc.api import GeniAPI
6     from sfa.plc.sfaImport import cleanup_string
7     from sfa.server.registry import Registries
8     from sfa.util.record import *
9     from sfa.trust.hierarchy import *
10     from sfa.util.misc import *
11     packages_imported = True
12 except:
13     packages_imported = False
14     
15 def wrap_exception(method):
16     def wrap(*args, **kwds):
17         try:
18             return method(*args, **kwds)
19         except:
20             traceback.print_exc()
21     return wrap
22
23 def required_packages_imported(method):
24     def wrap(*args, **kwds):
25         if packages_imported:
26             return method(*args, **kwds)
27         else:
28             return
29     return wrap         
30
31 class SFA:
32     
33     @wrap_exception
34     @required_packages_imported
35     def __init__(self, api):
36         
37         self.api = api
38         
39         # Get the path to the sfa server key/cert files from 
40         # the sfa hierarchy object
41         sfa_hierarchy = Hierarchy()
42         sfa_key_path = sfa_hierarchy.basedir
43         key_file = os.path.join(sfa_key_path, "server.key")
44         cert_file = os.path.join(sfa_key_path, "server.cert")
45     
46         # get a connection to our local sfa registry
47         # and a valid credential
48         self.sfa_api = GeniAPI(key_file = key_file, cert_file = cert_file)
49         self.sfa_api.interface = "plcapi"
50         registries = Registries(self.sfa_api)
51         self.registry = registries[self.sfa_api.hrn]
52         self.credential = self.sfa_api.getCredential()
53         self.authority = self.sfa_api.hrn
54         
55
56     def get_login_base(self, site_id):
57         sites = Sites(self.api, [site_id], ['login_base'])
58         login_base = sites[0]['login_base']
59         return login_base
60         
61
62     def get_login_bases(self, object):
63         login_bases = []
64         site_ids = []
65         
66         # get the site_ids
67         if object.has_key('site_id') and object['site_id']:
68             site_ids.append(object['site_id'])
69         elif object.has_key('site_ids') and object['site_ids']:
70             site_ids.extend(object['site_ids'])
71         else:
72             raise Exception
73
74         # get the login bases
75         for site_id in site_ids:
76             login_bases.append(self.get_login_base(site_id))
77
78         return login_bases
79
80     def get_object_hrn(self, type, object, authority, login_base):
81         parent_hrn = authority + "." + login_base 
82         if type in ['person', 'user']:
83             name_parts = object['email'].split("@")
84             hrn = parent_hrn + "." + name_parts[:1][0]
85         
86         elif type in ['slice']:
87             name_parts = object['name'].split("_")
88             hrn = parent_hrn + "." + name_parts[-1:][0]
89         
90         elif type in ['node']:
91             hrn = hostname_to_hrn(self.authority, login_base, object['hostname'])
92         
93         elif type in ['site', 'authority']:
94             hrn = parent_hrn
95         
96         else:
97             raise Exception, "Invalid record type %(type)s" % locals()
98
99         return hrn
100
101     def sfa_record_exists(self, hrn, type):
102         """
103         check if the record (hrn and type) already exist in our sfa db
104         """
105         exists = False
106         
107         # list is quicker than resolve
108         parent_hrn = get_authority(hrn)
109         if not parent_hrn: parent_hrn = hrn
110         records = self.registry.list(self.credential, parent_hrn)
111         for record in records: 
112             if record['type'] == type and record['hrn'] == hrn:
113                 exists = True
114         return exists 
115
116     @wrap_exception
117     @required_packages_imported
118     def update_record(self, object, type, login_bases = None):
119         # determine this objects site and login_base
120         if not login_bases:
121             login_bases = self.get_login_bases(object)
122
123         if isinstance(login_bases, StringTypes):
124             login_bases = [login_bases]
125
126         for login_base in login_bases:
127             login_base = cleanup_string(login_base)
128             parent_hrn = self.authority + "." + login_base
129                         
130             if type in ['person']:
131                 type = 'user'
132             elif type in ['site']:
133                 type = 'authority'
134         
135             # set the object hrn, tpye and create the sfa record 
136             # object 
137             object['hrn'] = self.get_object_hrn(type, object, self.authority, login_base)   
138             object['type'] = type
139             if type in ['user']:
140                 record = UserRecord(dict=object)
141
142             elif type in ['slice']:
143                 record = SliceRecord(dict=object)
144
145             elif type in ['node']:
146                 record = NodeRecord(dict=object)
147     
148             elif type in ['authority']:
149                 record = AuthorityRecord(dict=object)
150
151             else:
152                 raise Exception, "Invalid record type %(type)s" % locals()
153
154             # add the record to sfa
155             if not self.sfa_record_exists(object['hrn'], type):
156                 self.registry.register(self.credential, record)
157
158     @wrap_exception
159     @required_packages_imported
160     def delete_record(self, object, type, login_base = None):
161         if type in ['person']:
162             type = 'user'
163         elif type in ['site']:
164             type = 'authority'
165         
166         if type not in ['user', 'slice', 'node', 'authority']:
167             raise Exception, "Invalid type %(type)s" % locals()    
168      
169         if not login_base:
170             login_bases = self.get_login_bases(object)
171         else:
172             login_bases = [login_base]
173
174         for login_base in login_bases:
175             login_base = cleanup_string(login_base)
176             hrn = self.get_object_hrn(type, object, self.authority, login_base)
177             if self.sfa_record_exists(hrn, type):
178                 self.registry.remove(self.credential, type, hrn) 
179