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