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