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