Adding federated user in LDAP.sed on email
[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                     logger.debug(" SLABSLICE.PY \tverify_person users \
481                                 not in ldap ...NEW ACCOUNT NEEDED %s \r\n \t \
482                                 ldap_reslt %s "  %(users, ldap_reslt))
483    
484         #requested_user_ids = users_by_id.keys() 
485         requested_user_hrns = users_by_hrn.keys()
486         logger.debug("SLABSLICE.PY \tverify_person  \
487                         user_by_hrn %s " %( users_by_hrn)) 
488       
489    
490         #Check that the user of the slice in the slice record
491         #matches the existing users 
492         try:
493             if slice_record['PI'][0] in requested_user_hrns:
494             #if slice_record['record_id_user'] in requested_user_ids and \
495                                 #slice_record['PI'][0] in requested_user_hrns:
496                 logger.debug(" SLABSLICE  \tverify_person  \slice_record['record_id_user'] %s" \
497                         %(slice_record['record_id_user']))
498            
499         except KeyError:
500             pass
501             
502       
503         # users to be added, removed or updated
504         #One user in one senslab slice : there should be no need
505         #to remove/ add any user from/to a slice.
506         #However a user from SFA which is not registered in Senslab yet
507         #should be added to the LDAP.
508
509         added_user_hrns = set(requested_user_hrns).\
510                                             difference(set(existing_user_hrns))
511
512         #self.verify_keys(existing_slice_users, updated_users_list, \
513                                                             #peer, append)
514
515         added_persons = []
516         # add new users
517         for added_user_hrn in added_user_hrns:
518             added_user = users_dict[added_user_hrn]
519             #hrn, type = urn_to_hrn(added_user['urn'])  
520             person = {
521                 #'first_name': added_user.get('first_name', hrn),
522                 #'last_name': added_user.get('last_name', hrn),
523                 'first_name': added_user['first_name'],
524                 'last_name': added_user['last_name'],
525                 'person_id': added_user['person_id'],
526                 'peer_person_id': None,
527                 'keys': [],
528                 'key_ids': added_user.get('key_ids', []),
529                 
530             } 
531             person['person_id'] = self.driver.AddPerson(person)
532             if peer:
533                 person['peer_person_id'] = added_user['person_id']
534             added_persons.append(person)
535            
536             # enable the account 
537             self.driver.UpdatePerson(person['person_id'], {'enabled': True})
538             
539             # add person to site
540             #self.driver.AddPersonToSite(added_user_id, login_base)
541
542             #for key_string in added_user.get('keys', []):
543                 #key = {'key':key_string, 'key_type':'ssh'}
544                 #key['key_id'] = self.driver.AddPersonKey(person['person_id'], \
545                                                 #                       key)
546                 #person['keys'].append(key)
547
548             # add the registry record
549             #if sfa_peer:
550                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': \
551                                                 #sfa_peer, \
552                                                 #'pointer': person['person_id']}
553                 #self.registry.register_peer_object(self.credential, peer_dict)
554         #for added_slice_user_hrn in \
555                                 #added_slice_user_hrns.union(added_user_hrns):
556             #self.driver.AddPersonToSlice(added_slice_user_hrn, \
557                                                     #slice_record['name'])
558         #for added_slice_user_id in \
559                                     #added_slice_user_ids.union(added_user_ids):
560             # add person to the slice 
561             #self.driver.AddPersonToSlice(added_slice_user_id, \
562                                                 #slice_record['name'])
563             # if this is a peer record then it 
564             # should already be bound to a peer.
565             # no need to return worry about it getting bound later 
566
567         return added_persons
568             
569     #Unused
570     def verify_keys(self, persons, users, peer, options={}):
571         # existing keys 
572         key_ids = []
573         for person in persons:
574             key_ids.extend(person['key_ids'])
575         keylist = self.driver.GetKeys(key_ids, ['key_id', 'key'])
576         keydict = {}
577         for key in keylist:
578             keydict[key['key']] = key['key_id']     
579         existing_keys = keydict.keys()
580         persondict = {}
581         for person in persons:
582             persondict[person['email']] = person    
583     
584         # add new keys
585         requested_keys = []
586         updated_persons = []
587         for user in users:
588             user_keys = user.get('keys', [])
589             updated_persons.append(user)
590             for key_string in user_keys:
591                 requested_keys.append(key_string)
592                 if key_string not in existing_keys:
593                     key = {'key': key_string, 'key_type': 'ssh'}
594                     try:
595                         if peer:
596                             person = persondict[user['email']]
597                             self.driver.UnBindObjectFromPeer('person', \
598                                         person['person_id'], peer['shortname'])
599                         key['key_id'] = \
600                                 self.driver.AddPersonKey(user['email'], key)
601                         if peer:
602                             key_index = user_keys.index(key['key'])
603                             remote_key_id = user['key_ids'][key_index]
604                             self.driver.BindObjectToPeer('key', \
605                                             key['key_id'], peer['shortname'], \
606                                             remote_key_id)
607                             
608                     finally:
609                         if peer:
610                             self.driver.BindObjectToPeer('person', \
611                                     person['person_id'], peer['shortname'], \
612                                     user['person_id'])
613         
614         # remove old keys (only if we are not appending)
615         append = options.get('append', True)
616         if append == False: 
617             removed_keys = set(existing_keys).difference(requested_keys)
618             for existing_key_id in keydict:
619                 if keydict[existing_key_id] in removed_keys:
620
621                     if peer:
622                         self.driver.UnBindObjectFromPeer('key', \
623                                         existing_key_id, peer['shortname'])
624                     self.driver.DeleteKey(existing_key_id)
625  
626
627     #def verify_slice_attributes(self, slice, requested_slice_attributes, \
628                                             #append=False, admin=False):
629         ## get list of attributes users ar able to manage
630         #filter = {'category': '*slice*'}
631         #if not admin:
632             #filter['|roles'] = ['user']
633         #slice_attributes = self.driver.GetTagTypes(filter)
634         #valid_slice_attribute_names = [attribute['tagname'] \
635                                             #for attribute in slice_attributes]
636
637         ## get sliver attributes
638         #added_slice_attributes = []
639         #removed_slice_attributes = []
640         #ignored_slice_attribute_names = []
641         #existing_slice_attributes = self.driver.GetSliceTags({'slice_id': \
642                                                             #slice['slice_id']})
643
644         ## get attributes that should be removed
645         #for slice_tag in existing_slice_attributes:
646             #if slice_tag['tagname'] in ignored_slice_attribute_names:
647                 ## If a slice already has a admin only role 
648                 ## it was probably given to them by an
649                 ## admin, so we should ignore it.
650                 #ignored_slice_attribute_names.append(slice_tag['tagname'])
651             #else:
652                 ## If an existing slice attribute was not 
653                 ## found in the request it should
654                 ## be removed
655                 #attribute_found=False
656                 #for requested_attribute in requested_slice_attributes:
657                     #if requested_attribute['name'] == slice_tag['tagname'] \
658                         #and requested_attribute['value'] == slice_tag['value']:
659                         #attribute_found=True
660                         #break
661
662             #if not attribute_found and not append:
663                 #removed_slice_attributes.append(slice_tag)
664         
665         ## get attributes that should be added:
666         #for requested_attribute in requested_slice_attributes:
667             ## if the requested attribute wasn't found  we should add it
668             #if requested_attribute['name'] in valid_slice_attribute_names:
669                 #attribute_found = False
670                 #for existing_attribute in existing_slice_attributes:
671                     #if requested_attribute['name'] == \
672                         #existing_attribute['tagname'] and \
673                        #requested_attribute['value'] == \
674                        #existing_attribute['value']:
675                         #attribute_found=True
676                         #break
677                 #if not attribute_found:
678                     #added_slice_attributes.append(requested_attribute)
679
680
681         ## remove stale attributes
682         #for attribute in removed_slice_attributes:
683             #try:
684                 #self.driver.DeleteSliceTag(attribute['slice_tag_id'])
685             #except Exception, error:
686                 #self.logger.warn('Failed to remove sliver attribute. name: \
687                                 #%s, value: %s, node_id: %s\nCause:%s'\
688                                 #% (name, value,  node_id, str(error)))
689
690         ## add requested_attributes
691         #for attribute in added_slice_attributes:
692             #try:
693                 #self.driver.AddSliceTag(slice['name'], attribute['name'], \
694                             #attribute['value'], attribute.get('node_id', None))
695             #except Exception, error:
696                 #self.logger.warn('Failed to add sliver attribute. name: %s, \
697                                 #value: %s, node_id: %s\nCause:%s'\
698                                 #% (name, value,  node_id, str(error)))
699
700