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