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