b6a0bcb98c65508a904af963e24cb27e5648045b
[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         # check if we are already peered with this site_authority, if so
119         #peers = self.driver.GetPeers({})  
120         peers = self.driver.GetPeers(peer_filter = slice_authority)
121         for peer_record in peers:
122           
123             if site_authority == peer_record.hrn:
124                 peer = peer_record
125         logger.debug(" SLABSLICES \tget_peer peer  %s " %(peer))
126         return peer
127
128     def get_sfa_peer(self, xrn):
129         hrn, hrn_type = urn_to_hrn(xrn)
130
131         # return the authority for this hrn or None if we are the authority
132         sfa_peer = None
133         slice_authority = get_authority(hrn)
134         site_authority = get_authority(slice_authority)
135
136         if site_authority != self.driver.hrn:
137             sfa_peer = site_authority
138
139         return sfa_peer
140         
141         
142     def verify_slice_leases(self, sfa_slice, requested_leases, kept_leases, \
143         peer):
144         
145         leases = self.driver.GetLeases({'name':sfa_slice['name']}, ['lease_id'])
146         grain = self.driver.GetLeaseGranularity()
147         if leases : 
148             current_leases = [lease['lease_id'] for lease in leases]
149             deleted_leases = list(set(current_leases).difference(kept_leases))
150     
151             try:
152                 if peer:
153                     self.driver.UnBindObjectFromPeer('slice', \
154                                     sfa_slice['slice_id'], peer['shortname'])
155                 deleted = self.driver.DeleteLeases(deleted_leases)
156                 for lease in requested_leases:
157                     added = self.driver.AddLeases(lease['hostname'], \
158                             sfa_slice['name'], int(lease['start_time']), \
159                             int(lease['duration']))
160             #TODO : catch other exception?
161             except KeyError: 
162                 logger.log_exc('Failed to add/remove slice leases')
163
164         return leases
165
166     def verify_slice_nodes(self, sfa_slice, requested_slivers, peer):
167         current_slivers = []
168         deleted_nodes = []
169         
170         if sfa_slice['node_ids']:
171             nodes = self.driver.GetNodes(sfa_slice['node_ids'], ['hostname'])
172             current_slivers = [node['hostname'] for node in nodes]
173     
174             # remove nodes not in rspec
175             deleted_nodes = list(set(current_slivers).\
176                                                 difference(requested_slivers))
177     
178         # add nodes from rspec
179         added_nodes = list(set(requested_slivers).difference(current_slivers))
180         try:
181             #if peer:
182                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], \
183                                                         #peer['shortname'])
184             #PI is a list, get the only username in this list
185             #so that the OAR/LDAP knows the user: 
186             #remove the authority from the name
187             tmp = sfa_slice['PI'][0].split(".")
188             username = tmp[(len(tmp)-1)]
189             #Update the table with the nodes that populate the slice
190             self.driver.db.update_job(sfa_slice['name'], nodes = added_nodes)
191             logger.debug("SLABSLICES \tverify_slice_nodes slice %s "\
192                                                              %(sfa_slice))
193             #If there is a timeslot specified, then a job can be launched
194             try:
195                 #slot = sfa_slice['timeslot']
196                 self.driver.LaunchExperimentOnOAR(sfa_slice, added_nodes, \
197                                                                     username)
198             except KeyError:  
199                 logger.log_exc("SLABSLICES \verify_slice_nodes KeyError \
200                                                 sfa_slice %s  " %(sfa_slice))
201
202
203             if deleted_nodes:
204                 self.driver.DeleteSliceFromNodes(sfa_slice['name'], \
205                                                                 deleted_nodes)
206
207         except: 
208             logger.log_exc('Failed to add/remove slice from nodes')
209             
210
211     def free_egre_key(self):
212         used = set()
213         for tag in self.driver.GetSliceTags({'tagname': 'egre_key'}):
214             used.add(int(tag['value']))
215
216         for i in range(1, 256):
217             if i not in used:
218                 key = i
219                 break
220         else:
221             raise KeyError("No more EGRE keys available")
222
223         return str(key)
224
225   
226        
227                         
228         
229
230     def handle_peer(self, site, sfa_slice, persons, peer):
231         if peer:
232             # bind site
233             try:
234                 if site:
235                     self.driver.BindObjectToPeer('site', site['site_id'], \
236                                         peer['shortname'], sfa_slice['site_id'])
237             except Exception, error:
238                 self.driver.DeleteSite(site['site_id'])
239                 raise error
240             
241             # bind slice
242             try:
243                 if sfa_slice:
244                     self.driver.BindObjectToPeer('slice', slice['slice_id'], \
245                                     peer['shortname'], sfa_slice['slice_id'])
246             except Exception, error:
247                 self.driver.DeleteSlice(sfa_slice['slice_id'])
248                 raise error 
249
250             # bind persons
251             for person in persons:
252                 try:
253                     self.driver.BindObjectToPeer('person', \
254                                     person['person_id'], peer['shortname'], \
255                                     person['peer_person_id'])
256
257                     for (key, remote_key_id) in zip(person['keys'], \
258                                                         person['key_ids']):
259                         try:
260                             self.driver.BindObjectToPeer( 'key', \
261                                             key['key_id'], peer['shortname'], \
262                                             remote_key_id)
263                         except:
264                             self.driver.DeleteKey(key['key_id'])
265                             logger.log_exc("failed to bind key: %s \
266                                             to peer: %s " % (key['key_id'], \
267                                             peer['shortname']))
268                 except Exception, error:
269                     self.driver.DeletePerson(person['person_id'])
270                     raise error       
271
272         return sfa_slice
273
274     #def verify_site(self, slice_xrn, slice_record={}, peer=None, \
275                                         #sfa_peer=None, options={}):
276         #(slice_hrn, type) = urn_to_hrn(slice_xrn)
277         #site_hrn = get_authority(slice_hrn)
278         ## login base can't be longer than 20 characters
279         ##slicename = hrn_to_pl_slicename(slice_hrn)
280         #authority_name = slice_hrn.split('.')[0]
281         #login_base = authority_name[:20]
282         #logger.debug(" SLABSLICES.PY \tverify_site authority_name %s  \
283                                         #login_base %s slice_hrn %s" \
284                                         #%(authority_name,login_base,slice_hrn)
285         
286         #sites = self.driver.GetSites(login_base)
287         #if not sites:
288             ## create new site record
289             #site = {'name': 'geni.%s' % authority_name,
290                     #'abbreviated_name': authority_name,
291                     #'login_base': login_base,
292                     #'max_slices': 100,
293                     #'max_slivers': 1000,
294                     #'enabled': True,
295                     #'peer_site_id': None}
296             #if peer:
297                 #site['peer_site_id'] = slice_record.get('site_id', None)
298             #site['site_id'] = self.driver.AddSite(site)
299             ## exempt federated sites from monitor policies
300             #self.driver.AddSiteTag(site['site_id'], 'exempt_site_until', \
301                                                                 #"20200101")
302             
303             ### is this still necessary?
304             ### add record to the local registry 
305             ##if sfa_peer and slice_record:
306                 ##peer_dict = {'type': 'authority', 'hrn': site_hrn, \
307                              ##'peer_authority': sfa_peer, 'pointer': \
308                                                         #site['site_id']}
309                 ##self.registry.register_peer_object(self.credential, peer_dict)
310         #else:
311             #site =  sites[0]
312             #if peer:
313                 ## unbind from peer so we can modify if necessary.
314                 ## Will bind back later
315                 #self.driver.UnBindObjectFromPeer('site', site['site_id'], \
316                                                             #peer['shortname']) 
317         
318         #return site        
319
320     def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer, options={}):
321
322         #login_base = slice_hrn.split(".")[0]
323         slicename = slice_hrn
324         sl = self.driver.GetSlices(slice_filter = slicename, \
325                                             slice_filter_type = 'slice_hrn') 
326         if sl:
327
328             logger.debug("SLABSLICE \tverify_slice slicename %s sl %s \
329                                 slice_record %s"%(slicename, sl, 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', slice['slice_id'], \
339                                                             #peer['shortname'])
340                 #Update existing record (e.g. expires field) 
341                 #it with the latest info.
342             ##if slice_record and slice['expires'] != slice_record['expires']:
343                 ##self.driver.UpdateSlice( slice['slice_id'], {'expires' : \
344                                                     #slice_record['expires']})
345         else:
346             logger.debug(" SLABSLICES \tverify_slice Oups \
347                         slice_record %s peer %s sfa_peer %s "\
348                         %(slice_record, peer,sfa_peer))
349             sfa_slice = {'slice_hrn': slicename,
350                      #'url': slice_record.get('url', slice_hrn), 
351                      #'description': slice_record.get('description', slice_hrn)
352                      'node_list' : [],
353                      'record_id_user' : slice_record['person_ids'][0],
354                      'record_id_slice': slice_record['record_id'],
355                      'peer_authority':str(peer.hrn)
356                     
357                      }
358             # add the slice  
359             self.driver.AddSlice(sfa_slice)                         
360             #slice['slice_id'] = self.driver.AddSlice(slice)
361             logger.debug("SLABSLICES \tverify_slice ADDSLICE OK") 
362             #slice['node_ids']=[]
363             #slice['person_ids'] = []
364             #if peer:
365                 #slice['peer_slice_id'] = slice_record.get('slice_id', None) 
366             # mark this slice as an sfa peer record
367             #if sfa_peer:
368                 #peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
369                              #'peer_authority': sfa_peer, 'pointer': \
370                                                     #slice['slice_id']}
371                 #self.registry.register_peer_object(self.credential, peer_dict)
372             
373
374        
375         return sfa_slice
376
377
378     def verify_persons(self, slice_hrn, slice_record, users,  peer, sfa_peer, \
379                                                                 options={}):
380         users_by_id = {}
381         users_by_hrn = {}
382         users_dict = {}
383       
384         for user in users:
385             
386             if 'urn' in user and (not 'hrn' in user ) :
387                 user['hrn'], user['type'] = urn_to_hrn(user['urn'])
388                
389             if 'person_id' in user and 'hrn' in user:
390                 users_by_id[user['person_id']] = user
391                 users_dict[user['person_id']] = {'person_id':\
392                                         user['person_id'], 'hrn':user['hrn']}
393
394                 users_by_hrn[user['hrn']] = user
395                 users_dict[user['hrn']] = {'person_id':user['person_id'], \
396                                                         'hrn':user['hrn']}
397                 
398         logger.debug( "SLABSLICE.PY \tverify_person  \
399                         users_dict %s \r\n user_by_hrn %s \r\n \
400                         \tusers_by_id %s " \
401                         %(users_dict,users_by_hrn, users_by_id))
402         
403         existing_user_ids = []
404         existing_user_hrns = []
405         existing_users = []
406         #Check if user is in LDAP using its hrn.
407         #Assuming Senslab is centralised :  one LDAP for all sites, 
408         # user_id unknown from LDAP
409         # LDAP does not provide users id, therfore we rely on hrns
410         if users_by_hrn:
411             #Construct the list of filters for GetPersons
412             filter_user = []
413             for hrn in users_by_hrn:
414                 #filter_user.append ( {'hrn':hrn}) 
415                 filter_user.append (users_by_hrn[hrn])
416             logger.debug(" SLABSLICE.PY \tverify_person  filter_user %s " \
417                                                     %(filter_user))   
418             existing_users = self.driver.GetPersons(filter_user)                
419             #existing_users = self.driver.GetPersons({'hrn': \
420                                             #users_by_hrn.keys()})
421             #existing_users = self.driver.GetPersons({'hrn': \
422                                                     #users_by_hrn.keys()}, \ 
423                                                     #['hrn','pkey'])
424             if existing_users:
425                 for user in existing_users :
426                     #for  k in users_dict[user['hrn']] :
427                     existing_user_hrns.append(users_dict[user['hrn']]['hrn'])
428                     existing_user_ids.\
429                                     append(users_dict[user['hrn']]['person_id'])
430          
431             #User from another federated site , 
432             #does not have a senslab account yet?
433             #or have multiple SFA accounts
434             #Check before adding  them to LDAP
435             
436             else: 
437                
438                 if isinstance(users, list):
439                     ldap_reslt = self.driver.ldap.LdapSearch(users[0])
440                 else:
441                     ldap_reslt = self.driver.ldap.LdapSearch(users)
442                 if ldap_reslt:
443                     existing_users = ldap_reslt[0]
444                     existing_user_hrns.append(users_dict[user['hrn']]['hrn'])
445                     existing_user_ids.\
446                                     append(users_dict[user['hrn']]['person_id'])
447                 else:
448                     #User not existing in LDAP
449             
450                     logger.debug(" SLABSLICE.PY \tverify_person users \
451                                 not in ldap ... %s \r\n \t ldap_reslt %s "  \
452                                                 %(users, ldap_reslt))
453
454                 
455         # requested slice users        
456         requested_user_ids = users_by_id.keys() 
457         requested_user_hrns = users_by_hrn.keys()
458         logger.debug("SLABSLICE.PY \tverify_person requested_user_ids  %s \
459                         user_by_hrn %s " %(requested_user_ids, users_by_hrn)) 
460         # existing slice users
461
462         #existing_slice_users_filter = {'hrn': slice_record['PI'][0]}
463         #logger.debug(" SLABSLICE.PY \tverify_person requested_user_ids %s \
464         #existing_slice_users_filter %s slice_record %s" %(requested_user_ids,\
465         #existing_slice_users_filter,slice_record))
466         
467         #existing_slice_users = \
468                         #self.driver.GetPersons([existing_slice_users_filter])
469         #existing_slice_users = \
470                         #self.driver.GetPersons(existing_slice_users_filter, \
471                         #['hrn','pkey'])
472         #logger.debug("SLABSLICE.PY \tverify_person  existing_slice_users %s " \
473                                     #%(existing_slice_users))
474         #Check that the user of the slice in the slice record
475         #matches the existing users 
476         try:
477             if slice_record['record_id_user'] in requested_user_ids and \
478                                 slice_record['PI'][0] in requested_user_hrns:
479                 logger.debug(" SLABSLICE  \tverify_person  \
480                         requested_user_ids %s = \
481                         slice_record['record_id_user'] %s" \
482                         %(requested_user_ids,slice_record['record_id_user']))
483            
484         except KeyError:
485             pass
486             
487         #existing_slice_user_hrns = [user['hrn'] for \
488                                         #user in existing_slice_users]
489
490         # users to be added, removed or updated
491         #One user in one senslab slice : there should be no need
492         #to remove/ add any user from/to a slice.
493         #However a user from SFA which is not registered in Senslab yet
494         #should be added to the LDAP.
495
496         added_user_hrns = set(requested_user_hrns).\
497                                             difference(set(existing_user_hrns))
498
499         #self.verify_keys(existing_slice_users, updated_users_list, \
500                                                             #peer, append)
501
502         added_persons = []
503         # add new users
504         for added_user_hrn in added_user_hrns:
505             added_user = users_dict[added_user_hrn]
506             #hrn, type = urn_to_hrn(added_user['urn'])  
507             person = {
508                 'first_name': added_user.get('first_name', hrn),
509                 'last_name': added_user.get('last_name', hrn),
510                 'person_id': added_user['person_id'],
511                 'peer_person_id': None,
512                 'keys': [],
513                 'key_ids': added_user.get('key_ids', []),
514                 
515             } 
516             person['person_id'] = self.driver.AddPerson(person)
517             if peer:
518                 person['peer_person_id'] = added_user['person_id']
519             added_persons.append(person)
520            
521             # enable the account 
522             self.driver.UpdatePerson(person['person_id'], {'enabled': True})
523             
524             # add person to site
525             #self.driver.AddPersonToSite(added_user_id, login_base)
526
527             #for key_string in added_user.get('keys', []):
528                 #key = {'key':key_string, 'key_type':'ssh'}
529                 #key['key_id'] = self.driver.AddPersonKey(person['person_id'], \
530                                                 #                       key)
531                 #person['keys'].append(key)
532
533             # add the registry record
534             #if sfa_peer:
535                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': \
536                                                 #sfa_peer, \
537                                                 #'pointer': person['person_id']}
538                 #self.registry.register_peer_object(self.credential, peer_dict)
539         #for added_slice_user_hrn in \
540                                 #added_slice_user_hrns.union(added_user_hrns):
541             #self.driver.AddPersonToSlice(added_slice_user_hrn, \
542                                                     #slice_record['name'])
543         #for added_slice_user_id in \
544                                     #added_slice_user_ids.union(added_user_ids):
545             # add person to the slice 
546             #self.driver.AddPersonToSlice(added_slice_user_id, \
547                                                 #slice_record['name'])
548             # if this is a peer record then it 
549             # should already be bound to a peer.
550             # no need to return worry about it getting bound later 
551
552         return added_persons
553             
554     #Unused
555     def verify_keys(self, persons, users, peer, options={}):
556         # existing keys 
557         key_ids = []
558         for person in persons:
559             key_ids.extend(person['key_ids'])
560         keylist = self.driver.GetKeys(key_ids, ['key_id', 'key'])
561         keydict = {}
562         for key in keylist:
563             keydict[key['key']] = key['key_id']     
564         existing_keys = keydict.keys()
565         persondict = {}
566         for person in persons:
567             persondict[person['email']] = person    
568     
569         # add new keys
570         requested_keys = []
571         updated_persons = []
572         for user in users:
573             user_keys = user.get('keys', [])
574             updated_persons.append(user)
575             for key_string in user_keys:
576                 requested_keys.append(key_string)
577                 if key_string not in existing_keys:
578                     key = {'key': key_string, 'key_type': 'ssh'}
579                     try:
580                         if peer:
581                             person = persondict[user['email']]
582                             self.driver.UnBindObjectFromPeer('person', \
583                                         person['person_id'], peer['shortname'])
584                         key['key_id'] = \
585                                 self.driver.AddPersonKey(user['email'], key)
586                         if peer:
587                             key_index = user_keys.index(key['key'])
588                             remote_key_id = user['key_ids'][key_index]
589                             self.driver.BindObjectToPeer('key', \
590                                             key['key_id'], peer['shortname'], \
591                                             remote_key_id)
592                             
593                     finally:
594                         if peer:
595                             self.driver.BindObjectToPeer('person', \
596                                     person['person_id'], peer['shortname'], \
597                                     user['person_id'])
598         
599         # remove old keys (only if we are not appending)
600         append = options.get('append', True)
601         if append == False: 
602             removed_keys = set(existing_keys).difference(requested_keys)
603             for existing_key_id in keydict:
604                 if keydict[existing_key_id] in removed_keys:
605                     try:
606                         if peer:
607                             self.driver.UnBindObjectFromPeer('key', \
608                                             existing_key_id, peer['shortname'])
609                         self.driver.DeleteKey(existing_key_id)
610                     except:
611                         pass   
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     #def create_slice_aggregate(self, xrn, rspec):
687         #hrn, type = urn_to_hrn(xrn)
688         ## Determine if this is a peer slice
689         #peer = self.get_peer(hrn)
690         #sfa_peer = self.get_sfa_peer(hrn)
691
692         #spec = RSpec(rspec)
693         ## Get the slice record from sfa
694         #slicename = hrn_to_pl_slicename(hrn) 
695         #slice = {}
696         #slice_record = None
697         #registry = self.api.registries[self.api.hrn]
698         #credential = self.api.getCredential()
699
700         #site_id, remote_site_id = self.verify_site(registry, \
701                                         #credential, hrn, peer, sfa_peer)
702         #slice = self.verify_slice(registry, credential, \
703                                 #hrn, site_id, remote_site_id, peer, sfa_peer)
704
705         ## find out where this slice is currently running
706         #nodelist = self.driver.GetNodes(slice['node_ids'], ['hostname'])
707         #hostnames = [node['hostname'] for node in nodelist]
708
709         ## get netspec details
710         #nodespecs = spec.getDictsByTagName('NodeSpec')
711
712         ## dict in which to store slice attributes to set for the nodes
713         #nodes = {}
714         #for nodespec in nodespecs:
715             #if isinstance(nodespec['name'], list):
716                 #for nodename in nodespec['name']:
717                     #nodes[nodename] = {}
718                     #for k in nodespec.keys():
719                         #rspec_attribute_value = nodespec[k]
720                         #if (self.rspec_to_slice_tag.has_key(k)):
721                             #slice_tag_name = self.rspec_to_slice_tag[k]
722                             #nodes[nodename][slice_tag_name] = \
723                                                         #rspec_attribute_value
724             #elif isinstance(nodespec['name'], StringTypes):
725                 #nodename = nodespec['name']
726                 #nodes[nodename] = {}
727                 #for k in nodespec.keys():
728                     #rspec_attribute_value = nodespec[k]
729                     #if (self.rspec_to_slice_tag.has_key(k)):
730                         #slice_tag_name = self.rspec_to_slice_tag[k]
731                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
732
733                 #for k in nodespec.keys():
734                     #rspec_attribute_value = nodespec[k]
735                     #if (self.rspec_to_slice_tag.has_key(k)):
736                         #slice_tag_name = self.rspec_to_slice_tag[k]
737                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
738
739         #node_names = nodes.keys()
740         ## remove nodes not in rspec
741         #deleted_nodes = list(set(hostnames).difference(node_names))
742         ## add nodes from rspec
743         #added_nodes = list(set(node_names).difference(hostnames))
744
745         #try:
746             #if peer:
747                 #self.driver.UnBindObjectFromPeer('slice', \
748                                                     #slice['slice_id'], peer)
749
750             #self.driver.LaunchExperimentOnOAR(slicename, added_nodes) 
751
752             ## Add recognized slice tags
753             #for node_name in node_names:
754                 #node = nodes[node_name]
755                 #for slice_tag in node.keys():
756                     #value = node[slice_tag]
757                     #if (isinstance(value, list)):
758                         #value = value[0]
759
760                     #self.driver.AddSliceTag(slicename, slice_tag, \
761                                                         #value, node_name)
762
763             #self.driver.DeleteSliceFromNodes(slicename, deleted_nodes)
764         #finally:
765             #if peer:
766                 #self.driver.BindObjectToPeer('slice', slice['slice_id'], \
767                                                 #peer, slice['peer_slice_id'])
768
769         #return 1
770