b57c9a37dc4eb8712c0221c60addfdb3e837e9bb
[sfa.git] / sfa / senslab / slabslices.py
1 from sfa.util.xrn import get_authority, urn_to_hrn
2 from sfa.util.sfalogging import logger
3
4
5 MAXINT =  2L**31-1
6
7 class SlabSlices:
8
9     rspec_to_slice_tag = {'max_rate':'net_max_rate'}
10     
11     
12     def __init__(self, driver):
13         self.driver = driver
14         
15     
16     def get_peer(self, xrn):
17         hrn, hrn_type = urn_to_hrn(xrn)
18         #Does this slice belong to a local site or a peer senslab site?
19         peer = None
20         
21         # get this slice's authority (site)
22         slice_authority = get_authority(hrn)
23         #Senslab stuff
24         #This slice belongs to the current site
25         if slice_authority ==  self.driver.slab_api.root_auth:
26             site_authority = slice_authority
27             return None
28        
29         site_authority = get_authority(slice_authority).lower()
30         # get this site's authority (sfa root authority or sub authority)
31
32         logger.debug("SLABSLICES \ get_peer slice_authority  %s \
33                     site_authority %s hrn %s" %(slice_authority, \
34                                         site_authority, hrn))
35         
36             
37         # check if we are already peered with this site_authority, if so
38         #peers = self.driver.slab_api.GetPeers({})  
39         peers = self.driver.slab_api.GetPeers(peer_filter = site_authority)
40         for peer_record in peers:
41           
42             if site_authority == peer_record.hrn:
43                 peer = peer_record
44         logger.debug(" SLABSLICES \tget_peer peer  %s " %(peer))
45         return peer
46
47     def get_sfa_peer(self, xrn):
48         hrn, hrn_type = urn_to_hrn(xrn)
49
50         # return the authority for this hrn or None if we are the authority
51         sfa_peer = None
52         slice_authority = get_authority(hrn)
53         site_authority = get_authority(slice_authority)
54
55         if site_authority != self.driver.hrn:
56             sfa_peer = site_authority
57
58         return sfa_peer
59
60         
61     def verify_slice_leases(self, sfa_slice, requested_jobs_dict, peer):
62
63         logger.debug("SLABSLICES verify_slice_leases sfa_slice %s \
64                         "%( sfa_slice))
65         #First get the list of current leases from OAR          
66         leases = self.driver.slab_api.GetLeases({'name':sfa_slice['hrn']})
67         logger.debug("SLABSLICES verify_slice_leases requested_jobs_dict %s \
68                         leases %s "%(requested_jobs_dict, leases ))
69         
70         current_nodes_reserved_by_start_time = {}
71         requested_nodes_by_start_time = {}
72         leases_by_start_time = {}
73         reschedule_jobs_dict = {}
74
75         
76         #Create reduced dictionary with key start_time and value 
77         # the list of nodes
78         #-for the leases already registered by OAR first
79         # then for the new leases requested by the user
80         
81         #Leases already scheduled/running in OAR
82         for lease in leases :
83             current_nodes_reserved_by_start_time[lease['t_from']] = \
84                     lease['reserved_nodes']
85             leases_by_start_time[lease['t_from']] = lease
86             
87         
88         #Requested jobs     
89         for start_time in requested_jobs_dict:
90             requested_nodes_by_start_time[int(start_time)]  = \
91                     requested_jobs_dict[start_time]['hostname']            
92         #Check if there is any difference between the leases already
93         #registered in OAR and the requested jobs.   
94         #Difference could be:
95         #-Lease deleted in the requested jobs
96         #-Added/removed nodes
97         #-Newly added lease 
98
99         logger.debug("SLABSLICES verify_slice_leases \
100                         requested_nodes_by_start_time %s \
101                         "%(requested_nodes_by_start_time ))
102         #Find all deleted leases
103         start_time_list = \
104             list(set(leases_by_start_time.keys()).\
105             difference(requested_nodes_by_start_time.keys()))
106         deleted_leases = [leases_by_start_time[start_time]['lease_id'] \
107                             for start_time in start_time_list]
108
109
110             
111         #Find added or removed nodes in exisiting leases
112         for start_time in requested_nodes_by_start_time: 
113             logger.debug("SLABSLICES verify_slice_leases  start_time %s \
114                          "%( start_time))
115             if start_time in current_nodes_reserved_by_start_time:
116                 
117                 if requested_nodes_by_start_time[start_time] == \
118                     current_nodes_reserved_by_start_time[start_time]:
119                     continue
120                 
121                 else:
122                     update_node_set = \
123                             set(requested_nodes_by_start_time[start_time])
124                     added_nodes = \
125                         update_node_set.difference(\
126                         current_nodes_reserved_by_start_time[start_time])
127                     shared_nodes = \
128                         update_node_set.intersection(\
129                         current_nodes_reserved_by_start_time[start_time])
130                     old_nodes_set = \
131                         set(\
132                         current_nodes_reserved_by_start_time[start_time])
133                     removed_nodes = \
134                         old_nodes_set.difference(\
135                         requested_nodes_by_start_time[start_time])
136                     logger.debug("SLABSLICES verify_slice_leases \
137                         shared_nodes %s  added_nodes %s removed_nodes %s"\
138                         %(shared_nodes, added_nodes,removed_nodes ))
139                     #If the lease is modified, delete it before 
140                     #creating it again.
141                     #Add the deleted lease job id in the list
142                     #WARNING :rescheduling does not work if there is already  
143                     # 2 running/scheduled jobs because deleting a job 
144                     #takes time SA 18/10/2012
145                     if added_nodes or removed_nodes:
146                         deleted_leases.append(\
147                             leases_by_start_time[start_time]['lease_id'])
148                         #Reschedule the job 
149                         if added_nodes or shared_nodes:
150                             reschedule_jobs_dict[str(start_time)] = \
151                                         requested_jobs_dict[str(start_time)]
152
153             else: 
154                     #New lease
155                     
156                 job = requested_jobs_dict[str(start_time)]
157                 logger.debug("SLABSLICES \
158                 NEWLEASE slice %s  job %s"\
159                 %(sfa_slice, job)) 
160                 self.driver.slab_api.AddLeases(job['hostname'], \
161                         sfa_slice, int(job['start_time']), \
162                         int(job['duration']))
163
164         #Deleted leases are the ones with lease id not declared in the Rspec
165         if deleted_leases:
166             self.driver.slab_api.DeleteLeases(deleted_leases, sfa_slice['hrn'])
167             logger.debug("SLABSLICES \
168                     verify_slice_leases slice %s deleted_leases %s"\
169                     %(sfa_slice, deleted_leases))
170                     
171                     
172         if reschedule_jobs_dict : 
173             for start_time in  reschedule_jobs_dict:
174                 job = reschedule_jobs_dict[start_time]
175                 self.driver.slab_api.AddLeases(job['hostname'], \
176                     sfa_slice, int(job['start_time']), \
177                     int(job['duration']))
178         return leases
179
180     def verify_slice_nodes(self, sfa_slice, requested_slivers, peer):
181         current_slivers = []
182         deleted_nodes = []
183
184         if 'node_ids' in sfa_slice:
185             nodes = self.driver.slab_api.GetNodes(sfa_slice['list_node_ids'], \
186                 ['hostname'])
187             current_slivers = [node['hostname'] for node in nodes]
188     
189             # remove nodes not in rspec
190             deleted_nodes = list(set(current_slivers).\
191                                                 difference(requested_slivers))
192             # add nodes from rspec
193             #added_nodes = list(set(requested_slivers).\
194                                         #difference(current_slivers))
195
196
197             logger.debug("SLABSLICES \tverify_slice_nodes slice %s\
198                                          \r\n \r\n deleted_nodes %s"\
199                                         %(sfa_slice, deleted_nodes))
200
201             if deleted_nodes:
202                 #Delete the entire experience
203                 self.driver.slab_api.DeleteSliceFromNodes(sfa_slice)
204                 #self.driver.DeleteSliceFromNodes(sfa_slice['slice_hrn'], \
205                                                                 #deleted_nodes)
206             return nodes
207
208             
209
210     def free_egre_key(self):
211         used = set()
212         for tag in self.driver.slab_api.GetSliceTags({'tagname': 'egre_key'}):
213             used.add(int(tag['value']))
214
215         for i in range(1, 256):
216             if i not in used:
217                 key = i
218                 break
219         else:
220             raise KeyError("No more EGRE keys available")
221
222         return str(key)
223
224   
225        
226                         
227         
228
229     def handle_peer(self, site, sfa_slice, persons, peer):
230         if peer:
231             # bind site
232             try:
233                 if site:
234                     self.driver.slab_api.BindObjectToPeer('site', site['site_id'], \
235                                         peer['shortname'], sfa_slice['site_id'])
236             except Exception, error:
237                 self.driver.slab_api.DeleteSite(site['site_id'])
238                 raise error
239             
240             # bind slice
241             try:
242                 if sfa_slice:
243                     self.driver.slab_api.BindObjectToPeer('slice', slice['slice_id'], \
244                                     peer['shortname'], sfa_slice['slice_id'])
245             except Exception, error:
246                 self.driver.slab_api.DeleteSlice(sfa_slice['slice_id'])
247                 raise error 
248
249             # bind persons
250             for person in persons:
251                 try:
252                     self.driver.slab_api.BindObjectToPeer('person', \
253                                     person['person_id'], peer['shortname'], \
254                                     person['peer_person_id'])
255
256                     for (key, remote_key_id) in zip(person['keys'], \
257                                                         person['key_ids']):
258                         try:
259                             self.driver.slab_api.BindObjectToPeer( 'key', \
260                                             key['key_id'], peer['shortname'], \
261                                             remote_key_id)
262                         except:
263                             self.driver.slab_api.DeleteKey(key['key_id'])
264                             logger.log_exc("failed to bind key: %s \
265                                             to peer: %s " % (key['key_id'], \
266                                             peer['shortname']))
267                 except Exception, error:
268                     self.driver.slab_api.DeletePerson(person['person_id'])
269                     raise error       
270
271         return sfa_slice
272
273     #def verify_site(self, slice_xrn, slice_record={}, peer=None, \
274                                         #sfa_peer=None, options={}):
275         #(slice_hrn, type) = urn_to_hrn(slice_xrn)
276         #site_hrn = get_authority(slice_hrn)
277         ## login base can't be longer than 20 characters
278         ##slicename = hrn_to_pl_slicename(slice_hrn)
279         #authority_name = slice_hrn.split('.')[0]
280         #login_base = authority_name[:20]
281         #logger.debug(" SLABSLICES.PY \tverify_site authority_name %s  \
282                                         #login_base %s slice_hrn %s" \
283                                         #%(authority_name,login_base,slice_hrn)
284         
285         #sites = self.driver.slab_api.GetSites(login_base)
286         #if not sites:
287             ## create new site record
288             #site = {'name': 'geni.%s' % authority_name,
289                     #'abbreviated_name': authority_name,
290                     #'login_base': login_base,
291                     #'max_slices': 100,
292                     #'max_slivers': 1000,
293                     #'enabled': True,
294                     #'peer_site_id': None}
295             #if peer:
296                 #site['peer_site_id'] = slice_record.get('site_id', None)
297             #site['site_id'] = self.driver.slab_api.AddSite(site)
298             ## exempt federated sites from monitor policies
299             #self.driver.slab_api.AddSiteTag(site['site_id'], 'exempt_site_until', \
300                                                                 #"20200101")
301             
302             ### is this still necessary?
303             ### add record to the local registry 
304             ##if sfa_peer and slice_record:
305                 ##peer_dict = {'type': 'authority', 'hrn': site_hrn, \
306                              ##'peer_authority': sfa_peer, 'pointer': \
307                                                         #site['site_id']}
308                 ##self.registry.register_peer_object(self.credential, peer_dict)
309         #else:
310             #site =  sites[0]
311             #if peer:
312                 ## unbind from peer so we can modify if necessary.
313                 ## Will bind back later
314                 #self.driver.slab_api.UnBindObjectFromPeer('site', site['site_id'], \
315                                                             #peer['shortname']) 
316         
317         #return site        
318
319     def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer):
320
321         #login_base = slice_hrn.split(".")[0]
322         slicename = slice_hrn
323         slices_list = self.driver.slab_api.GetSlices(slice_filter = slicename, \
324                                             slice_filter_type = 'slice_hrn') 
325         sfa_slice = None                                 
326         if slices_list:
327             for sl in slices_list:
328             
329                 logger.debug("SLABSLICE \tverify_slice slicename %s slices_list %s sl %s \
330                                     slice_record %s"%(slicename, slices_list,sl, \
331                                                             slice_record))
332                 sfa_slice = sl
333                 sfa_slice.update(slice_record)
334                 #del slice['last_updated']
335                 #del slice['date_created']
336                 #if peer:
337                     #slice['peer_slice_id'] = slice_record.get('slice_id', None)
338                     ## unbind from peer so we can modify if necessary. 
339                     ## Will bind back later
340                     #self.driver.slab_api.UnBindObjectFromPeer('slice', \
341                                                         #slice['slice_id'], \
342                                                             #peer['shortname'])
343                 #Update existing record (e.g. expires field) 
344                     #it with the latest info.
345                 ##if slice_record and slice['expires'] != slice_record['expires']:
346                     ##self.driver.slab_api.UpdateSlice( slice['slice_id'], {'expires' : \
347                                                         #slice_record['expires']})
348         else:
349             #Search for user in ldap based on email SA 14/11/12
350             ldap_user = self.driver.slab_api.ldap.LdapFindUser(slice_record['user'])
351             logger.debug(" SLABSLICES \tverify_slice Oups \
352                         slice_record %s peer %s sfa_peer %s ldap_user %s"\
353                         %(slice_record, peer,sfa_peer ,ldap_user ))
354             #User already registered in ldap, meaning user should be in SFA db
355             #and hrn = sfa_auth+ uid   
356             sfa_slice = {'hrn': slicename,
357                      #'url': slice_record.get('url', slice_hrn), 
358                      #'description': slice_record.get('description', slice_hrn)
359                      'node_list' : [],
360                      'authority' : slice_record['authority'],
361                      'gid':slice_record['gid'],
362                      #'record_id_user' : user.record_id,
363                      'slice_id' : slice_record['record_id'],
364                      'reg-researchers':slice_record['reg-researchers'],
365                      #'record_id_slice': slice_record['record_id'],
366                      'peer_authority':str(sfa_peer)
367                     
368                      }        
369             if ldap_user : 
370                 hrn = self.driver.slab_api.root_auth +'.'+ ldap_user['uid']
371                 
372                 user = self.driver.get_user_record(hrn)
373                 
374                 logger.debug(" SLABSLICES \tverify_slice hrn %s USER %s" %(hrn, user))
375                 #sfa_slice = {'slice_hrn': slicename,
376                      ##'url': slice_record.get('url', slice_hrn), 
377                      ##'description': slice_record.get('description', slice_hrn)
378                      #'node_list' : [],
379                      #'authority' : slice_record['authority'],
380                      #'gid':slice_record['gid'],
381                      ##'record_id_user' : user.record_id,
382                      #'slice_id' : slice_record['record_id'],
383                      #'reg-researchers':slice_record['reg-researchers'],
384                      ##'record_id_slice': slice_record['record_id'],
385                      #'peer_authority':str(peer.hrn)
386                     
387                      #}
388                      # add the slice  
389                 if sfa_slice :
390                     self.driver.slab_api.AddSlice(sfa_slice, user)  
391                      
392                 if peer:
393                     sfa_slice['slice_id'] = slice_record['record_id']
394                                    
395             #slice['slice_id'] = self.driver.slab_api.AddSlice(slice)
396             logger.debug("SLABSLICES \tverify_slice ADDSLICE OK") 
397             #slice['node_ids']=[]
398             #slice['person_ids'] = []
399             #if peer:
400                 #sfa_slice['peer_slice_id'] = slice_record.get('slice_id', None) 
401             # mark this slice as an sfa peer record
402             #if sfa_peer:
403                 #peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
404                              #'peer_authority': sfa_peer, 'pointer': \
405                                                     #slice['slice_id']}
406                 #self.registry.register_peer_object(self.credential, peer_dict)
407             
408
409        
410         return sfa_slice
411
412
413     def verify_persons(self, slice_hrn, slice_record, users,  peer, sfa_peer, \
414                                                                 options={}):
415         """ 
416         users is a record list. Records can either be local records 
417         or users records from known and trusted federated sites. 
418         If the user is from another site that senslab doesn't trust yet,
419         then Resolve will raise an error before getting to create_sliver. 
420         """
421         #TODO SA 21/08/12 verify_persons Needs review 
422         
423         logger.debug("SLABSLICES \tverify_persons \tslice_hrn  %s  \t slice_record %s\r\n users %s \t peer %s "%( slice_hrn, slice_record, users,  peer)) 
424         users_by_id = {}  
425         #users_by_hrn = {} 
426         users_by_email = {}
427         #users_dict : dict whose keys can either be the user's hrn or its id.
428         #Values contains only id and hrn 
429         users_dict = {}
430         
431         #First create dicts by hrn and id for each user in the user record list:      
432         for info in users:
433             
434             if 'slice_record' in info :
435                 slice_rec = info['slice_record'] 
436                 user = slice_rec['user']
437
438             if 'email' in user:  
439                 users_by_email[user['email']] = user
440                 users_dict[user['email']] = user
441                 
442             #if 'hrn' in user:
443                 #users_by_hrn[user['hrn']] = user
444                 #users_dict[user['hrn']] = user
445         
446         logger.debug( "SLABSLICE.PY \t verify_person  \
447                         users_dict %s \r\n user_by_email %s \r\n \
448                         \tusers_by_id %s " \
449                         %(users_dict,users_by_email, users_by_id))
450         
451         existing_user_ids = []
452         #existing_user_hrns = []
453         existing_user_emails = []
454         existing_users = []
455         # Check if user is in Senslab LDAP using its hrn.
456         # Assuming Senslab is centralised :  one LDAP for all sites, 
457         # user_id unknown from LDAP
458         # LDAP does not provide users id, therefore we rely on hrns containing
459         # the login of the user.
460         # If the hrn is not a senslab hrn, the user may not be in LDAP.
461         #if users_by_hrn:
462         if users_by_email :
463             #Construct the list of filters (list of dicts) for GetPersons
464             filter_user = []
465             #for hrn in users_by_hrn:
466             for email in users_by_email :
467                 #filter_user.append (users_by_hrn[hrn])
468                 filter_user.append (users_by_email[email])
469             #Check user's in LDAP with GetPersons
470             #Needed because what if the user has been deleted in LDAP but 
471             #is still in SFA?
472             existing_users = self.driver.slab_api.GetPersons(filter_user) 
473             logger.debug(" \r\n SLABSLICE.PY \tverify_person  filter_user %s existing_users %s " \
474                                                     %(filter_user, existing_users))               
475             #User's in senslab LDAP               
476             if existing_users:
477                 for user in existing_users :
478                     users_dict[user['email']].update(user)
479                     existing_user_emails.append(users_dict[user['email']]['email'])
480                     
481                     #existing_user_hrns.append(users_dict[user['hrn']]['hrn'])
482                     #existing_user_ids.\
483                                     #append(users_dict[user['hrn']]['person_id'])
484          
485             # User from another known trusted federated site. Check 
486             # if a senslab account matching the email has already been created.
487             else: 
488                 req = 'mail='
489                 if isinstance(users, list):
490                     
491                     req += users[0]['email']  
492                 else:
493                     req += users['email']
494                     
495                 ldap_reslt = self.driver.slab_api.ldap.LdapSearch(req)
496                 if ldap_reslt:
497                     logger.debug(" SLABSLICE.PY \tverify_person users \
498                                 USER already in Senslab \t ldap_reslt %s \
499                                 "%( ldap_reslt)) 
500                     existing_users.append(ldap_reslt[1])
501                  
502                 else:
503                     #User not existing in LDAP
504                     #TODO SA 21/08/12 raise smthg to add user or add it auto ?
505                     #new_record = {}
506                     #new_record['pkey'] = users[0]['keys'][0]
507                     #new_record['mail'] = users[0]['email']
508                   
509                     logger.debug(" SLABSLICE.PY \tverify_person users \
510                                 not in ldap ...NEW ACCOUNT NEEDED %s \r\n \t \
511                                 ldap_reslt %s "  %(users, ldap_reslt))
512    
513         #requested_user_ids = users_by_id.keys() 
514         #requested_user_hrns = users_by_hrn.keys()
515         requested_user_emails = users_by_email.keys()
516         requested_user_hrns = [users_by_email[user]['hrn'] for user in users_by_email]
517         logger.debug("SLABSLICE.PY \tverify_person  \
518                        users_by_email  %s " %( users_by_email)) 
519         #logger.debug("SLABSLICE.PY \tverify_person  \
520                         #user_by_hrn %s " %( users_by_hrn)) 
521       
522    
523         #Check that the user of the slice in the slice record
524         #matches the existing users 
525         try:
526             if slice_record['PI'][0] in requested_user_hrns:
527             #if slice_record['record_id_user'] in requested_user_ids and \
528                                 #slice_record['PI'][0] in requested_user_hrns:
529                 logger.debug(" SLABSLICE  \tverify_person ['PI'] slice_record %s" \
530                         %(slice_record))
531            
532         except KeyError:
533             pass
534             
535       
536         # users to be added, removed or updated
537         #One user in one senslab slice : there should be no need
538         #to remove/ add any user from/to a slice.
539         #However a user from SFA which is not registered in Senslab yet
540         #should be added to the LDAP.
541         added_user_emails = set(requested_user_emails).\
542                                             difference(set(existing_user_emails))
543         #added_user_hrns = set(requested_user_hrns).\
544                                             #difference(set(existing_user_hrns))
545
546         #self.verify_keys(existing_slice_users, updated_users_list, \
547                                                             #peer, append)
548
549         added_persons = []
550         # add new users
551         
552         #requested_user_email is in existing_user_emails
553         if len(added_user_emails) == 0:
554            
555             slice_record['login'] = users_dict[requested_user_emails[0]]['uid']
556             logger.debug(" SLABSLICE  \tverify_person QUICK DIRTY %s" \
557                         %(slice_record))
558             
559         #for added_user_hrn in added_user_hrns:
560             #added_user = users_dict[added_user_hrn]
561             
562             
563         for added_user_email in added_user_emails:
564             #hrn, type = urn_to_hrn(added_user['urn'])  
565             added_user = users_dict[added_user_email]
566             logger.debug(" SLABSLICE \r\n \r\n  \t THE SECOND verify_person  added_user %s" %(added_user))
567             person = {}
568             person['peer_person_id'] =  None
569             k_list  = ['first_name','last_name','person_id']
570             for k in k_list:
571                 if k in added_user:
572                     person[k] = added_user[k]
573
574             person['pkey'] = added_user['keys'][0]
575             person['mail'] = added_user['email']
576             person['email'] = added_user['email']
577             person['key_ids'] =  added_user.get('key_ids', [])
578             #person['urn'] =   added_user['urn']
579               
580             #person['person_id'] = self.driver.slab_api.AddPerson(person)
581             person['uid'] = self.driver.slab_api.AddPerson(person)
582             
583             logger.debug(" SLABSLICE \r\n \r\n  \t THE SECOND verify_person ppeersonne  %s" %(person))
584             #Update slice_Record with the id now known to LDAP
585             slice_record['login'] = person['uid']
586             #slice_record['reg_researchers'] = [self.driver.slab_api.root_auth + '.' + person['uid']]
587             #slice_record['reg-researchers'] =  slice_record['reg_researchers']
588             
589             #if peer:
590                 #person['peer_person_id'] = added_user['person_id']
591             added_persons.append(person)
592            
593             # enable the account 
594             #self.driver.slab_api.UpdatePerson(slice_record['reg_researchers'][0], added_user_email)
595             
596             # add person to site
597             #self.driver.slab_api.AddPersonToSite(added_user_id, login_base)
598
599             #for key_string in added_user.get('keys', []):
600                 #key = {'key':key_string, 'key_type':'ssh'}
601                 #key['key_id'] = self.driver.slab_api.AddPersonKey(person['person_id'], \
602                                                 #                       key)
603                 #person['keys'].append(key)
604
605             # add the registry record
606             #if sfa_peer:
607                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': \
608                                                 #sfa_peer, \
609                                                 #'pointer': person['person_id']}
610                 #self.registry.register_peer_object(self.credential, peer_dict)
611         #for added_slice_user_hrn in \
612                                 #added_slice_user_hrns.union(added_user_hrns):
613             #self.driver.slab_api.AddPersonToSlice(added_slice_user_hrn, \
614                                                     #slice_record['name'])
615         #for added_slice_user_id in \
616                                     #added_slice_user_ids.union(added_user_ids):
617             # add person to the slice 
618             #self.driver.slab_api.AddPersonToSlice(added_slice_user_id, \
619                                                 #slice_record['name'])
620             # if this is a peer record then it 
621             # should already be bound to a peer.
622             # no need to return worry about it getting bound later 
623
624         return added_persons
625             
626     #Unused
627     def verify_keys(self, persons, users, peer, options={}):
628         # existing keys 
629         key_ids = []
630         for person in persons:
631             key_ids.extend(person['key_ids'])
632         keylist = self.driver.slab_api.GetKeys(key_ids, ['key_id', 'key'])
633         keydict = {}
634         for key in keylist:
635             keydict[key['key']] = key['key_id']     
636         existing_keys = keydict.keys()
637         persondict = {}
638         for person in persons:
639             persondict[person['email']] = person    
640     
641         # add new keys
642         requested_keys = []
643         updated_persons = []
644         for user in users:
645             user_keys = user.get('keys', [])
646             updated_persons.append(user)
647             for key_string in user_keys:
648                 requested_keys.append(key_string)
649                 if key_string not in existing_keys:
650                     key = {'key': key_string, 'key_type': 'ssh'}
651                     try:
652                         if peer:
653                             person = persondict[user['email']]
654                             self.driver.slab_api.UnBindObjectFromPeer('person', \
655                                         person['person_id'], peer['shortname'])
656                         key['key_id'] = \
657                                 self.driver.slab_api.AddPersonKey(user['email'], key)
658                         if peer:
659                             key_index = user_keys.index(key['key'])
660                             remote_key_id = user['key_ids'][key_index]
661                             self.driver.slab_api.BindObjectToPeer('key', \
662                                             key['key_id'], peer['shortname'], \
663                                             remote_key_id)
664                             
665                     finally:
666                         if peer:
667                             self.driver.slab_api.BindObjectToPeer('person', \
668                                     person['person_id'], peer['shortname'], \
669                                     user['person_id'])
670         
671         # remove old keys (only if we are not appending)
672         append = options.get('append', True)
673         if append == False: 
674             removed_keys = set(existing_keys).difference(requested_keys)
675             for existing_key_id in keydict:
676                 if keydict[existing_key_id] in removed_keys:
677
678                     if peer:
679                         self.driver.slab_api.UnBindObjectFromPeer('key', \
680                                         existing_key_id, peer['shortname'])
681                     self.driver.slab_api.DeleteKey(existing_key_id)
682  
683
684     #def verify_slice_attributes(self, slice, requested_slice_attributes, \
685                                             #append=False, admin=False):
686         ## get list of attributes users ar able to manage
687         #filter = {'category': '*slice*'}
688         #if not admin:
689             #filter['|roles'] = ['user']
690         #slice_attributes = self.driver.slab_api.GetTagTypes(filter)
691         #valid_slice_attribute_names = [attribute['tagname'] \
692                                             #for attribute in slice_attributes]
693
694         ## get sliver attributes
695         #added_slice_attributes = []
696         #removed_slice_attributes = []
697         #ignored_slice_attribute_names = []
698         #existing_slice_attributes = self.driver.slab_api.GetSliceTags({'slice_id': \
699                                                             #slice['slice_id']})
700
701         ## get attributes that should be removed
702         #for slice_tag in existing_slice_attributes:
703             #if slice_tag['tagname'] in ignored_slice_attribute_names:
704                 ## If a slice already has a admin only role 
705                 ## it was probably given to them by an
706                 ## admin, so we should ignore it.
707                 #ignored_slice_attribute_names.append(slice_tag['tagname'])
708             #else:
709                 ## If an existing slice attribute was not 
710                 ## found in the request it should
711                 ## be removed
712                 #attribute_found=False
713                 #for requested_attribute in requested_slice_attributes:
714                     #if requested_attribute['name'] == slice_tag['tagname'] \
715                         #and requested_attribute['value'] == slice_tag['value']:
716                         #attribute_found=True
717                         #break
718
719             #if not attribute_found and not append:
720                 #removed_slice_attributes.append(slice_tag)
721         
722         ## get attributes that should be added:
723         #for requested_attribute in requested_slice_attributes:
724             ## if the requested attribute wasn't found  we should add it
725             #if requested_attribute['name'] in valid_slice_attribute_names:
726                 #attribute_found = False
727                 #for existing_attribute in existing_slice_attributes:
728                     #if requested_attribute['name'] == \
729                         #existing_attribute['tagname'] and \
730                        #requested_attribute['value'] == \
731                        #existing_attribute['value']:
732                         #attribute_found=True
733                         #break
734                 #if not attribute_found:
735                     #added_slice_attributes.append(requested_attribute)
736
737
738         ## remove stale attributes
739         #for attribute in removed_slice_attributes:
740             #try:
741                 #self.driver.slab_api.DeleteSliceTag(attribute['slice_tag_id'])
742             #except Exception, error:
743                 #self.logger.warn('Failed to remove sliver attribute. name: \
744                                 #%s, value: %s, node_id: %s\nCause:%s'\
745                                 #% (name, value,  node_id, str(error)))
746
747         ## add requested_attributes
748         #for attribute in added_slice_attributes:
749             #try:
750                 #self.driver.slab_api.AddSliceTag(slice['name'], attribute['name'], \
751                             #attribute['value'], attribute.get('node_id', None))
752             #except Exception, error:
753                 #self.logger.warn('Failed to add sliver attribute. name: %s, \
754                                 #value: %s, node_id: %s\nCause:%s'\
755                                 #% (name, value,  node_id, str(error)))
756
757