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