Modified LdapAPI.py and client_helper to match the master one.
[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         site_authority = slice_authority
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 hrn %s" %(slice_authority, site_authority, hrn)
221         # check if we are already peered with this site_authority, if so
222         #peers = self.driver.GetPeers({})  
223         peers = self.driver.GetPeers(peer_filter = slice_authority)
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_peerAPRES Mpeer  %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         
248         if slice['node_ids']:
249             nodes = self.driver.GetNodes(slice['node_ids'], ['hostname'])
250             current_slivers = [node['hostname'] for node in nodes]
251     
252             # remove nodes not in rspec
253             deleted_nodes = list(set(current_slivers).difference(requested_slivers))
254     
255         # add nodes from rspec
256         added_nodes = list(set(requested_slivers).difference(current_slivers))        
257         #print>>sys.stderr , "\r\n \r\n \t slices.py  verify_slice_nodes added_nodes %s slice %s" %( added_nodes,slice)
258         try:
259             #if peer:
260                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
261             #PI is a list, get the only username in this list
262             #so that the OAR/LDAP knows the user: remove the authority from the name
263             tmp=  slice['PI'][0].split(".")
264             username = tmp[(len(tmp)-1)]
265             #Update the table with the nodes that populate the slice
266             self.driver.db.update_job(slice['name'],nodes = added_nodes)
267             print>>sys.stderr, "\r\n \\r\n \r\n \t\t\t VERIFY_SLICE_NODES slice %s \r\n \r\n \r\n " %(slice)
268             #If there is a timeslot specified, then a job can be launched
269             try:
270                 slot = slice['timeslot']
271                 self.driver.LaunchExperimentOnOAR(slice, added_nodes, username)
272             except KeyError:
273                 pass
274
275             
276             if deleted_nodes:
277                 self.driver.DeleteSliceFromNodes(slice['name'], deleted_nodes)
278
279         except: 
280             logger.log_exc('Failed to add/remove slice from nodes')
281             
282
283     def free_egre_key(self):
284         used = set()
285         for tag in self.driver.GetSliceTags({'tagname': 'egre_key'}):
286                 used.add(int(tag['value']))
287
288         for i in range(1, 256):
289             if i not in used:
290                 key = i
291                 break
292         else:
293             raise KeyError("No more EGRE keys available")
294
295         return str(key)
296
297   
298        
299                         
300         
301
302     def handle_peer(self, site, slice, persons, peer):
303         if peer:
304             # bind site
305             try:
306                 if site:
307                     self.driver.BindObjectToPeer('site', site['site_id'], peer['shortname'], slice['site_id'])
308             except Exception,e:
309                 self.driver.DeleteSite(site['site_id'])
310                 raise e
311             
312             # bind slice
313             try:
314                 if slice:
315                     self.driver.BindObjectToPeer('slice', slice['slice_id'], peer['shortname'], slice['slice_id'])
316             except Exception,e:
317                 self.driver.DeleteSlice(slice['slice_id'])
318                 raise e 
319
320             # bind persons
321             for person in persons:
322                 try:
323                     self.driver.BindObjectToPeer('person', 
324                                                      person['person_id'], peer['shortname'], person['peer_person_id'])
325
326                     for (key, remote_key_id) in zip(person['keys'], person['key_ids']):
327                         try:
328                             self.driver.BindObjectToPeer( 'key', key['key_id'], peer['shortname'], remote_key_id)
329                         except:
330                             self.driver.DeleteKey(key['key_id'])
331                             logger("failed to bind key: %s to peer: %s " % (key['key_id'], peer['shortname']))
332                 except Exception,e:
333                     self.driver.DeletePerson(person['person_id'])
334                     raise e       
335
336         return slice
337
338     #def verify_site(self, slice_xrn, slice_record={}, peer=None, sfa_peer=None, options={}):
339         #(slice_hrn, type) = urn_to_hrn(slice_xrn)
340         #site_hrn = get_authority(slice_hrn)
341         ## login base can't be longer than 20 characters
342         ##slicename = hrn_to_pl_slicename(slice_hrn)
343         #authority_name = slice_hrn.split('.')[0]
344         #login_base = authority_name[:20]
345         #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)
346         
347         #sites = self.driver.GetSites(login_base)
348         #if not sites:
349             ## create new site record
350             #site = {'name': 'geni.%s' % authority_name,
351                     #'abbreviated_name': authority_name,
352                     #'login_base': login_base,
353                     #'max_slices': 100,
354                     #'max_slivers': 1000,
355                     #'enabled': True,
356                     #'peer_site_id': None}
357             #if peer:
358                 #site['peer_site_id'] = slice_record.get('site_id', None)
359             #site['site_id'] = self.driver.AddSite(site)
360             ## exempt federated sites from monitor policies
361             #self.driver.AddSiteTag(site['site_id'], 'exempt_site_until', "20200101")
362             
363             ### is this still necessary?
364             ### add record to the local registry 
365             ##if sfa_peer and slice_record:
366                 ##peer_dict = {'type': 'authority', 'hrn': site_hrn, \
367                              ##'peer_authority': sfa_peer, 'pointer': site['site_id']}
368                 ##self.registry.register_peer_object(self.credential, peer_dict)
369         #else:
370             #site =  sites[0]
371             #if peer:
372                 ## unbind from peer so we can modify if necessary. Will bind back later
373                 #self.driver.UnBindObjectFromPeer('site', site['site_id'], peer['shortname']) 
374         
375         #return site        
376
377     def verify_slice(self, slice_hrn, slice_record, peer, sfa_peer, options={} ):
378
379         login_base = slice_hrn.split(".")[0]
380         slicename = slice_hrn
381         sl = self.driver.GetSlices(slice_filter=slicename, filter_type = 'slice_hrn') 
382         if sl:
383
384             print>>sys.stderr, " \r\n \r\rn Slices.py verify_slice slicename %s sl %s slice_record %s"%(slicename ,sl, slice_record)
385             slice = sl
386             slice.update(slice_record)
387             #del slice['last_updated']
388             #del slice['date_created']
389             #if peer:
390                 #slice['peer_slice_id'] = slice_record.get('slice_id', None)
391                 ## unbind from peer so we can modify if necessary. Will bind back later
392                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer['shortname'])
393                 #Update existing record (e.g. expires field) it with the latest info.
394             ##if slice_record and slice['expires'] != slice_record['expires']:
395                 ##self.driver.UpdateSlice( slice['slice_id'], {'expires' : slice_record['expires']})
396         else:
397             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)
398             slice = {'slice_hrn': slicename,
399                      #'url': slice_record.get('url', slice_hrn), 
400                      #'description': slice_record.get('description', slice_hrn)
401                      'node_list' : [],
402                      'record_id_user' : slice_record['person_ids'][0],
403                      'record_id_slice': slice_record['record_id'],
404                      'peer_authority':str(peer.hrn)
405                     
406                      }
407             # add the slice  
408             self.driver.AddSlice(slice)                         
409             #slice['slice_id'] = self.driver.AddSlice(slice)
410             print>>sys.stderr, " \r\n \r\rn Slices.py verify_slice ADDSLICE OHYEEEEEEEEEEAH! " 
411             #slice['node_ids']=[]
412             #slice['person_ids'] = []
413             #if peer:
414                 #slice['peer_slice_id'] = slice_record.get('slice_id', None) 
415             # mark this slice as an sfa peer record
416             #if sfa_peer:
417                 #peer_dict = {'type': 'slice', 'hrn': slice_hrn, 
418                              #'peer_authority': sfa_peer, 'pointer': slice['slice_id']}
419                 #self.registry.register_peer_object(self.credential, peer_dict)
420             
421
422        
423         return slice
424
425
426     def verify_persons(self, slice_hrn, slice_record, users,  peer, sfa_peer, options={}):
427         users_by_id = {}
428         users_by_hrn = {}
429         users_dict = {}
430       
431         for user in users:
432             
433             if 'urn' in user and (not 'hrn' in user ) :
434                 user['hrn'],user['type'] = urn_to_hrn(user['urn'])
435                
436             if 'person_id' in user and 'hrn' in user:
437                 users_by_id[user['person_id']] = user
438                 users_dict[user['person_id']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
439
440                 users_by_hrn[user['hrn']] = user
441                 users_dict[user['hrn']] = {'person_id':user['person_id'], 'hrn':user['hrn']}
442                 
443         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) 
444         
445         existing_user_ids = []
446         existing_user_hrns = []
447         existing_users= []
448         #Check if user is in LDAP using its hrn.
449         #Assuming Senslab is centralised :  one LDAP for all sites, user_id unknown from LDAP
450         # LDAP does not provide users id, therfore we rely on hrns
451         if users_by_hrn:            
452             existing_users = self.driver.GetPersons({'hrn': users_by_hrn.keys()})
453             #existing_users = self.driver.GetPersons({'hrn': users_by_hrn.keys()}, 
454                                                         #['hrn','pkey'])
455             if existing_users:
456                 for user in existing_users :
457                     #for  k in users_dict[user['hrn']] :
458                     existing_user_hrns.append (users_dict[user['hrn']]['hrn'])
459                     existing_user_ids.append (users_dict[user['hrn']]['person_id'])
460                     #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) 
461          
462             #User from another federated site , does not have a senslab account yet?
463             #or have multiple SFA accounts
464             #Check before adding  them to LDAP
465             
466             else: 
467                
468                 if isinstance(users,list):
469                    ldap_reslt = self.driver.ldap.ldapSearch(users[0])
470                 else:
471                     ldap_reslt = self.driver.ldap.ldapSearch(users)
472                 if ldap_result:
473                     existing_users = ldap_reslt[0]
474                     existing_user_hrns.append (users_dict[user['hrn']]['hrn'])
475                     existing_user_ids.append (users_dict[user['hrn']]['person_id'])
476                 else:
477                     #User not existing in LDAP
478             
479                     print>>sys.stderr, " \r\n \r\n \t slabslices.py verify_person users HUMHUMHUMHUM ... %s \r\n \t ldap_reslt %s "  %(users, ldap_reslt)
480
481                 
482         # requested slice users        
483         requested_user_ids = users_by_id.keys() 
484         requested_user_hrns = users_by_hrn.keys()
485         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) 
486         # existing slice users
487         existing_slice_users_filter = {'hrn': slice_record.get('PI', [])}
488         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)
489         
490         existing_slice_users = self.driver.GetPersons(existing_slice_users_filter)
491         #existing_slice_users = self.driver.GetPersons(existing_slice_users_filter,['hrn','pkey'])
492         print>>sys.stderr, " \r\n \r\n slices.py verify_person   existing_slice_users %s " %(existing_slice_users)
493
494         existing_slice_user_hrns = [user['hrn'] for user in existing_slice_users]
495
496         #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)
497         # users to be added, removed or updated
498
499         added_user_hrns = set(requested_user_hrns).difference(set(existing_user_hrns))
500
501         added_slice_user_hrns = set(requested_user_hrns).difference(existing_slice_user_hrns)
502         
503         removed_user_hrns = set(existing_slice_user_hrns).difference(requested_user_hrns)
504         
505
506         updated_user_hrns = set(existing_slice_user_hrns).intersection(requested_user_hrns)
507         #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)
508         #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)
509         # Remove stale users (only if we are not appending) 
510         append = options.get('append', True)
511         if append == False:
512             for removed_user_hrn in removed_user_hrns:
513                 self.driver.DeletePersonFromSlice(removed_user_hrn, slice_record['name'])
514         # update_existing users
515         updated_users_list = [user for user in existing_slice_users if user['hrn'] in \
516           updated_user_hrns]
517         #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) 
518         #self.verify_keys(existing_slice_users, updated_users_list, peer, append)
519
520         added_persons = []
521         # add new users
522         for added_user_hrn in added_user_hrns:
523             added_user = users_dict[added_user_hrn]
524             #hrn, type = urn_to_hrn(added_user['urn'])  
525             person = {
526                 #'first_name': added_user.get('first_name', hrn),
527                 #'last_name': added_user.get('last_name', hrn),
528                 'person_id': added_user['person_id'],
529                 #'peer_person_id': None,
530                 #'keys': [],
531                 #'key_ids': added_user.get('key_ids', []),
532                 
533             } 
534             #print>>sys.stderr, " \r\n \r\n slices.py verify_persons   added_user_ids %s " %(added_user_ids)
535             person['person_id'] = self.driver.AddPerson(person)
536             if peer:
537                 person['peer_person_id'] = added_user['person_id']
538             added_persons.append(person)
539            
540             # enable the account 
541             self.driver.UpdatePerson(person['person_id'], {'enabled': True})
542             
543             # add person to site
544             #self.driver.AddPersonToSite(added_user_id, login_base)
545
546             #for key_string in added_user.get('keys', []):
547                 #key = {'key':key_string, 'key_type':'ssh'}
548                 #key['key_id'] = self.driver.AddPersonKey(person['person_id'], key)
549                 #person['keys'].append(key)
550
551             # add the registry record
552             #if sfa_peer:
553                 #peer_dict = {'type': 'user', 'hrn': hrn, 'peer_authority': sfa_peer, \
554                     #'pointer': person['person_id']}
555                 #self.registry.register_peer_object(self.credential, peer_dict)
556         for added_slice_user_hrn in added_slice_user_hrns.union(added_user_hrns):           
557             self.driver.AddPersonToSlice(added_slice_user_hrn, slice_record['name'])
558         #for added_slice_user_id in added_slice_user_ids.union(added_user_ids):
559             # add person to the slice 
560             #self.driver.AddPersonToSlice(added_slice_user_id, slice_record['name'])
561             # if this is a peer record then it should already be bound to a peer.
562             # no need to return worry about it getting bound later 
563
564         return added_persons
565             
566
567     def verify_keys(self, persons, users, peer, options={}):
568         # existing keys 
569         key_ids = []
570         for person in persons:
571             key_ids.extend(person['key_ids'])
572         keylist = self.driver.GetKeys(key_ids, ['key_id', 'key'])
573         keydict = {}
574         for key in keylist:
575             keydict[key['key']] = key['key_id']     
576         existing_keys = keydict.keys()
577         persondict = {}
578         for person in persons:
579             persondict[person['email']] = person    
580     
581         # add new keys
582         requested_keys = []
583         updated_persons = []
584         for user in users:
585             user_keys = user.get('keys', [])
586             updated_persons.append(user)
587             for key_string in user_keys:
588                 requested_keys.append(key_string)
589                 if key_string not in existing_keys:
590                     key = {'key': key_string, 'key_type': 'ssh'}
591                     try:
592                         if peer:
593                             person = persondict[user['email']]
594                             self.driver.UnBindObjectFromPeer('person', person['person_id'], peer['shortname'])
595                         key['key_id'] = self.driver.AddPersonKey(user['email'], key)
596                         if peer:
597                             key_index = user_keys.index(key['key'])
598                             remote_key_id = user['key_ids'][key_index]
599                             self.driver.BindObjectToPeer('key', key['key_id'], peer['shortname'], remote_key_id)
600                             
601                     finally:
602                         if peer:
603                             self.driver.BindObjectToPeer('person', person['person_id'], peer['shortname'], user['person_id'])
604         
605         # remove old keys (only if we are not appending)
606         if append == False: 
607             removed_keys = set(existing_keys).difference(requested_keys)
608             for existing_key_id in keydict:
609                 if keydict[existing_key_id] in removed_keys:
610                     try:
611                         if peer:
612                             self.driver.UnBindObjectFromPeer('key', existing_key_id, peer['shortname'])
613                         self.driver.DeleteKey(existing_key_id)
614                     except:
615                         pass   
616
617     #def verify_slice_attributes(self, slice, requested_slice_attributes, append=False, admin=False):
618         ## get list of attributes users ar able to manage
619         #filter = {'category': '*slice*'}
620         #if not admin:
621             #filter['|roles'] = ['user']
622         #slice_attributes = self.driver.GetTagTypes(filter)
623         #valid_slice_attribute_names = [attribute['tagname'] for attribute in slice_attributes]
624
625         ## get sliver attributes
626         #added_slice_attributes = []
627         #removed_slice_attributes = []
628         #ignored_slice_attribute_names = []
629         #existing_slice_attributes = self.driver.GetSliceTags({'slice_id': slice['slice_id']})
630
631         ## get attributes that should be removed
632         #for slice_tag in existing_slice_attributes:
633             #if slice_tag['tagname'] in ignored_slice_attribute_names:
634                 ## If a slice already has a admin only role it was probably given to them by an
635                 ## admin, so we should ignore it.
636                 #ignored_slice_attribute_names.append(slice_tag['tagname'])
637             #else:
638                 ## If an existing slice attribute was not found in the request it should
639                 ## be removed
640                 #attribute_found=False
641                 #for requested_attribute in requested_slice_attributes:
642                     #if requested_attribute['name'] == slice_tag['tagname'] and \
643                        #requested_attribute['value'] == slice_tag['value']:
644                         #attribute_found=True
645                         #break
646
647             #if not attribute_found and not append:
648                 #removed_slice_attributes.append(slice_tag)
649         
650         ## get attributes that should be added:
651         #for requested_attribute in requested_slice_attributes:
652             ## if the requested attribute wasn't found  we should add it
653             #if requested_attribute['name'] in valid_slice_attribute_names:
654                 #attribute_found = False
655                 #for existing_attribute in existing_slice_attributes:
656                     #if requested_attribute['name'] == existing_attribute['tagname'] and \
657                        #requested_attribute['value'] == existing_attribute['value']:
658                         #attribute_found=True
659                         #break
660                 #if not attribute_found:
661                     #added_slice_attributes.append(requested_attribute)
662
663
664         ## remove stale attributes
665         #for attribute in removed_slice_attributes:
666             #try:
667                 #self.driver.DeleteSliceTag(attribute['slice_tag_id'])
668             #except Exception, e:
669                 #self.logger.warn('Failed to remove sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
670                                 #% (name, value,  node_id, str(e)))
671
672         ## add requested_attributes
673         #for attribute in added_slice_attributes:
674             #try:
675                 #self.driver.AddSliceTag(slice['name'], attribute['name'], attribute['value'], attribute.get('node_id', None))
676             #except Exception, e:
677                 #self.logger.warn('Failed to add sliver attribute. name: %s, value: %s, node_id: %s\nCause:%s'\
678                                 #% (name, value,  node_id, str(e)))
679
680     #def create_slice_aggregate(self, xrn, rspec):
681         #hrn, type = urn_to_hrn(xrn)
682         ## Determine if this is a peer slice
683         #peer = self.get_peer(hrn)
684         #sfa_peer = self.get_sfa_peer(hrn)
685
686         #spec = RSpec(rspec)
687         ## Get the slice record from sfa
688         #slicename = hrn_to_pl_slicename(hrn) 
689         #slice = {}
690         #slice_record = None
691         #registry = self.api.registries[self.api.hrn]
692         #credential = self.api.getCredential()
693
694         #site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
695         #slice = self.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer)
696
697         ## find out where this slice is currently running
698         #nodelist = self.driver.GetNodes(slice['node_ids'], ['hostname'])
699         #hostnames = [node['hostname'] for node in nodelist]
700
701         ## get netspec details
702         #nodespecs = spec.getDictsByTagName('NodeSpec')
703
704         ## dict in which to store slice attributes to set for the nodes
705         #nodes = {}
706         #for nodespec in nodespecs:
707             #if isinstance(nodespec['name'], list):
708                 #for nodename in nodespec['name']:
709                     #nodes[nodename] = {}
710                     #for k in nodespec.keys():
711                         #rspec_attribute_value = nodespec[k]
712                         #if (self.rspec_to_slice_tag.has_key(k)):
713                             #slice_tag_name = self.rspec_to_slice_tag[k]
714                             #nodes[nodename][slice_tag_name] = rspec_attribute_value
715             #elif isinstance(nodespec['name'], StringTypes):
716                 #nodename = nodespec['name']
717                 #nodes[nodename] = {}
718                 #for k in nodespec.keys():
719                     #rspec_attribute_value = nodespec[k]
720                     #if (self.rspec_to_slice_tag.has_key(k)):
721                         #slice_tag_name = self.rspec_to_slice_tag[k]
722                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
723
724                 #for k in nodespec.keys():
725                     #rspec_attribute_value = nodespec[k]
726                     #if (self.rspec_to_slice_tag.has_key(k)):
727                         #slice_tag_name = self.rspec_to_slice_tag[k]
728                         #nodes[nodename][slice_tag_name] = rspec_attribute_value
729
730         #node_names = nodes.keys()
731         ## remove nodes not in rspec
732         #deleted_nodes = list(set(hostnames).difference(node_names))
733         ## add nodes from rspec
734         #added_nodes = list(set(node_names).difference(hostnames))
735
736         #try:
737             #if peer:
738                 #self.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
739
740             #self.driver.LaunchExperimentOnOAR(slicename, added_nodes) 
741
742             ## Add recognized slice tags
743             #for node_name in node_names:
744                 #node = nodes[node_name]
745                 #for slice_tag in node.keys():
746                     #value = node[slice_tag]
747                     #if (isinstance(value, list)):
748                         #value = value[0]
749
750                     #self.driver.AddSliceTag(slicename, slice_tag, value, node_name)
751
752             #self.driver.DeleteSliceFromNodes(slicename, deleted_nodes)
753         #finally:
754             #if peer:
755                 #self.driver.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
756
757         #return 1
758