4 from sfa.util.faults import MissingSfaInfo, UnknownSfaType, \
5 RecordNotFound, SfaNotImplemented, SliverDoesNotExist
7 from sfa.util.sfalogging import logger
8 from sfa.util.defaultdict import defaultdict
9 from sfa.util.sfatime import utcparse, datetime_to_string, datetime_to_epoch
10 from sfa.util.xrn import hrn_to_urn, get_leaf, urn_to_sliver_id
11 from sfa.util.cache import Cache
13 # one would think the driver should not need to mess with the SFA db, but..
14 from sfa.storage.alchemy import dbsession
15 from sfa.storage.model import RegRecord
17 # used to be used in get_ticket
18 #from sfa.trust.sfaticket import SfaTicket
20 from sfa.rspecs.version_manager import VersionManager
21 from sfa.rspecs.rspec import RSpec
23 # the driver interface, mostly provides default behaviours
24 from sfa.managers.driver import Driver
26 from sfa.nitos.nitosshell import NitosShell
27 from sfa.nitos.nitosaggregate import NitosAggregate
28 from sfa.nitos.nitosslices import NitosSlices
30 from sfa.nitos.nitosxrn import NitosXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_nitos_slicename, xrn_to_hostname
33 def list_to_dict(recs, key):
35 convert a list of dictionaries into a dictionary keyed on the
36 specified dictionary key
38 return dict ( [ (rec[key],rec) for rec in recs ] )
41 # NitosShell is just an xmlrpc serverproxy where methods
42 # can be sent as-is; it takes care of authentication
43 # from the global config
45 class NitosDriver (Driver):
47 # the cache instance is a class member so it survives across incoming requests
50 def __init__ (self, config):
51 Driver.__init__ (self, config)
52 self.shell = NitosShell (config)
54 self.testbedInfo = self.shell.getTestbedInfo()
55 if config.SFA_AGGREGATE_CACHING:
56 if NitosDriver.cache is None:
57 NitosDriver.cache = Cache()
58 self.cache = NitosDriver.cache
60 ########################################
61 ########## registry oriented
62 ########################################
64 def augment_records_with_testbed_info (self, sfa_records):
65 return self.fill_record_info (sfa_records)
68 def register (self, sfa_record, hrn, pub_key):
69 type = sfa_record['type']
70 nitos_record = self.sfa_fields_to_nitos_fields(type, hrn, sfa_record)
72 if type == 'authority':
76 slices = self.shell.getSlices()
79 if slice['slice_name'] == nitos_record['name']:
80 slice_id = slice['slice_id']
84 pointer = self.shell.addSlice({slice_name : nitos_record['name']})
89 users = self.shell.getUsers()
92 if user['user_name'] == nitos_record['name']:
93 user_id = user['user_id']
96 pointer = self.shell.addUser({username : nitos_record['name'], email : nitos_record['email']})
100 # What roles should this user have?
104 self.shell.addUserKey({user_id : pointer,'key' : pub_key})
107 login_base = PlXrn(xrn=sfa_record['authority'],type='node').pl_login_base()
108 nodes = self.shell.GetNodes([pl_record['hostname']])
111 if node['node_name'] == nitos_record['name']:
112 node_id = node['node_id']
116 pointer = self.shell.addNode(nitos_record)
123 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
125 pointer = old_sfa_record['pointer']
126 type = old_sfa_record['type']
128 # new_key implemented for users only
129 if new_key and type not in [ 'user' ]:
130 raise UnknownSfaType(type)
132 if (type == "authority"):
133 #self.shell.UpdateSite(pointer, new_sfa_record)
136 elif type == "slice":
137 nitos_record=self.sfa_fields_to_nitos_fields(type, hrn, new_sfa_record)
138 if 'name' in nitos_record:
139 nitos_record.pop('name')
140 self.shell.updateSlice(pointer, nitos_record)
143 # SMBAKER: UpdatePerson only allows a limited set of fields to be
144 # updated. Ideally we should have a more generic way of doing
145 # this. I copied the field names from UpdatePerson.py...
147 all_fields = new_sfa_record
148 for key in all_fields.keys():
149 if key in ['first_name', 'last_name', 'title', 'email',
150 'password', 'phone', 'url', 'bio', 'accepted_aup',
152 update_fields[key] = all_fields[key]
153 # when updating a user, we always get a 'email' field at this point
154 # this is because 'email' is a native field in the RegUser object...
155 if 'email' in update_fields and not update_fields['email']:
156 del update_fields['email']
157 self.shell.UpdatePerson(pointer, update_fields)
160 # must check this key against the previous one if it exists
161 persons = self.shell.getUsers([pointer], ['key_ids'])
163 keys = person['key_ids']
164 keys = self.shell.GetKeys(person['key_ids'])
166 # Delete all stale keys
169 if new_key != key['key']:
170 self.shell.DeleteKey(key['key_id'])
174 self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
177 self.shell.UpdateNode(pointer, new_sfa_record)
184 def remove (self, sfa_record):
186 type=sfa_record['type']
187 pointer=sfa_record['pointer']
189 persons = self.shell.getUsers(pointer)
190 # only delete this person if he has site ids. if he doesnt, it probably means
191 # he was just removed from a site, not actually deleted
192 if persons and persons[0]['site_ids']:
193 self.shell.DeletePerson(pointer)
194 elif type == 'slice':
195 if self.shell.GetSlices(pointer):
196 self.shell.DeleteSlice(pointer)
198 if self.shell.GetNodes(pointer):
199 self.shell.DeleteNode(pointer)
200 elif type == 'authority':
201 if self.shell.GetSites(pointer):
202 self.shell.DeleteSite(pointer)
212 # Convert SFA fields to NITOS fields for use when registering or updating
213 # registry record in the PLC database
216 def sfa_fields_to_nitos_fields(self, type, hrn, sfa_record):
221 nitos_record["name"] = hrn_to_nitos_slicename(hrn)
223 if not "hostname" in nitos_record:
224 # fetch from sfa_record
225 if "hostname" not in sfa_record:
226 raise MissingSfaInfo("hostname")
227 nitos_record["name"] = sfa_record["hostname"]
228 elif type == "authority":
229 nitos_record["name"] = NitosXrn(xrn=hrn,type='authority').nitos_login_base()
230 if "name" not in sfa_record:
231 nitos_record["name"] = hrn
236 def fill_record_info(self, records):
238 Given a (list of) SFA record, fill in the PLC specific
239 and SFA specific fields in the record.
241 if not isinstance(records, list):
244 self.fill_record_pl_info(records)
245 self.fill_record_hrns(records)
246 self.fill_record_sfa_info(records)
249 def fill_record_pl_info(self, records):
251 Fill in the planetlab specific fields of a SFA record. This
252 involves calling the appropriate PLC method to retrieve the
253 database record for the object.
255 @param record: record to fill in field (in/out param)
259 node_ids, site_ids, slice_ids = [], [], []
260 person_ids, key_ids = [], []
261 type_map = {'node': node_ids, 'authority': site_ids,
262 'slice': slice_ids, 'user': person_ids}
264 for record in records:
265 for type in type_map:
266 if type == record['type']:
267 type_map[type].append(record['pointer'])
270 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
272 node_list = self.shell.GetNodes(node_ids)
273 nodes = list_to_dict(node_list, 'node_id')
275 site_list = self.shell.GetSites(site_ids)
276 sites = list_to_dict(site_list, 'site_id')
278 slice_list = self.shell.GetSlices(slice_ids)
279 slices = list_to_dict(slice_list, 'slice_id')
281 person_list = self.shell.getUsers(person_ids)
282 persons = list_to_dict(person_list, 'person_id')
283 for person in persons:
284 key_ids.extend(persons[person]['key_ids'])
286 pl_records = {'node': nodes, 'authority': sites,
287 'slice': slices, 'user': persons}
290 key_list = self.shell.GetKeys(key_ids)
291 keys = list_to_dict(key_list, 'key_id')
294 for record in records:
295 # records with pointer==-1 do not have plc info.
296 # for example, the top level authority records which are
297 # authorities, but not PL "sites"
298 if record['pointer'] == -1:
301 for type in pl_records:
302 if record['type'] == type:
303 if record['pointer'] in pl_records[type]:
304 record.update(pl_records[type][record['pointer']])
307 if record['type'] == 'user':
308 if 'key_ids' not in record:
309 logger.info("user record has no 'key_ids' - need to import from myplc ?")
311 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
312 record['keys'] = pubkeys
317 def fill_record_hrns(self, records):
319 convert pl ids to hrns
324 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
325 for record in records:
326 if 'site_id' in record:
327 site_ids.append(record['site_id'])
328 if 'site_ids' in record:
329 site_ids.extend(record['site_ids'])
330 if 'person_ids' in record:
331 person_ids.extend(record['person_ids'])
332 if 'slice_ids' in record:
333 slice_ids.extend(record['slice_ids'])
334 if 'node_ids' in record:
335 node_ids.extend(record['node_ids'])
338 slices, persons, sites, nodes = {}, {}, {}, {}
340 site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
341 sites = list_to_dict(site_list, 'site_id')
343 person_list = self.shell.getUsers(person_ids, ['person_id', 'email'])
344 persons = list_to_dict(person_list, 'person_id')
346 slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
347 slices = list_to_dict(slice_list, 'slice_id')
349 node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
350 nodes = list_to_dict(node_list, 'node_id')
352 # convert ids to hrns
353 for record in records:
354 # get all relevant data
355 type = record['type']
356 pointer = record['pointer']
362 if 'site_id' in record:
363 site = sites[record['site_id']]
364 login_base = site['login_base']
365 record['site'] = ".".join([auth_hrn, login_base])
366 if 'person_ids' in record:
367 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
368 if person_id in persons]
369 usernames = [email.split('@')[0] for email in emails]
370 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
371 record['persons'] = person_hrns
372 if 'slice_ids' in record:
373 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
374 if slice_id in slices]
375 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
376 record['slices'] = slice_hrns
377 if 'node_ids' in record:
378 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
380 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
381 record['nodes'] = node_hrns
382 if 'site_ids' in record:
383 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
385 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
386 record['sites'] = site_hrns
388 if 'expires' in record:
389 date = utcparse(record['expires'])
390 datestring = datetime_to_string(date)
391 record['expires'] = datestring
397 def fill_record_sfa_info(self, records):
399 def startswith(prefix, values):
400 return [value for value in values if value.startswith(prefix)]
405 for record in records:
406 person_ids.extend(record.get("person_ids", []))
407 site_ids.extend(record.get("site_ids", []))
408 if 'site_id' in record:
409 site_ids.append(record['site_id'])
411 # get all pis from the sites we've encountered
412 # and store them in a dictionary keyed on site_id
415 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
416 pi_list = self.shell.getUsers(pi_filter, ['person_id', 'site_ids'])
418 # we will need the pi's hrns also
419 person_ids.append(pi['person_id'])
421 # we also need to keep track of the sites these pis
423 for site_id in pi['site_ids']:
424 if site_id in site_pis:
425 site_pis[site_id].append(pi)
427 site_pis[site_id] = [pi]
429 # get sfa records for all records associated with these records.
430 # we'll replace pl ids (person_ids) with hrns from the sfa records
433 # get the registry records
434 person_list, persons = [], {}
435 person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
436 # create a hrns keyed on the sfa record's pointer.
437 # Its possible for multiple records to have the same pointer so
438 # the dict's value will be a list of hrns.
439 persons = defaultdict(list)
440 for person in person_list:
441 persons[person.pointer].append(person)
444 pl_person_list, pl_persons = [], {}
445 pl_person_list = self.shell.getUsers(person_ids, ['person_id', 'roles'])
446 pl_persons = list_to_dict(pl_person_list, 'person_id')
449 for record in records:
450 # skip records with no pl info (top level authorities)
451 #if record['pointer'] == -1:
454 type = record['type']
455 logger.info("fill_record_sfa_info - incoming record typed %s"%type)
456 if (type == "slice"):
457 # all slice users are researchers
458 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
460 record['researcher'] = []
461 for person_id in record.get('person_ids', []):
462 hrns = [person.hrn for person in persons[person_id]]
463 record['researcher'].extend(hrns)
465 # pis at the slice's site
466 if 'site_id' in record and record['site_id'] in site_pis:
467 pl_pis = site_pis[record['site_id']]
468 pi_ids = [pi['person_id'] for pi in pl_pis]
469 for person_id in pi_ids:
470 hrns = [person.hrn for person in persons[person_id]]
471 record['PI'].extend(hrns)
472 record['geni_creator'] = record['PI']
474 elif (type.startswith("authority")):
476 logger.info("fill_record_sfa_info - authority xherex")
477 if record['pointer'] != -1:
479 record['operator'] = []
481 for pointer in record.get('person_ids', []):
482 if pointer not in persons or pointer not in pl_persons:
483 # this means there is not sfa or pl record for this user
485 hrns = [person.hrn for person in persons[pointer]]
486 roles = pl_persons[pointer]['roles']
488 record['PI'].extend(hrns)
490 record['operator'].extend(hrns)
492 record['owner'].extend(hrns)
493 # xxx TODO: OrganizationName
494 elif (type == "node"):
495 sfa_info['dns'] = record.get("hostname", "")
496 # xxx TODO: URI, LatLong, IP, DNS
498 elif (type == "user"):
499 logger.info('setting user.email')
500 sfa_info['email'] = record.get("email", "")
501 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
502 sfa_info['geni_certificate'] = record['gid']
503 # xxx TODO: PostalAddress, Phone
504 record.update(sfa_info)
509 # plcapi works by changes, compute what needs to be added/deleted
510 def update_relation (self, subject_type, target_type, relation_name, subject_id, target_ids):
512 # hard-wire the code for slice/user for now, could be smarter if needed
513 if subject_type =='slice' and target_type == 'user' and relation_name == 'researcher':
514 subject=self.shell.GetSlices (subject_id)[0]
515 current_target_ids = subject['person_ids']
516 add_target_ids = list ( set (target_ids).difference(current_target_ids))
517 del_target_ids = list ( set (current_target_ids).difference(target_ids))
518 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
519 for target_id in add_target_ids:
520 self.shell.AddPersonToSlice (target_id,subject_id)
521 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
522 for target_id in del_target_ids:
523 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
524 self.shell.DeletePersonFromSlice (target_id, subject_id)
525 elif subject_type == 'authority' and target_type == 'user' and relation_name == 'pi':
526 # due to the plcapi limitations this means essentially adding pi role to all people in the list
527 # it's tricky to remove any pi role here, although it might be desirable
528 persons = self.shell.getUsers (target_ids)
529 for person in persons:
530 if 'pi' not in person['roles']:
531 self.shell.AddRoleToPerson('pi',person['person_id'])
533 logger.info('unexpected relation %s to maintain, %s -> %s'%(relation_name,subject_type,target_type))
537 ########################################
538 ########## aggregate oriented
539 ########################################
541 def testbed_name (self): return "nitos"
543 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
544 def aggregate_version (self):
545 version_manager = VersionManager()
546 ad_rspec_versions = []
547 request_rspec_versions = []
548 for rspec_version in version_manager.versions:
549 if rspec_version.content_type in ['*', 'ad']:
550 ad_rspec_versions.append(rspec_version.to_dict())
551 if rspec_version.content_type in ['*', 'request']:
552 request_rspec_versions.append(rspec_version.to_dict())
554 'testbed':self.testbed_name(),
555 'geni_request_rspec_versions': request_rspec_versions,
556 'geni_ad_rspec_versions': ad_rspec_versions,
559 def list_slices (self, creds, options):
560 # look in cache first
562 slices = self.cache.get('slices')
564 logger.debug("NitosDriver.list_slices returns from cache")
568 slices = self.shell.getSlices()
570 #site_name = self.shell.getTestbedInfo()['site_name']
572 slice_hrns = [slicename_to_hrn(self.hrn, site_name, slice['slice_name']) for slice in slices]
573 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
577 logger.debug ("NitosDriver.list_slices stores value in cache")
578 self.cache.add('slices', slice_urns)
582 # first 2 args are None in case of resource discovery
583 def list_resources (self, slice_urn, slice_hrn, creds, options):
584 cached_requested = options.get('cached', True)
585 version_manager = VersionManager()
586 # get the rspec's return format from options
587 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
588 version_string = "rspec_%s" % (rspec_version)
590 #panos adding the info option to the caching key (can be improved)
591 if options.get('info'):
592 version_string = version_string + "_"+options.get('info', 'default')
594 # Adding the list_leases option to the caching key
595 if options.get('list_leases'):
596 version_string = version_string + "_"+options.get('list_leases', 'default')
598 # Adding geni_available to caching key
599 if options.get('geni_available'):
600 version_string = version_string + "_" + str(options.get('geni_available'))
602 # look in cache first
603 if cached_requested and self.cache and not slice_hrn:
604 rspec = self.cache.get(version_string)
606 logger.debug("NitosDriver.ListResources: returning cached advertisement")
609 #panos: passing user-defined options
610 #print "manager options = ",options
611 aggregate = NitosAggregate(self)
612 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
616 if self.cache and not slice_hrn:
617 logger.debug("NitosDriver.ListResources: stores advertisement in cache")
618 self.cache.add(version_string, rspec)
622 def sliver_status (self, slice_urn, slice_hrn):
623 # find out where this slice is currently running
624 slicename = hrn_to_nitos_slicename(slice_hrn)
626 slices = self.shell.getSlices()
629 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
632 if slice['slice_name'] == slicename:
637 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
639 # report about the reserved nodes only
640 reserved_nodes = self.shell.getReservedNodes()
641 nodes = self.shell.getNodes()
643 user_reserved_nodes = []
644 for r_node in reserved_nodes:
645 if r_node['slice_id'] == slice['slice_id']:
647 if node['id'] == r_node['node_id']:
648 user_reserved_nodes.append(node)
653 if len(user_reserved_nodes) == 0:
654 raise SliverDoesNotExist("You have not allocated any slivers here")
656 ##### continue from here
659 if slice['person_ids']:
660 persons = self.shell.GetPersons(slice['person_ids'], ['key_ids'])
661 key_ids = [key_id for person in persons for key_id in person['key_ids']]
662 person_keys = self.shell.GetKeys(key_ids)
663 keys = [key['key'] for key in person_keys]
665 user.update({'urn': slice_urn,
666 'login': slice['name'],
671 site_ids = [node['site_id'] for node in nodes]
674 top_level_status = 'unknown'
676 top_level_status = 'ready'
677 result['geni_urn'] = slice_urn
678 result['pl_login'] = slice['name']
679 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
680 result['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
685 res['pl_hostname'] = node['hostname']
686 res['pl_boot_state'] = node['boot_state']
687 res['pl_last_contact'] = node['last_contact']
688 res['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
689 if node['last_contact'] is not None:
691 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
692 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'], authority=self.hrn)
693 res['geni_urn'] = sliver_id
694 if node['boot_state'] == 'boot':
695 res['geni_status'] = 'ready'
697 res['geni_status'] = 'failed'
698 top_level_status = 'failed'
700 res['geni_error'] = ''
701 res['users'] = [user]
703 resources.append(res)
705 result['geni_status'] = top_level_status
706 result['geni_resources'] = resources
710 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
712 aggregate = NitosAggregate(self)
713 slices = NitosSlices(self)
714 peer = slices.get_peer(slice_hrn)
715 sfa_peer = slices.get_sfa_peer(slice_hrn)
718 slice_record = users[0].get('slice_record', {})
721 rspec = RSpec(rspec_string)
722 requested_attributes = rspec.version.get_slice_attributes()
724 # ensure site record exists
725 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
726 # ensure slice record exists
727 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
728 # ensure person records exists
729 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
730 # ensure slice attributes exists
731 slices.verify_slice_attributes(slice, requested_attributes, options=options)
733 # add/remove slice from nodes
734 requested_slivers = []
735 for node in rspec.version.get_nodes_with_slivers():
737 if node.get('component_name'):
738 hostname = node.get('component_name').strip()
739 elif node.get('component_id'):
740 hostname = xrn_to_hostname(node.get('component_id').strip())
742 requested_slivers.append(hostname)
743 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
745 # add/remove links links
746 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
749 requested_leases = []
751 for lease in rspec.version.get_leases():
753 if not lease.get('lease_id'):
754 requested_lease['hostname'] = xrn_to_hostname(lease.get('component_id').strip())
755 requested_lease['start_time'] = lease.get('start_time')
756 requested_lease['duration'] = lease.get('duration')
758 kept_leases.append(int(lease['lease_id']))
759 if requested_lease.get('hostname'):
760 requested_leases.append(requested_lease)
762 leases = slices.verify_slice_leases(slice, requested_leases, kept_leases, peer)
764 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
766 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
767 slicename = hrn_to_nitos_slicename(slice_hrn)
768 slices = self.shell.GetSlices({'name': slicename})
773 # determine if this is a peer slice
774 # xxx I wonder if this would not need to use PlSlices.get_peer instead
775 # in which case plc.peers could be deprecated as this here
776 # is the only/last call to this last method in plc.peers
777 peer = peers.get_peer(self, slice_hrn)
780 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
781 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
784 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
787 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
788 slicename = hrn_to_nitos_slicename(slice_hrn)
789 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
791 raise RecordNotFound(slice_hrn)
793 requested_time = utcparse(expiration_time)
794 record = {'expires': int(datetime_to_epoch(requested_time))}
796 self.shell.UpdateSlice(slice['slice_id'], record)
802 # xxx this code is quite old and has not run for ages
803 # it is obviously totally broken and needs a rewrite
804 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
805 raise SfaNotImplemented,"NitosDriver.get_ticket needs a rewrite"
806 # please keep this code for future reference
807 # slices = PlSlices(self)
808 # peer = slices.get_peer(slice_hrn)
809 # sfa_peer = slices.get_sfa_peer(slice_hrn)
811 # # get the slice record
812 # credential = api.getCredential()
813 # interface = api.registries[api.hrn]
814 # registry = api.server_proxy(interface, credential)
815 # records = registry.Resolve(xrn, credential)
817 # # make sure we get a local slice record
819 # for tmp_record in records:
820 # if tmp_record['type'] == 'slice' and \
821 # not tmp_record['peer_authority']:
822 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
823 # slice_record = SliceRecord(dict=tmp_record)
825 # raise RecordNotFound(slice_hrn)
827 # # similar to CreateSliver, we must verify that the required records exist
828 # # at this aggregate before we can issue a ticket
830 # rspec = RSpec(rspec_string)
831 # requested_attributes = rspec.version.get_slice_attributes()
833 # # ensure site record exists
834 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
835 # # ensure slice record exists
836 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
837 # # ensure person records exists
838 # # xxx users is undefined in this context
839 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
840 # # ensure slice attributes exists
841 # slices.verify_slice_attributes(slice, requested_attributes)
844 # slivers = slices.get_slivers(slice_hrn)
847 # raise SliverDoesNotExist(slice_hrn)
852 # 'timestamp': int(time.time()),
853 # 'initscripts': initscripts,
857 # # create the ticket
858 # object_gid = record.get_gid_object()
859 # new_ticket = SfaTicket(subject = object_gid.get_subject())
860 # new_ticket.set_gid_caller(api.auth.client_gid)
861 # new_ticket.set_gid_object(object_gid)
862 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
863 # new_ticket.set_pubkey(object_gid.get_pubkey())
864 # new_ticket.set_attributes(data)
865 # new_ticket.set_rspec(rspec)
866 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
867 # new_ticket.encode()
870 # return new_ticket.save_to_string(save_parents=True)