d372eea202bfc2370e399c29ef1e365788a507de
[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.util.plxrn import hrn_to_pl_slicename
6 from sfa.util.policy import Policy
7 from sfa.rspecs.rspec import RSpec
8 from sfa.plc.vlink import VLink
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, 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  #def get_slivers(self, xrn, node=None):
107         #hrn, type = urn_to_hrn(xrn)
108          
109         #slice_name = hrn_to_pl_slicename(hrn)
110         ## XX Should we just call PLCAPI.GetSliceTicket(slice_name) instead
111         ## of doing all of this?
112         ##return self.api.driver.GetSliceTicket(self.auth, slice_name) 
113         
114         ## from PLCAPI.GetSlivers.get_slivers()
115         #slice_fields = ['slice_id', 'name', 'instantiation', 'expires', 'person_ids', 'slice_tag_ids']
116         #slices = self.api.driver.GetSlices(slice_name, slice_fields)
117         ## Build up list of users and slice attributes
118         #person_ids = set()
119         #all_slice_tag_ids = set()
120         #for slice in slices:
121             #person_ids.update(slice['person_ids'])
122             #all_slice_tag_ids.update(slice['slice_tag_ids'])
123         #person_ids = list(person_ids)
124         #all_slice_tag_ids = list(all_slice_tag_ids)
125         ## Get user information
126         #all_persons_list = self.api.driver.GetPersons({'person_id':person_ids,'enabled':True}, ['person_id', 'enabled', 'key_ids'])
127         #all_persons = {}
128         #for person in all_persons_list:
129             #all_persons[person['person_id']] = person        
130
131         ## Build up list of keys
132         #key_ids = set()
133         #for person in all_persons.values():
134             #key_ids.update(person['key_ids'])
135         #key_ids = list(key_ids)
136         ## Get user account keys
137         #all_keys_list = self.api.driver.GetKeys(key_ids, ['key_id', 'key', 'key_type'])
138         #all_keys = {}
139         #for key in all_keys_list:
140             #all_keys[key['key_id']] = key
141         ## Get slice attributes
142         #all_slice_tags_list = self.api.driver.GetSliceTags(all_slice_tag_ids)
143         #all_slice_tags = {}
144         #for slice_tag in all_slice_tags_list:
145             #all_slice_tags[slice_tag['slice_tag_id']] = slice_tag
146            
147         #slivers = []
148         #for slice in slices:
149             #keys = []
150             #for person_id in slice['person_ids']:
151                 #if person_id in all_persons:
152                     #person = all_persons[person_id]
153                     #if not person['enabled']:
154                         #continue
155                     #for key_id in person['key_ids']:
156                         #if key_id in all_keys:
157                             #key = all_keys[key_id]
158                             #keys += [{'key_type': key['key_type'],
159                                     #'key': key['key']}]
160             #attributes = []
161             ## All (per-node and global) attributes for this slice
162             #slice_tags = []
163             #for slice_tag_id in slice['slice_tag_ids']:
164                 #if slice_tag_id in all_slice_tags:
165                     #slice_tags.append(all_slice_tags[slice_tag_id]) 
166             ## Per-node sliver attributes take precedence over global
167             ## slice attributes, so set them first.
168             ## Then comes nodegroup slice attributes
169             ## Followed by global slice attributes
170             #sliver_attributes = []
171
172             #if node is not None:
173                 #for sliver_attribute in filter(lambda a: a['node_id'] == node['node_id'], slice_tags):
174                     #sliver_attributes.append(sliver_attribute['tagname'])
175                     #attributes.append({'tagname': sliver_attribute['tagname'],
176                                     #'value': sliver_attribute['value']})
177
178             ## set nodegroup slice attributes
179             #for slice_tag in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_tags):
180                 ## Do not set any nodegroup slice attributes for
181                 ## which there is at least one sliver attribute
182                 ## already set.
183                 #if slice_tag not in slice_tags:
184                     #attributes.append({'tagname': slice_tag['tagname'],
185                         #'value': slice_tag['value']})
186
187             #for slice_tag in filter(lambda a: a['node_id'] is None, slice_tags):
188                 ## Do not set any global slice attributes for
189                 ## which there is at least one sliver attribute
190                 ## already set.
191                 #if slice_tag['tagname'] not in sliver_attributes:
192                     #attributes.append({'tagname': slice_tag['tagname'],
193                                    #'value': slice_tag['value']})
194
195             ## XXX Sanity check; though technically this should be a system invariant
196             ## checked with an assertion
197             #if slice['expires'] > MAXINT:  slice['expires']= MAXINT
198             
199             #slivers.append({
200                 #'hrn': hrn,
201                 #'name': slice['name'],
202                 #'slice_id': slice['slice_id'],
203                 #'instantiation': slice['instantiation'],
204                 #'expires': slice['expires'],
205                 #'keys': keys,
206                 #'attributes': attributes
207             #})
208
209         #return slivers
210     def get_peer(self, xrn):
211         hrn, type = urn_to_hrn(xrn)
212         #Does this slice belong to a local site or a peer senslab site?
213         peer = None
214         
215         # get this slice's authority (site)
216         slice_authority = get_authority(hrn)
217         
218         # get this site's authority (sfa root authority or sub authority)
219         site_authority = get_authority(slice_authority).lower()
220         print>>sys.stderr, " \r\n \r\n \t slices.py get_peer slice_authority  %s site_authority %s " %(slice_authority, site_authority)
221         # check if we are already peered with this site_authority, if so
222         peers = self.driver.GetPeers({})
223         print>>sys.stderr, " \r\n \r\n \t slices.py get_peer peers %s " %(peers)
224         for peer_record in peers:
225           
226             if site_authority == peer_record.hrn:
227                 peer = peer_record
228         print>>sys.stderr, " \r\n \r\n \t slices.py get_peer peer  %s " %(peer) 
229         return peer
230
231     def get_sfa_peer(self, xrn):
232         hrn, type = urn_to_hrn(xrn)
233
234         # return the authority for this hrn or None if we are the authority
235         sfa_peer = None
236         slice_authority = get_authority(hrn)
237         site_authority = get_authority(slice_authority)
238
239         if site_authority != self.driver.hrn:
240             sfa_peer = site_authority
241
242         return sfa_peer
243
244     def verify_slice_nodes(self, slice, requested_slivers, peer):
245         current_slivers = []
246         deleted_nodes = []
247         if slice['node_ids']:
248             nodes = self.driver.GetNodes(slice['node_ids'], ['hostname'])
249             current_slivers = [node['hostname'] for node in nodes]
250     
251             # remove nodes not in rspec
252             deleted_nodes = list(set(current_slivers).difference(requested_slivers))
253     
254         # add nodes from rspec
255         added_nodes = list(set(requested_slivers).difference(current_slivers))        
256         print>>sys.stderr , "\r\n \r\n \t slices.py  verify_slice_nodes added_nodes %s slice %s" %( added_nodes,slice)
257         try:
258             #if peer:
259                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
260             #PI is a list, get the only username in this list
261             #so that the OAR/LDAP knows the user: remove the authority from the name
262             tmp=  slice['PI'][0].split(".")
263             username = tmp[(len(tmp)-1)]
264             self.driver.AddSliceToNodes(slice['name'], added_nodes, username)
265             
266             if deleted_nodes:
267                 self.driver.DeleteSliceFromNodes(slice['name'], deleted_nodes)
268
269         except: 
270             logger.log_exc('Failed to add/remove slice from nodes')
271
272     def free_egre_key(self):
273         used = set()
274         for tag in self.driver.GetSliceTags({'tagname': 'egre_key'}):
275                 used.add(int(tag['value']))
276
277         for i in range(1, 256):
278             if i not in used:
279                 key = i
280                 break
281         else:
282             raise KeyError("No more EGRE keys available")
283
284         return str(key)
285
286   
287        
288                         
289         
290
291     def handle_peer(self, site, slice, persons, peer):
292         if peer:
293             # bind site
294             try:
295                 if site:
296                     self.driver.BindObjectToPeer('site', site['site_id'], peer['shortname'], slice['site_id'])
297             except Exception,e:
298                 self.driver.DeleteSite(site['site_id'])
299                 raise e
300             
301             # bind slice
302             try:
303                 if slice:
304                     self.driver.BindObjectToPeer('slice', slice['slice_id'], peer['shortname'], slice['slice_id'])
305             except Exception,e:
306                 self.driver.DeleteSlice(slice['slice_id'])
307                 raise e 
308
309             # bind persons
310             for person in persons:
311                 try:
312                     self.driver.BindObjectToPeer('person', 
313                                                      person['person_id'], peer['shortname'], person['peer_person_id'])
314
315                     for (key, remote_key_id) in zip(person['keys'], person['key_ids']):
316                         try:
317                             self.driver.BindObjectToPeer( 'key', key['key_id'], peer['shortname'], remote_key_id)
318                         except:
319                             self.driver.DeleteKey(key['key_id'])
320                             logger("failed to bind key: %s to peer: %s " % (key['key_id'], peer['shortname']))
321                 except Exception,e:
322                     self.driver.DeletePerson(person['person_id'])
323                     raise e       
324
325         return slice
326
327     #def verify_site(self, slice_xrn, slice_record={}, peer=None, sfa_peer=None, options={}):
328         #(slice_hrn, type) = urn_to_hrn(slice_xrn)
329         #site_hrn = get_authority(slice_hrn)
330         ## login base can't be longer than 20 characters
331         ##slicename = hrn_to_pl_slicename(slice_hrn)
332         #authority_name = slice_hrn.split('.')[0]
333         #login_base = authority_name[:20]
334         #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)
335         
336         #sites = self.driver.GetSites(login_base)
337         #if not sites:
338             ## create new site record
339             #site = {'name': 'geni.%s' % authority_name,
340                     #'abbreviated_name': authority_name,
341                     #'login_base': login_base,
342                     #'max_slices': 100,
343                     #'max_slivers': 1000,
344                     #'enabled': True,
345                     #'peer_site_id': None}
346             #if peer:
347                 #site['peer_site_id'] = slice_record.get('site_id', None)
348             #site['site_id'] = self.driver.AddSite(site)
349             ## exempt federated sites from monitor policies
350             #self.driver.AddSiteTag(site['site_id'], 'exempt_site_until', "20200101")
351             
352             ### is this still necessary?
353             ### add record to the local registry 
354             ##if sfa_peer and slice_record:
355                 ##peer_dict = {'type': 'authority', 'hrn': site_hrn, \
356                              ##'peer_authority': sfa_peer, 'pointer': site['site_id']}
357                 ##self.registry.register_peer_object(self.credential, peer_dict)
358         #else:
359             #site =  sites[0]
360             #if peer:
361                 ## unbind from peer so we can modify if necessary. Will bind back later
362                 #self.driver.UnBindObjectFromPeer('site', site['site_id'], peer['shortname']) 
363         
364         #return site        
365
366     def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer, options={} ):
367
368         login_base = slice_hrn.split(".")[0]
369         slicename = slice_hrn
370         sl = self.driver.GetSlices(slice_filter=slicename, filter_type = 'slice_hrn') 
371         if sl:
372
373             print>>sys.stderr, " \r\n \r\rn Slices.py verify_slice slicename %s sl %s slice_record %s"%(slicename ,sl, slice_record)
374         else:
375             print>>sys.stderr, " \r\n \r\rn Slices.py verify_slice UH-Oh..."
376         if not sl:
377             slice = {'name': slicename,
378                      'url': slice_record.get('url', slice_hrn), 
379                      #'description': slice_record.get('description', slice_hrn)
380                      }
381             # add the slice                          
382             slice['slice_id'] = self.driver.AddSlice(slice)
383             slice['node_ids'] = []
384             slice['person_ids'] = []
385             #if peer:
386                 #slice['peer_slice_id'] = slice_record.get('slice_id', None) 
387             # mark this slice as an sfa peer record
388             #if sfa_peer:
389                 #peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
390                              #'peer_authority': sfa_peer, 'pointer': slice['slice_id']}
391                 #self.registry.register_peer_object(self.credential, peer_dict)
392         else:
393             slice = sl
394             slice.update(slice_record)
395             #del slice['last_updated']
396             #del slice['date_created']
397             #if peer:
398                 #slice['peer_slice_id'] = slice_record.get('slice_id', None)
399                 ## unbind from peer so we can modify if necessary. Will bind back later
400                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
401                 #Update existing record (e.g. expires field) it with the latest info.
402             ##if slice_record and slice['expires'] != slice_record['expires']:
403                 ##self.driver.UpdateSlice( slice['slice_id'], {'expires' : slice_record['expires']})
404        
405         return slice
406
407     #def get_existing_persons(self, users):
408     def verify_persons(self, slice_hrn, slice_record, users,  peer, sfa_peer, options={}):
409         users_by_id = {}
410         users_by_hrn = {}
411         users_dict = {}
412       
413         for user in users:
414             if 'person_id' in user and 'hrn' in user:
415                 users_by_id[user['person_id']] = user
416                 users_dict[user['person_id']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
417
418                 users_by_hrn[user['hrn']] = user
419                 users_dict[user['hrn']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
420                 
421         #print>>sys.stderr, " \r\n \r\n \t slabslices.py verify_person  users_dict %s \r\n user_by_hrn %s \r\n \tusers_by_id %s " %( users_dict,users_by_hrn, users_by_id) 
422         
423         existing_user_ids = []
424         existing_user_hrns = []
425         existing_users= []
426         #Check if user is in LDAP using its hrn.
427         #Assuming Senslab is centralised :  one LDAP for all sites, user_id unknown from LDAP
428         # LDAP does not provide users id, therfore we rely on hrns
429         if users_by_hrn:
430             existing_users = self.driver.GetPersons({'hrn': users_by_hrn.keys()}, 
431                                                         ['hrn','pkey'])
432             if existing_users:
433                 for user in existing_users :
434                     #for  k in users_dict[user['hrn']] :
435                     existing_user_hrns.append (users_dict[user['hrn']]['hrn'])
436                     existing_user_ids.append (users_dict[user['hrn']]['person_id'])
437                     #print>>sys.stderr, " \r\n \r\n \t slabslices.py verify_person  existing_user_ids.append (users_dict[user['hrn']][k]) %s \r\n existing_users %s " %(  existing_user_ids,existing_users) 
438          
439
440         # requested slice users        
441         requested_user_ids = users_by_id.keys() 
442         requested_user_hrns = users_by_hrn.keys()
443         #print>>sys.stderr, " \r\n \r\n \t slabslices.py verify_person  requested_user_ids  %s user_by_hrn %s " %( requested_user_ids,users_by_hrn) 
444         # existing slice users
445         existing_slice_users_filter = {'hrn': slice_record.get('PI', [])}
446         #print>>sys.stderr, " \r\n \r\n slices.py verify_person requested_user_ids %s existing_slice_users_filter %s slice_record %s" %(requested_user_ids,existing_slice_users_filter,slice_record)
447         
448         existing_slice_users = self.driver.GetPersons(existing_slice_users_filter,['hrn','pkey'])
449         #print>>sys.stderr, " \r\n \r\n slices.py verify_person   existing_slice_users %s " %(existing_slice_users)
450
451         existing_slice_user_hrns = [user['hrn'] for user in existing_slice_users]
452
453         #print>>sys.stderr, " \r\n \r\n slices.py verify_person requested_user_ids %s  existing_slice_user_hrns %s " %(requested_user_ids,existing_slice_user_hrns)
454         # users to be added, removed or updated
455
456         added_user_hrns = set(requested_user_hrns).difference(set(existing_user_hrns))
457
458         added_slice_user_hrns = set(requested_user_hrns).difference(existing_slice_user_hrns)
459         
460         removed_user_hrns = set(existing_slice_user_hrns).difference(requested_user_hrns)
461         
462
463         updated_user_hrns = set(existing_slice_user_hrns).intersection(requested_user_hrns)
464         #print>>sys.stderr, " \r\n \r\n slices.py verify_persons  added_user_ids %s added_slice_user_ids %s " %(added_user_ids,added_slice_user_ids)
465         #print>>sys.stderr, " \r\n \r\n slices.py verify_persons  removed_user_hrns %s updated_user_hrns %s " %(removed_user_hrns,updated_user_hrns)
466         # Remove stale users (only if we are not appending) 
467         append = options.get('append', True)
468         if append == False:
469             for removed_user_hrn in removed_user_hrns:
470                 self.driver.DeletePersonFromSlice(removed_user_hrn, slice_record['name'])
471         # update_existing users
472         updated_users_list = [user for user in existing_slice_users if user['hrn'] in \
473           updated_user_hrns]
474         print>>sys.stderr, " \r\n \r\n slices.py verify_persons  removed_user_hrns %s updated_users_list %s " %(removed_user_hrns,updated_users_list) 
475         #self.verify_keys(existing_slice_users, updated_users_list, peer, append)
476
477         added_persons = []
478         # add new users
479         for added_user_hrn in added_user_hrns:
480             added_user = users_dict[added_user_hrn]
481             #hrn, type = urn_to_hrn(added_user['urn'])  
482             person = {
483                 #'first_name': added_user.get('first_name', hrn),
484                 #'last_name': added_user.get('last_name', hrn),
485                 'person_id': added_user['person_id'],
486                 #'peer_person_id': None,
487                 #'keys': [],
488                 #'key_ids': added_user.get('key_ids', []),
489                 
490             } 
491             #print>>sys.stderr, " \r\n \r\n slices.py verify_persons   added_user_ids %s " %(added_user_ids)
492             person['person_id'] = self.driver.AddPerson(person)
493             if peer:
494                 person['peer_person_id'] = added_user['person_id']
495             added_persons.append(person)
496            
497             # enable the account 
498             self.driver.UpdatePerson(person['person_id'], {'enabled': True})
499             
500             # add person to site
501             #self.driver.AddPersonToSite(added_user_id, login_base)
502
503             #for key_string in added_user.get('keys', []):
504                 #key = {'key':key_string, 'key_type':'ssh'}
505                 #key['key_id'] = self.driver.AddPersonKey(person['person_id'], key)
506                 #person['keys'].append(key)
507
508             # add the registry record
509             #if sfa_peer:
510                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': sfa_peer, \
511                     #'pointer': person['person_id']}
512                 #self.registry.register_peer_object(self.credential, peer_dict)
513         for added_slice_user_hrn in added_slice_user_hrns.union(added_user_hrns):           
514             self.driver.AddPersonToSlice(added_slice_user_hrn, slice_record['name'])
515         #for added_slice_user_id in added_slice_user_ids.union(added_user_ids):
516             # add person to the slice 
517             #self.driver.AddPersonToSlice(added_slice_user_id, slice_record['name'])
518             # if this is a peer record then it should already be bound to a peer.
519             # no need to return worry about it getting bound later 
520
521         return added_persons
522             
523
524     def verify_keys(self, persons, users, peer, options={}):
525         # existing keys 
526         key_ids = []
527         for person in persons:
528             key_ids.extend(person['key_ids'])
529         keylist = self.driver.GetKeys(key_ids, ['key_id', 'key'])
530         keydict = {}
531         for key in keylist:
532             keydict[key['key']] = key['key_id']     
533         existing_keys = keydict.keys()
534         persondict = {}
535         for person in persons:
536             persondict[person['email']] = person    
537     
538         # add new keys
539         requested_keys = []
540         updated_persons = []
541         for user in users:
542             user_keys = user.get('keys', [])
543             updated_persons.append(user)
544             for key_string in user_keys:
545                 requested_keys.append(key_string)
546                 if key_string not in existing_keys:
547                     key = {'key': key_string, 'key_type': 'ssh'}
548                     try:
549                         if peer:
550                             person = persondict[user['email']]
551                             self.driver.UnBindObjectFromPeer('person', person['person_id'], peer['shortname'])
552                         key['key_id'] = self.driver.AddPersonKey(user['email'], key)
553                         if peer:
554                             key_index = user_keys.index(key['key'])
555                             remote_key_id = user['key_ids'][key_index]
556                             self.driver.BindObjectToPeer('key', key['key_id'], peer['shortname'], remote_key_id)
557                             
558                     finally:
559                         if peer:
560                             self.driver.BindObjectToPeer('person', person['person_id'], peer['shortname'], user['person_id'])
561         
562         # remove old keys (only if we are not appending)
563         if append == False: 
564             removed_keys = set(existing_keys).difference(requested_keys)
565             for existing_key_id in keydict:
566                 if keydict[existing_key_id] in removed_keys:
567                     try:
568                         if peer:
569                             self.driver.UnBindObjectFromPeer('key', existing_key_id, peer['shortname'])
570                         self.driver.DeleteKey(existing_key_id)
571                     except:
572                         pass   
573
574     #def verify_slice_attributes(self, slice, requested_slice_attributes, append=False, admin=False):
575         ## get list of attributes users ar able to manage
576         #filter = {'category': '*slice*'}
577         #if not admin:
578             #filter['|roles'] = ['user']
579         #slice_attributes = self.driver.GetTagTypes(filter)
580         #valid_slice_attribute_names = [attribute['tagname'] for attribute in slice_attributes]
581
582         ## get sliver attributes
583         #added_slice_attributes = []
584         #removed_slice_attributes = []
585         #ignored_slice_attribute_names = []
586         #existing_slice_attributes = self.driver.GetSliceTags({'slice_id': slice['slice_id']})
587
588         ## get attributes that should be removed
589         #for slice_tag in existing_slice_attributes:
590             #if slice_tag['tagname'] in ignored_slice_attribute_names:
591                 ## If a slice already has a admin only role it was probably given to them by an
592                 ## admin, so we should ignore it.
593                 #ignored_slice_attribute_names.append(slice_tag['tagname'])
594             #else:
595                 ## If an existing slice attribute was not found in the request it should
596                 ## be removed
597                 #attribute_found=False
598                 #for requested_attribute in requested_slice_attributes:
599                     #if requested_attribute['name'] == slice_tag['tagname'] and \
600                        #requested_attribute['value'] == slice_tag['value']:
601                         #attribute_found=True
602                         #break
603
604             #if not attribute_found and not append:
605                 #removed_slice_attributes.append(slice_tag)
606         
607         ## get attributes that should be added:
608         #for requested_attribute in requested_slice_attributes:
609             ## if the requested attribute wasn't found  we should add it
610             #if requested_attribute['name'] in valid_slice_attribute_names:
611                 #attribute_found = False
612                 #for existing_attribute in existing_slice_attributes:
613                     #if requested_attribute['name'] == existing_attribute['tagname'] and \
614                        #requested_attribute['value'] == existing_attribute['value']:
615                         #attribute_found=True
616                         #break
617                 #if not attribute_found:
618                     #added_slice_attributes.append(requested_attribute)
619
620
621         ## remove stale attributes
622         #for attribute in removed_slice_attributes:
623             #try:
624                 #self.driver.DeleteSliceTag(attribute['slice_tag_id'])
625             #except Exception, e:
626                 #self.logger.warn('Failed to remove sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
627                                 #% (name, value,  node_id, str(e)))
628
629         ## add requested_attributes
630         #for attribute in added_slice_attributes:
631             #try:
632                 #self.driver.AddSliceTag(slice['name'], attribute['name'], attribute['value'], attribute.get('node_id', None))
633             #except Exception, e:
634                 #self.logger.warn('Failed to add sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
635                                 #% (name, value,  node_id, str(e)))
636
637     #def create_slice_aggregate(self, xrn, rspec):
638         #hrn, type = urn_to_hrn(xrn)
639         ## Determine if this is a peer slice
640         #peer = self.get_peer(hrn)
641         #sfa_peer = self.get_sfa_peer(hrn)
642
643         #spec = RSpec(rspec)
644         ## Get the slice record from sfa
645         #slicename = hrn_to_pl_slicename(hrn) 
646         #slice = {}
647         #slice_record = None
648         #registry = self.api.registries[self.api.hrn]
649         #credential = self.api.getCredential()
650
651         #site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
652         #slice = self.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer)
653
654         ## find out where this slice is currently running
655         #nodelist = self.driver.GetNodes(slice['node_ids'], ['hostname'])
656         #hostnames = [node['hostname'] for node in nodelist]
657
658         ## get netspec details
659         #nodespecs = spec.getDictsByTagName('NodeSpec')
660
661         ## dict in which to store slice attributes to set for the nodes
662         #nodes = {}
663         #for nodespec in nodespecs:
664             #if isinstance(nodespec['name'], list):
665                 #for nodename in nodespec['name']:
666                     #nodes[nodename] = {}
667                     #for k in nodespec.keys():
668                         #rspec_attribute_value = nodespec[k]
669                         #if (self.rspec_to_slice_tag.has_key(k)):
670                             #slice_tag_name = self.rspec_to_slice_tag[k]
671                             #nodes[nodename][slice_tag_name] = rspec_attribute_value
672             #elif isinstance(nodespec['name'], StringTypes):
673                 #nodename = nodespec['name']
674                 #nodes[nodename] = {}
675                 #for k in nodespec.keys():
676                     #rspec_attribute_value = nodespec[k]
677                     #if (self.rspec_to_slice_tag.has_key(k)):
678                         #slice_tag_name = self.rspec_to_slice_tag[k]
679                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
680
681                 #for k in nodespec.keys():
682                     #rspec_attribute_value = nodespec[k]
683                     #if (self.rspec_to_slice_tag.has_key(k)):
684                         #slice_tag_name = self.rspec_to_slice_tag[k]
685                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
686
687         #node_names = nodes.keys()
688         ## remove nodes not in rspec
689         #deleted_nodes = list(set(hostnames).difference(node_names))
690         ## add nodes from rspec
691         #added_nodes = list(set(node_names).difference(hostnames))
692
693         #try:
694             #if peer:
695                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
696
697             #self.driver.AddSliceToNodes(slicename, added_nodes) 
698
699             ## Add recognized slice tags
700             #for node_name in node_names:
701                 #node = nodes[node_name]
702                 #for slice_tag in node.keys():
703                     #value = node[slice_tag]
704                     #if (isinstance(value, list)):
705                         #value = value[0]
706
707                     #self.driver.AddSliceTag(slicename, slice_tag, value, node_name)
708
709             #self.driver.DeleteSliceFromNodes(slicename, deleted_nodes)
710         #finally:
711             #if peer:
712                 #self.driver.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
713
714         #return 1
715