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