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