Added support for new slice table for Senslab.
[sfa.git] / sfa / senslab / slab-import.py
1 ###########################################################################
2 #    Copyright (C) 2011 by root                                      
3 #    <root@FlabFedora2>                                                             
4 #
5 # Copyright: See COPYING file that comes with this distribution
6 #
7 ###########################################################################
8 import sys
9 import datetime
10 import time
11 from sfa.senslab.OARrestapi import OARapi
12 from sfa.senslab.LDAPapi import LDAPapi
13 from sfa.senslab.slabdriver import SlabDriver
14 from sfa.senslab.slabpostgres import SlabDB
15 from sfa.util.config import Config
16 from sfa.util.xrn import hrn_to_urn, get_authority,Xrn,get_leaf
17 from sfa.util.table import SfaTable
18 from sfa.util.record import SfaRecord
19 from sfa.trust.hierarchy import Hierarchy
20 from sfa.trust.certificate import Keypair,convert_public_key
21 from sfa.trust.gid import create_uuid
22 from sfa.trust.trustedroots import TrustedRoots
23
24 config = Config()
25 TrustedR = TrustedRoots(Config.get_trustedroots_dir(config))
26 AuthHierarchy = Hierarchy()
27 table = SfaTable()
28 db = SlabDB()
29 if not table.exists():
30     table.create()
31     
32     
33 def create_sm_client_record():
34     """
35     Create a user record for the Slicemanager service.
36     """
37     hrn = config.SFA_INTERFACE_HRN + '.slicemanager'
38     urn = hrn_to_urn(hrn, 'user')
39     if not AuthHierarchy.auth_exists(urn):
40         AuthHierarchy.create_auth(urn)
41
42     auth_info = AuthHierarchy.get_auth_info(hrn)
43     table = SfaTable()
44     sm_user_record = table.find({'type': 'user', 'hrn': hrn})
45     if not sm_user_record:
46         record = SfaRecord(hrn=hrn, gid=auth_info.get_gid_object(), type="user", pointer=-1)
47         record['authority'] = get_authority(record['hrn'])
48         table.insert(record)
49                 
50 def create_interface_records():
51     """
52     Create a record for each SFA interface
53     """
54     # just create certs for all sfa interfaces even if they
55     # arent enabled
56     interface_hrn = config.SFA_INTERFACE_HRN
57     interfaces = ['authority+sa', 'authority+am', 'authority+sm']
58     
59     auth_info = AuthHierarchy.get_auth_info(interface_hrn)
60     pkey = auth_info.get_pkey_object()
61     for interface in interfaces:
62         interface_record = table.find({'type': interface, 'hrn': interface_hrn})
63         if not interface_record:
64             urn = hrn_to_urn(interface_hrn, interface)
65             gid = AuthHierarchy.create_gid(urn, create_uuid(), pkey)
66             record = SfaRecord(hrn=interface_hrn, gid=gid, type=interface, pointer=-1)  
67             record['authority'] = get_authority(interface_hrn)
68             print>>sys.stderr,"\r\n ==========create_interface_records", record['authority']
69             table.insert(record)                
70                 
71 def create_top_level_auth_records(hrn):
72     """
73     Create top level records (includes root and sub authorities (local/remote)
74     """
75
76     urn = hrn_to_urn(hrn, 'authority')
77     # make sure parent exists
78     parent_hrn = get_authority(hrn)
79     print>>sys.stderr, "\r\n =========slab-import create_top_level_auth_records hrn %s  urn %s parent_hrn %s \r\n" %(hrn, urn, parent_hrn)
80     if not parent_hrn:
81         parent_hrn = hrn
82     if not parent_hrn == hrn:
83         create_top_level_auth_records(parent_hrn)
84
85     # create the authority if it doesnt already exist 
86     if not AuthHierarchy.auth_exists(urn):
87         AuthHierarchy.create_auth(urn)
88     
89     # create the db record if it doesnt already exist    
90     auth_info = AuthHierarchy.get_auth_info(hrn)
91    
92     auth_record = table.find({'type': 'authority', 'hrn': hrn})
93
94     if not auth_record:
95         auth_record = SfaRecord(hrn=hrn, gid=auth_info.get_gid_object(), type="authority", pointer=-1)
96         auth_record['authority'] = get_authority(auth_record['hrn'])
97         print sys.stderr, " \r\n \t slab-import : auth record %s inserted record %s " %(auth_record['hrn'], auth_record)
98         table.insert(auth_record)
99
100         
101     
102 def import_node(hrn, node):
103
104     # ASN.1 will have problems with hrn's longer than 64 characters
105     if len(hrn) > 64:
106         hrn = hrn[:64]
107
108     node_record = table.find({'type': 'node', 'hrn': hrn})
109     pkey = Keypair(create=True)
110     urn = hrn_to_urn(hrn, 'node')
111     node_gid = AuthHierarchy.create_gid(urn, create_uuid(), pkey)
112     node_record = SfaRecord(hrn=hrn, gid=node_gid, type="node", pointer=node['node_id'])
113     node_record['authority'] = get_authority(node_record['hrn'])
114     extime = datetime.datetime.utcnow()
115     node_record['date_created'] = int(time.mktime(extime.timetuple()))
116     existing_records = table.find({'hrn': hrn, 'type': 'node', 'pointer': node['node_id']})
117     if not existing_records:
118         print>>sys.stderr, " \r\n \t slab-import : node record %s inserted" %(node_record['hrn'])
119         table.insert(node_record)
120     else:
121         existing_record = existing_records[0]
122         node_record['record_id'] = existing_record['record_id']
123         table.update(node_record)
124
125 # person is already a sfa record 
126 def import_person(authname,person):       
127     existing_records = table.find({'hrn': person['hrn'], 'type': 'user'})
128     extime = datetime.datetime.utcnow()
129     person['date_created'] = int(time.mktime(extime.timetuple()))
130
131   
132     if not existing_records:
133         print>>sys.stderr, " \r\n \t slab-import : person record %s inserted" %(person['hrn'])
134         uuid=create_uuid() 
135         RSA_KEY_STRING=person['pkey']
136         pkey=convert_public_key(RSA_KEY_STRING)
137         person['gid']=AuthHierarchy.create_gid("urn:publicid:IDN+"+authname+"+user+"+person['uid'], uuid, pkey, CA=False).save_to_string()
138         table.insert(person)
139     else:
140         existing_record = existing_records[0]
141         person['record_id'] = existing_record['record_id']
142         # handle key change ??? 
143         table.update(person)
144         
145 def import_slice(person):
146
147     hrn = person['hrn']+'_slice'
148     pkey = Keypair(create=True)
149     urn = hrn_to_urn(hrn, 'slice')
150     gid = AuthHierarchy.create_gid(urn, create_uuid(), pkey)
151     slice_record= SfaRecord(hrn=hrn, gid=gid, type="slice", pointer=-1)
152     slice_record['authority'] = get_authority(slice_record['hrn'])
153    
154     extime = datetime.datetime.utcnow()
155     slice_record['date_created'] = int(time.mktime(extime.timetuple()))
156     #special slice table for Senslab, to store nodes info (OAR)                         
157
158     existing_records = table.find({'hrn': slice_record['hrn'], 'type': 'slice'})
159     if not existing_records:
160         print>>sys.stderr, " \r\n \t slab-import : slice record %s inserted" %(slice_record['hrn'])
161         table.insert(slice_record)
162         #table.insert_slice(person)
163         db.insert_slice(person)
164
165     else:
166         print>>sys.stderr, " \r\n \t slab-import : slice record %s updated" %(slice_record['hrn'])
167         existing_record = existing_records[0]
168         slice_record['record_id'] = existing_record['record_id']
169         table.update(slice_record)
170         db.update_slice(slice_record)   
171         
172 def delete_record( hrn, type):
173     # delete the record
174     record_list = table.find({'type': type, 'hrn': hrn})
175     for record in record_list:
176         print>>sys.stderr, " \r\n \t slab-import : record %s deleted" %(record['hrn'])
177         table.remove(record)
178                 
179 def hostname_to_hrn(root_auth,hostname):
180     # keep only the first part of the DNS name
181     #hrn='.'.join( [auth,hostname.split(".")[0] ] )
182     # escape the '.' in the hostname
183     hrn='.'.join( [root_auth,Xrn.escape(hostname)] )
184     return hrn_to_urn(hrn,'node')
185     
186 def main():
187
188     if not db.exists('slice'):
189         db.createtable('slice')
190         
191     if not config.SFA_REGISTRY_ENABLED:
192         sys.exit(0)
193     root_auth = config.SFA_REGISTRY_ROOT_AUTH
194     interface_hrn = config.SFA_INTERFACE_HRN
195     print interface_hrn, root_auth
196     
197     #Get all records in the sfa table   
198     # create dict of all existing sfa records
199     existing_records = {}
200     existing_hrns = []
201     key_ids = []
202     results = table.find()
203    
204     for result in results:
205         existing_records[(result['hrn'], result['type'])] = result
206         existing_hrns.append(result['hrn'])   
207         
208     # create root authority if it doesn't exist
209     if root_auth not in  existing_hrns or \
210     (root_auth, 'authority') not in existing_records:
211         create_top_level_auth_records(root_auth)
212         if not root_auth == interface_hrn:
213             create_top_level_auth_records(interface_hrn)
214     
215         # create s user record for the slice manager Do we need this?
216         create_sm_client_record()
217         
218         # create interface records ADDED 18 nov 11 Do we need this?
219     
220         create_interface_records()
221     
222         # add local root authority's cert  to trusted list ADDED 18 nov 11 Do we need this?
223         
224         authority = AuthHierarchy.get_auth_info(interface_hrn)
225         TrustedR.add_gid(authority.get_gid_object())
226
227
228     #Get Senslab nodes 
229    
230     Driver = SlabDriver(config)
231     nodes_dict  = Driver.GetNodes()
232     #print "\r\n NODES8DICT ",nodes_dict
233     
234     ldap_person_list = Driver.GetPersons()
235
236         # import node records
237     for node in nodes_dict:
238         hrn =  hostname_to_hrn( root_auth, node['hostname'])
239         if hrn not in existing_hrns or \
240         (hrn, 'node') not in existing_records:
241             import_node(hrn, node)
242
243    # import persons and slices
244     for person in ldap_person_list:
245         if person['hrn'] not in existing_hrns or \
246             (person['hrn'], 'user') not in existing_records :
247             import_person(root_auth,person)
248             import_slice(person)
249                                 
250                                 
251     # remove stale records    
252     system_records = [interface_hrn, root_auth, interface_hrn + '.slicemanager']
253
254     for (record_hrn, type) in existing_records.keys():
255         if record_hrn in system_records:
256             continue
257         
258         record = existing_records[(record_hrn, type)]
259         if record['peer_authority']:
260             continue                                    
261
262
263
264         found = False
265         
266         if type == 'authority':    
267             found = True
268             print "\t \t Found :", found
269             break
270                 
271         elif type == 'user':
272             for person in ldap_person_list:
273                 if person['hrn'] == record_hrn:
274                     found = True
275                     break
276             
277         elif type == 'node':
278             login_base = get_leaf(get_authority(record_hrn))
279             nodename = Xrn.unescape(get_leaf(record_hrn))
280             for node in nodes_dict:
281                 if node['hostname'] == nodename :
282                     found = True
283                     break 
284                 
285         elif type == 'slice':
286             for person in ldap_person_list:
287                 if person['hrn']+'_slice' == record_hrn:
288                     found = True
289                     break           
290         else:
291             continue 
292         
293         if not found:
294             record_object = existing_records[(record_hrn, type)]
295             print "\t\t  NOT FOUND ! ", record_hrn
296             delete_record(record_hrn, type) 
297     
298 if __name__ == "__main__":
299     main()