Verify user also work with an urn now (worked only with hrn before). NT
[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             
415             if 'urn' in user and (not 'hrn' in user ) :
416                 user['hrn'],user['type'] = urn_to_hrn(user['urn'])
417                
418             if 'person_id' in user and 'hrn' in user:
419                 users_by_id[user['person_id']] = user
420                 users_dict[user['person_id']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
421
422                 users_by_hrn[user['hrn']] = user
423                 users_dict[user['hrn']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
424                 
425         #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) 
426         
427         existing_user_ids = []
428         existing_user_hrns = []
429         existing_users= []
430         #Check if user is in LDAP using its hrn.
431         #Assuming Senslab is centralised :  one LDAP for all sites, user_id unknown from LDAP
432         # LDAP does not provide users id, therfore we rely on hrns
433         if users_by_hrn:
434             existing_users = self.driver.GetPersons({'hrn': users_by_hrn.keys()}, 
435                                                         ['hrn','pkey'])
436             if existing_users:
437                 for user in existing_users :
438                     #for  k in users_dict[user['hrn']] :
439                     existing_user_hrns.append (users_dict[user['hrn']]['hrn'])
440                     existing_user_ids.append (users_dict[user['hrn']]['person_id'])
441                     #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) 
442          
443
444         # requested slice users        
445         requested_user_ids = users_by_id.keys() 
446         requested_user_hrns = users_by_hrn.keys()
447         #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) 
448         # existing slice users
449         existing_slice_users_filter = {'hrn': slice_record.get('PI', [])}
450         #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)
451         
452         existing_slice_users = self.driver.GetPersons(existing_slice_users_filter,['hrn','pkey'])
453         #print>>sys.stderr, " \r\n \r\n slices.py verify_person   existing_slice_users %s " %(existing_slice_users)
454
455         existing_slice_user_hrns = [user['hrn'] for user in existing_slice_users]
456
457         #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)
458         # users to be added, removed or updated
459
460         added_user_hrns = set(requested_user_hrns).difference(set(existing_user_hrns))
461
462         added_slice_user_hrns = set(requested_user_hrns).difference(existing_slice_user_hrns)
463         
464         removed_user_hrns = set(existing_slice_user_hrns).difference(requested_user_hrns)
465         
466
467         updated_user_hrns = set(existing_slice_user_hrns).intersection(requested_user_hrns)
468         #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)
469         #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)
470         # Remove stale users (only if we are not appending) 
471         append = options.get('append', True)
472         if append == False:
473             for removed_user_hrn in removed_user_hrns:
474                 self.driver.DeletePersonFromSlice(removed_user_hrn, slice_record['name'])
475         # update_existing users
476         updated_users_list = [user for user in existing_slice_users if user['hrn'] in \
477           updated_user_hrns]
478         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) 
479         #self.verify_keys(existing_slice_users, updated_users_list, peer, append)
480
481         added_persons = []
482         # add new users
483         for added_user_hrn in added_user_hrns:
484             added_user = users_dict[added_user_hrn]
485             #hrn, type = urn_to_hrn(added_user['urn'])  
486             person = {
487                 #'first_name': added_user.get('first_name', hrn),
488                 #'last_name': added_user.get('last_name', hrn),
489                 'person_id': added_user['person_id'],
490                 #'peer_person_id': None,
491                 #'keys': [],
492                 #'key_ids': added_user.get('key_ids', []),
493                 
494             } 
495             #print>>sys.stderr, " \r\n \r\n slices.py verify_persons   added_user_ids %s " %(added_user_ids)
496             person['person_id'] = self.driver.AddPerson(person)
497             if peer:
498                 person['peer_person_id'] = added_user['person_id']
499             added_persons.append(person)
500            
501             # enable the account 
502             self.driver.UpdatePerson(person['person_id'], {'enabled': True})
503             
504             # add person to site
505             #self.driver.AddPersonToSite(added_user_id, login_base)
506
507             #for key_string in added_user.get('keys', []):
508                 #key = {'key':key_string, 'key_type':'ssh'}
509                 #key['key_id'] = self.driver.AddPersonKey(person['person_id'], key)
510                 #person['keys'].append(key)
511
512             # add the registry record
513             #if sfa_peer:
514                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': sfa_peer, \
515                     #'pointer': person['person_id']}
516                 #self.registry.register_peer_object(self.credential, peer_dict)
517         for added_slice_user_hrn in added_slice_user_hrns.union(added_user_hrns):           
518             self.driver.AddPersonToSlice(added_slice_user_hrn, slice_record['name'])
519         #for added_slice_user_id in added_slice_user_ids.union(added_user_ids):
520             # add person to the slice 
521             #self.driver.AddPersonToSlice(added_slice_user_id, slice_record['name'])
522             # if this is a peer record then it should already be bound to a peer.
523             # no need to return worry about it getting bound later 
524
525         return added_persons
526             
527
528     def verify_keys(self, persons, users, peer, options={}):
529         # existing keys 
530         key_ids = []
531         for person in persons:
532             key_ids.extend(person['key_ids'])
533         keylist = self.driver.GetKeys(key_ids, ['key_id', 'key'])
534         keydict = {}
535         for key in keylist:
536             keydict[key['key']] = key['key_id']     
537         existing_keys = keydict.keys()
538         persondict = {}
539         for person in persons:
540             persondict[person['email']] = person    
541     
542         # add new keys
543         requested_keys = []
544         updated_persons = []
545         for user in users:
546             user_keys = user.get('keys', [])
547             updated_persons.append(user)
548             for key_string in user_keys:
549                 requested_keys.append(key_string)
550                 if key_string not in existing_keys:
551                     key = {'key': key_string, 'key_type': 'ssh'}
552                     try:
553                         if peer:
554                             person = persondict[user['email']]
555                             self.driver.UnBindObjectFromPeer('person', person['person_id'], peer['shortname'])
556                         key['key_id'] = self.driver.AddPersonKey(user['email'], key)
557                         if peer:
558                             key_index = user_keys.index(key['key'])
559                             remote_key_id = user['key_ids'][key_index]
560                             self.driver.BindObjectToPeer('key', key['key_id'], peer['shortname'], remote_key_id)
561                             
562                     finally:
563                         if peer:
564                             self.driver.BindObjectToPeer('person', person['person_id'], peer['shortname'], user['person_id'])
565         
566         # remove old keys (only if we are not appending)
567         if append == False: 
568             removed_keys = set(existing_keys).difference(requested_keys)
569             for existing_key_id in keydict:
570                 if keydict[existing_key_id] in removed_keys:
571                     try:
572                         if peer:
573                             self.driver.UnBindObjectFromPeer('key', existing_key_id, peer['shortname'])
574                         self.driver.DeleteKey(existing_key_id)
575                     except:
576                         pass   
577
578     #def verify_slice_attributes(self, slice, requested_slice_attributes, append=False, admin=False):
579         ## get list of attributes users ar able to manage
580         #filter = {'category': '*slice*'}
581         #if not admin:
582             #filter['|roles'] = ['user']
583         #slice_attributes = self.driver.GetTagTypes(filter)
584         #valid_slice_attribute_names = [attribute['tagname'] for attribute in slice_attributes]
585
586         ## get sliver attributes
587         #added_slice_attributes = []
588         #removed_slice_attributes = []
589         #ignored_slice_attribute_names = []
590         #existing_slice_attributes = self.driver.GetSliceTags({'slice_id': slice['slice_id']})
591
592         ## get attributes that should be removed
593         #for slice_tag in existing_slice_attributes:
594             #if slice_tag['tagname'] in ignored_slice_attribute_names:
595                 ## If a slice already has a admin only role it was probably given to them by an
596                 ## admin, so we should ignore it.
597                 #ignored_slice_attribute_names.append(slice_tag['tagname'])
598             #else:
599                 ## If an existing slice attribute was not found in the request it should
600                 ## be removed
601                 #attribute_found=False
602                 #for requested_attribute in requested_slice_attributes:
603                     #if requested_attribute['name'] == slice_tag['tagname'] and \
604                        #requested_attribute['value'] == slice_tag['value']:
605                         #attribute_found=True
606                         #break
607
608             #if not attribute_found and not append:
609                 #removed_slice_attributes.append(slice_tag)
610         
611         ## get attributes that should be added:
612         #for requested_attribute in requested_slice_attributes:
613             ## if the requested attribute wasn't found  we should add it
614             #if requested_attribute['name'] in valid_slice_attribute_names:
615                 #attribute_found = False
616                 #for existing_attribute in existing_slice_attributes:
617                     #if requested_attribute['name'] == existing_attribute['tagname'] and \
618                        #requested_attribute['value'] == existing_attribute['value']:
619                         #attribute_found=True
620                         #break
621                 #if not attribute_found:
622                     #added_slice_attributes.append(requested_attribute)
623
624
625         ## remove stale attributes
626         #for attribute in removed_slice_attributes:
627             #try:
628                 #self.driver.DeleteSliceTag(attribute['slice_tag_id'])
629             #except Exception, e:
630                 #self.logger.warn('Failed to remove sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
631                                 #% (name, value,  node_id, str(e)))
632
633         ## add requested_attributes
634         #for attribute in added_slice_attributes:
635             #try:
636                 #self.driver.AddSliceTag(slice['name'], attribute['name'], attribute['value'], attribute.get('node_id', None))
637             #except Exception, e:
638                 #self.logger.warn('Failed to add sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
639                                 #% (name, value,  node_id, str(e)))
640
641     #def create_slice_aggregate(self, xrn, rspec):
642         #hrn, type = urn_to_hrn(xrn)
643         ## Determine if this is a peer slice
644         #peer = self.get_peer(hrn)
645         #sfa_peer = self.get_sfa_peer(hrn)
646
647         #spec = RSpec(rspec)
648         ## Get the slice record from sfa
649         #slicename = hrn_to_pl_slicename(hrn) 
650         #slice = {}
651         #slice_record = None
652         #registry = self.api.registries[self.api.hrn]
653         #credential = self.api.getCredential()
654
655         #site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
656         #slice = self.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer)
657
658         ## find out where this slice is currently running
659         #nodelist = self.driver.GetNodes(slice['node_ids'], ['hostname'])
660         #hostnames = [node['hostname'] for node in nodelist]
661
662         ## get netspec details
663         #nodespecs = spec.getDictsByTagName('NodeSpec')
664
665         ## dict in which to store slice attributes to set for the nodes
666         #nodes = {}
667         #for nodespec in nodespecs:
668             #if isinstance(nodespec['name'], list):
669                 #for nodename in nodespec['name']:
670                     #nodes[nodename] = {}
671                     #for k in nodespec.keys():
672                         #rspec_attribute_value = nodespec[k]
673                         #if (self.rspec_to_slice_tag.has_key(k)):
674                             #slice_tag_name = self.rspec_to_slice_tag[k]
675                             #nodes[nodename][slice_tag_name] = rspec_attribute_value
676             #elif isinstance(nodespec['name'], StringTypes):
677                 #nodename = nodespec['name']
678                 #nodes[nodename] = {}
679                 #for k in nodespec.keys():
680                     #rspec_attribute_value = nodespec[k]
681                     #if (self.rspec_to_slice_tag.has_key(k)):
682                         #slice_tag_name = self.rspec_to_slice_tag[k]
683                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
684
685                 #for k in nodespec.keys():
686                     #rspec_attribute_value = nodespec[k]
687                     #if (self.rspec_to_slice_tag.has_key(k)):
688                         #slice_tag_name = self.rspec_to_slice_tag[k]
689                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
690
691         #node_names = nodes.keys()
692         ## remove nodes not in rspec
693         #deleted_nodes = list(set(hostnames).difference(node_names))
694         ## add nodes from rspec
695         #added_nodes = list(set(node_names).difference(hostnames))
696
697         #try:
698             #if peer:
699                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
700
701             #self.driver.AddSliceToNodes(slicename, added_nodes) 
702
703             ## Add recognized slice tags
704             #for node_name in node_names:
705                 #node = nodes[node_name]
706                 #for slice_tag in node.keys():
707                     #value = node[slice_tag]
708                     #if (isinstance(value, list)):
709                         #value = value[0]
710
711                     #self.driver.AddSliceTag(slicename, slice_tag, value, node_name)
712
713             #self.driver.DeleteSliceFromNodes(slicename, deleted_nodes)
714         #finally:
715             #if peer:
716                 #self.driver.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
717
718         #return 1
719