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