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
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.table import SfaTable
16 # used to be used in get_ticket
17 #from sfa.trust.sfaticket import SfaTicket
19 from sfa.rspecs.version_manager import VersionManager
20 from sfa.rspecs.rspec import RSpec
22 # the driver interface, mostly provides default behaviours
23 from sfa.managers.driver import Driver
25 from sfa.plc.plshell import PlShell
26 import sfa.plc.peers as peers
27 from sfa.plc.plaggregate import PlAggregate
28 from sfa.plc.plslices import PlSlices
29 from sfa.util.plxrn import slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, hrn_to_pl_login_base
32 def list_to_dict(recs, key):
34 convert a list of dictionaries into a dictionary keyed on the
35 specified dictionary key
37 return dict ( [ (rec[key],rec) for rec in recs ] )
40 # PlShell is just an xmlrpc serverproxy where methods
41 # can be sent as-is; it takes care of authentication
42 # from the global config
44 # so we inherit PlShell just so one can do driver.GetNodes
45 # which would not make much sense in the context of other testbeds
46 # so ultimately PlDriver should drop the PlShell inheritance
47 # and would have a driver.shell reference to a PlShell instead
49 class PlDriver (Driver, PlShell):
51 # the cache instance is a class member so it survives across incoming requests
54 def __init__ (self, config):
55 PlShell.__init__ (self, config)
56 Driver.__init__ (self, config)
58 if config.SFA_AGGREGATE_CACHING:
59 if PlDriver.cache is None:
60 PlDriver.cache = Cache()
61 self.cache = PlDriver.cache
63 ########################################
64 ########## registry oriented
65 ########################################
67 ########## disabled users
68 def is_enabled (self, record):
69 # the incoming record was augmented already, so 'enabled' should be set
70 if record['type'] == 'user':
71 return record['enabled']
72 # only users can be disabled
75 def augment_records_with_testbed_info (self, sfa_records):
76 return self.fill_record_info (sfa_records)
79 def register (self, sfa_record, hrn, pub_key):
80 type = sfa_record['type']
81 pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record)
83 if type == 'authority':
84 sites = self.GetSites([pl_record['login_base']])
86 pointer = self.AddSite(pl_record)
88 pointer = sites[0]['site_id']
91 acceptable_fields=['url', 'instantiation', 'name', 'description']
92 for key in pl_record.keys():
93 if key not in acceptable_fields:
95 slices = self.GetSlices([pl_record['name']])
97 pointer = self.AddSlice(pl_record)
99 pointer = slices[0]['slice_id']
102 persons = self.GetPersons([sfa_record['email']])
104 pointer = self.AddPerson(dict(sfa_record))
106 pointer = persons[0]['person_id']
108 if 'enabled' in sfa_record and sfa_record['enabled']:
109 self.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
110 # add this person to the site only if she is being added for the first
111 # time by sfa and doesont already exist in plc
112 if not persons or not persons[0]['site_ids']:
113 login_base = get_leaf(sfa_record['authority'])
114 self.AddPersonToSite(pointer, login_base)
116 # What roles should this user have?
117 self.AddRoleToPerson('user', pointer)
120 self.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
123 login_base = hrn_to_pl_login_base(sfa_record['authority'])
124 nodes = self.GetNodes([pl_record['hostname']])
126 pointer = self.AddNode(login_base, pl_record)
128 pointer = nodes[0]['node_id']
133 # xxx actually old_sfa_record comes filled with plc stuff as well in the original code
134 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
135 pointer = old_sfa_record['pointer']
136 type = old_sfa_record['type']
138 # new_key implemented for users only
139 if new_key and type not in [ 'user' ]:
140 raise UnknownSfaType(type)
142 if (type == "authority"):
143 self.UpdateSite(pointer, new_sfa_record)
145 elif type == "slice":
146 pl_record=self.sfa_fields_to_pl_fields(type, hrn, new_sfa_record)
147 if 'name' in pl_record:
148 pl_record.pop('name')
149 self.UpdateSlice(pointer, pl_record)
152 # SMBAKER: UpdatePerson only allows a limited set of fields to be
153 # updated. Ideally we should have a more generic way of doing
154 # this. I copied the field names from UpdatePerson.py...
156 all_fields = new_sfa_record
157 for key in all_fields.keys():
158 if key in ['first_name', 'last_name', 'title', 'email',
159 'password', 'phone', 'url', 'bio', 'accepted_aup',
161 update_fields[key] = all_fields[key]
162 self.UpdatePerson(pointer, update_fields)
165 # must check this key against the previous one if it exists
166 persons = self.GetPersons([pointer], ['key_ids'])
168 keys = person['key_ids']
169 keys = self.GetKeys(person['key_ids'])
171 # Delete all stale keys
174 if new_key != key['key']:
175 self.DeleteKey(key['key_id'])
179 self.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
182 self.UpdateNode(pointer, new_sfa_record)
188 def remove (self, sfa_record):
189 type=sfa_record['type']
190 pointer=sfa_record['pointer']
192 persons = self.GetPersons(pointer)
193 # only delete this person if he has site ids. if he doesnt, it probably means
194 # he was just removed from a site, not actually deleted
195 if persons and persons[0]['site_ids']:
196 self.DeletePerson(pointer)
197 elif type == 'slice':
198 if self.GetSlices(pointer):
199 self.DeleteSlice(pointer)
201 if self.GetNodes(pointer):
202 self.DeleteNode(pointer)
203 elif type == 'authority':
204 if self.GetSites(pointer):
205 self.DeleteSite(pointer)
214 # Convert SFA fields to PLC fields for use when registering up updating
215 # registry record in the PLC database
218 def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
223 pl_record["name"] = hrn_to_pl_slicename(hrn)
224 if "instantiation" in sfa_record:
225 pl_record['instantiation']=sfa_record['instantiation']
227 pl_record["instantiation"] = "plc-instantiated"
228 if "url" in sfa_record:
229 pl_record["url"] = sfa_record["url"]
230 if "description" in sfa_record:
231 pl_record["description"] = sfa_record["description"]
232 if "expires" in sfa_record:
233 pl_record["expires"] = int(sfa_record["expires"])
236 if not "hostname" in pl_record:
237 # fetch from sfa_record
238 if "hostname" not in sfa_record:
239 raise MissingSfaInfo("hostname")
240 pl_record["hostname"] = sfa_record["hostname"]
241 if "model" in sfa_record:
242 pl_record["model"] = sfa_record["model"]
244 pl_record["model"] = "geni"
246 elif type == "authority":
247 pl_record["login_base"] = hrn_to_pl_login_base(hrn)
248 if "name" not in sfa_record:
249 pl_record["name"] = hrn
250 if "abbreviated_name" not in sfa_record:
251 pl_record["abbreviated_name"] = hrn
252 if "enabled" not in sfa_record:
253 pl_record["enabled"] = True
254 if "is_public" not in sfa_record:
255 pl_record["is_public"] = True
260 def fill_record_info(self, records):
262 Given a (list of) SFA record, fill in the PLC specific
263 and SFA specific fields in the record.
265 if not isinstance(records, list):
268 self.fill_record_pl_info(records)
269 self.fill_record_hrns(records)
270 self.fill_record_sfa_info(records)
273 def fill_record_pl_info(self, records):
275 Fill in the planetlab specific fields of a SFA record. This
276 involves calling the appropriate PLC method to retrieve the
277 database record for the object.
279 @param record: record to fill in field (in/out param)
282 node_ids, site_ids, slice_ids = [], [], []
283 person_ids, key_ids = [], []
284 type_map = {'node': node_ids, 'authority': site_ids,
285 'slice': slice_ids, 'user': person_ids}
287 for record in records:
288 for type in type_map:
289 if type == record['type']:
290 type_map[type].append(record['pointer'])
293 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
295 node_list = self.GetNodes(node_ids)
296 nodes = list_to_dict(node_list, 'node_id')
298 site_list = self.GetSites(site_ids)
299 sites = list_to_dict(site_list, 'site_id')
301 slice_list = self.GetSlices(slice_ids)
302 slices = list_to_dict(slice_list, 'slice_id')
304 person_list = self.GetPersons(person_ids)
305 persons = list_to_dict(person_list, 'person_id')
306 for person in persons:
307 key_ids.extend(persons[person]['key_ids'])
309 pl_records = {'node': nodes, 'authority': sites,
310 'slice': slices, 'user': persons}
313 key_list = self.GetKeys(key_ids)
314 keys = list_to_dict(key_list, 'key_id')
317 for record in records:
318 # records with pointer==-1 do not have plc info.
319 # for example, the top level authority records which are
320 # authorities, but not PL "sites"
321 if record['pointer'] == -1:
324 for type in pl_records:
325 if record['type'] == type:
326 if record['pointer'] in pl_records[type]:
327 record.update(pl_records[type][record['pointer']])
330 if record['type'] == 'user':
331 if 'key_ids' not in record:
332 logger.info("user record has no 'key_ids' - need to import from myplc ?")
334 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
335 record['keys'] = pubkeys
339 def fill_record_hrns(self, records):
341 convert pl ids to hrns
345 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
346 for record in records:
347 if 'site_id' in record:
348 site_ids.append(record['site_id'])
349 if 'site_ids' in record:
350 site_ids.extend(record['site_ids'])
351 if 'person_ids' in record:
352 person_ids.extend(record['person_ids'])
353 if 'slice_ids' in record:
354 slice_ids.extend(record['slice_ids'])
355 if 'node_ids' in record:
356 node_ids.extend(record['node_ids'])
359 slices, persons, sites, nodes = {}, {}, {}, {}
361 site_list = self.GetSites(site_ids, ['site_id', 'login_base'])
362 sites = list_to_dict(site_list, 'site_id')
364 person_list = self.GetPersons(person_ids, ['person_id', 'email'])
365 persons = list_to_dict(person_list, 'person_id')
367 slice_list = self.GetSlices(slice_ids, ['slice_id', 'name'])
368 slices = list_to_dict(slice_list, 'slice_id')
370 node_list = self.GetNodes(node_ids, ['node_id', 'hostname'])
371 nodes = list_to_dict(node_list, 'node_id')
373 # convert ids to hrns
374 for record in records:
375 # get all relevant data
376 type = record['type']
377 pointer = record['pointer']
383 if 'site_id' in record:
384 site = sites[record['site_id']]
385 login_base = site['login_base']
386 record['site'] = ".".join([auth_hrn, login_base])
387 if 'person_ids' in record:
388 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
389 if person_id in persons]
390 usernames = [email.split('@')[0] for email in emails]
391 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
392 record['persons'] = person_hrns
393 if 'slice_ids' in record:
394 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
395 if slice_id in slices]
396 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
397 record['slices'] = slice_hrns
398 if 'node_ids' in record:
399 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
401 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
402 record['nodes'] = node_hrns
403 if 'site_ids' in record:
404 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
406 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
407 record['sites'] = site_hrns
411 def fill_record_sfa_info(self, records):
413 def startswith(prefix, values):
414 return [value for value in values if value.startswith(prefix)]
419 for record in records:
420 person_ids.extend(record.get("person_ids", []))
421 site_ids.extend(record.get("site_ids", []))
422 if 'site_id' in record:
423 site_ids.append(record['site_id'])
425 # get all pis from the sites we've encountered
426 # and store them in a dictionary keyed on site_id
429 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
430 pi_list = self.GetPersons(pi_filter, ['person_id', 'site_ids'])
432 # we will need the pi's hrns also
433 person_ids.append(pi['person_id'])
435 # we also need to keep track of the sites these pis
437 for site_id in pi['site_ids']:
438 if site_id in site_pis:
439 site_pis[site_id].append(pi)
441 site_pis[site_id] = [pi]
443 # get sfa records for all records associated with these records.
444 # we'll replace pl ids (person_ids) with hrns from the sfa records
447 # get the sfa records
449 person_list, persons = [], {}
450 person_list = table.find({'type': 'user', 'pointer': person_ids})
451 # create a hrns keyed on the sfa record's pointer.
452 # Its possible for multiple records to have the same pointer so
453 # the dict's value will be a list of hrns.
454 persons = defaultdict(list)
455 for person in person_list:
456 persons[person['pointer']].append(person)
459 pl_person_list, pl_persons = [], {}
460 pl_person_list = self.GetPersons(person_ids, ['person_id', 'roles'])
461 pl_persons = list_to_dict(pl_person_list, 'person_id')
464 for record in records:
465 # skip records with no pl info (top level authorities)
466 #if record['pointer'] == -1:
469 type = record['type']
470 if (type == "slice"):
471 # all slice users are researchers
472 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
474 record['researcher'] = []
475 for person_id in record.get('person_ids', []):
476 hrns = [person['hrn'] for person in persons[person_id]]
477 record['researcher'].extend(hrns)
479 # pis at the slice's site
480 if 'site_id' in record and record['site_id'] in site_pis:
481 pl_pis = site_pis[record['site_id']]
482 pi_ids = [pi['person_id'] for pi in pl_pis]
483 for person_id in pi_ids:
484 hrns = [person['hrn'] for person in persons[person_id]]
485 record['PI'].extend(hrns)
486 record['geni_creator'] = record['PI']
488 elif (type.startswith("authority")):
490 if record['pointer'] != -1:
492 record['operator'] = []
494 for pointer in record.get('person_ids', []):
495 if pointer not in persons or pointer not in pl_persons:
496 # this means there is not sfa or pl record for this user
498 hrns = [person['hrn'] for person in persons[pointer]]
499 roles = pl_persons[pointer]['roles']
501 record['PI'].extend(hrns)
503 record['operator'].extend(hrns)
505 record['owner'].extend(hrns)
506 # xxx TODO: OrganizationName
507 elif (type == "node"):
508 sfa_info['dns'] = record.get("hostname", "")
509 # xxx TODO: URI, LatLong, IP, DNS
511 elif (type == "user"):
512 sfa_info['email'] = record.get("email", "")
513 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
514 sfa_info['geni_certificate'] = record['gid']
515 # xxx TODO: PostalAddress, Phone
516 record.update(sfa_info)
520 # plcapi works by changes, compute what needs to be added/deleted
521 def update_relation (self, subject_type, target_type, subject_id, target_ids):
522 # hard-wire the code for slice/user for now, could be smarter if needed
523 if subject_type =='slice' and target_type == 'user':
524 subject=self.GetSlices (subject_id)[0]
525 current_target_ids = subject['person_ids']
526 add_target_ids = list ( set (target_ids).difference(current_target_ids))
527 del_target_ids = list ( set (current_target_ids).difference(target_ids))
528 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
529 for target_id in add_target_ids:
530 self.AddPersonToSlice (target_id,subject_id)
531 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
532 for target_id in del_target_ids:
533 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
534 self.DeletePersonFromSlice (target_id, subject_id)
536 logger.info('unexpected relation to maintain, %s -> %s'%(subject_type,target_type))
539 ########################################
540 ########## aggregate oriented
541 ########################################
543 def testbed_name (self): return "myplc"
545 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
546 def aggregate_version (self):
547 version_manager = VersionManager()
548 ad_rspec_versions = []
549 request_rspec_versions = []
550 for rspec_version in version_manager.versions:
551 if rspec_version.content_type in ['*', 'ad']:
552 ad_rspec_versions.append(rspec_version.to_dict())
553 if rspec_version.content_type in ['*', 'request']:
554 request_rspec_versions.append(rspec_version.to_dict())
556 'testbed':self.testbed_name(),
557 'geni_request_rspec_versions': request_rspec_versions,
558 'geni_ad_rspec_versions': ad_rspec_versions,
561 def list_slices (self, creds, options):
562 # look in cache first
564 slices = self.cache.get('slices')
566 logger.debug("PlDriver.list_slices returns from cache")
570 slices = self.GetSlices({'peer_id': None}, ['name'])
571 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
572 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
576 logger.debug ("PlDriver.list_slices stores value in cache")
577 self.cache.add('slices', slice_urns)
581 # first 2 args are None in case of resource discovery
582 def list_resources (self, slice_urn, slice_hrn, creds, options):
583 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 # look in cache first
595 if cached_requested and self.cache and not slice_hrn:
596 rspec = self.cache.get(version_string)
598 logger.debug("PlDriver.ListResources: returning cached advertisement")
601 #panos: passing user-defined options
602 #print "manager options = ",options
603 aggregate = PlAggregate(self)
604 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
608 if self.cache and not slice_hrn:
609 logger.debug("PlDriver.ListResources: stores advertisement in cache")
610 self.cache.add(version_string, rspec)
614 def sliver_status (self, slice_urn, slice_hrn):
615 # find out where this slice is currently running
616 slicename = hrn_to_pl_slicename(slice_hrn)
618 slices = self.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
620 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
623 # report about the local nodes only
624 nodes = self.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
625 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
626 site_ids = [node['site_id'] for node in nodes]
629 top_level_status = 'unknown'
631 top_level_status = 'ready'
632 result['geni_urn'] = slice_urn
633 result['pl_login'] = slice['name']
634 result['pl_expires'] = datetime.datetime.fromtimestamp(slice['expires']).ctime()
639 res['pl_hostname'] = node['hostname']
640 res['pl_boot_state'] = node['boot_state']
641 res['pl_last_contact'] = node['last_contact']
642 if node['last_contact'] is not None:
643 res['pl_last_contact'] = datetime.datetime.fromtimestamp(node['last_contact']).ctime()
644 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'])
645 res['geni_urn'] = sliver_id
646 if node['boot_state'] == 'boot':
647 res['geni_status'] = 'ready'
649 res['geni_status'] = 'failed'
650 top_level_status = 'failed'
652 res['geni_error'] = ''
654 resources.append(res)
656 result['geni_status'] = top_level_status
657 result['geni_resources'] = resources
660 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
662 aggregate = PlAggregate(self)
663 slices = PlSlices(self)
664 peer = slices.get_peer(slice_hrn)
665 sfa_peer = slices.get_sfa_peer(slice_hrn)
668 slice_record = users[0].get('slice_record', {})
671 rspec = RSpec(rspec_string)
672 requested_attributes = rspec.version.get_slice_attributes()
674 # ensure site record exists
675 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
676 # ensure slice record exists
677 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
678 # ensure person records exists
679 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
680 # ensure slice attributes exists
681 slices.verify_slice_attributes(slice, requested_attributes, options=options)
683 # add/remove slice from nodes
684 requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
685 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
687 # add/remove links links
688 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
690 # handle MyPLC peer association.
691 # only used by plc and ple.
692 slices.handle_peer(site, slice, persons, peer)
694 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
696 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
697 slicename = hrn_to_pl_slicename(slice_hrn)
698 slices = self.GetSlices({'name': slicename})
703 # determine if this is a peer slice
704 # xxx I wonder if this would not need to use PlSlices.get_peer instead
705 # in which case plc.peers could be deprecated as this here
706 # is the only/last call to this last method in plc.peers
707 peer = peers.get_peer(self, slice_hrn)
710 self.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
711 self.DeleteSliceFromNodes(slicename, slice['node_ids'])
714 self.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
717 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
718 slicename = hrn_to_pl_slicename(slice_hrn)
719 slices = self.GetSlices({'name': slicename}, ['slice_id'])
721 raise RecordNotFound(slice_hrn)
723 requested_time = utcparse(expiration_time)
724 record = {'expires': int(time.mktime(requested_time.timetuple()))}
726 self.UpdateSlice(slice['slice_id'], record)
731 # remove the 'enabled' tag
732 def start_slice (self, slice_urn, slice_hrn, creds):
733 slicename = hrn_to_pl_slicename(slice_hrn)
734 slices = self.GetSlices({'name': slicename}, ['slice_id'])
736 raise RecordNotFound(slice_hrn)
737 slice_id = slices[0]['slice_id']
738 slice_tags = self.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
739 # just remove the tag if it exists
741 self.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
744 # set the 'enabled' tag to 0
745 def stop_slice (self, slice_urn, slice_hrn, creds):
746 slicename = hrn_to_pl_slicename(slice_hrn)
747 slices = self.GetSlices({'name': slicename}, ['slice_id'])
749 raise RecordNotFound(slice_hrn)
750 slice_id = slices[0]['slice_id']
751 slice_tags = self.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
753 self.AddSliceTag(slice_id, 'enabled', '0')
754 elif slice_tags[0]['value'] != "0":
755 tag_id = slice_tags[0]['slice_tag_id']
756 self.UpdateSliceTag(tag_id, '0')
759 def reset_slice (self, slice_urn, slice_hrn, creds):
760 raise SfaNotImplemented ("reset_slice not available at this interface")
762 # xxx this code is quite old and has not run for ages
763 # it is obviously totally broken and needs a rewrite
764 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
765 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
766 # please keep this code for future reference
767 # slices = PlSlices(self)
768 # peer = slices.get_peer(slice_hrn)
769 # sfa_peer = slices.get_sfa_peer(slice_hrn)
771 # # get the slice record
772 # credential = api.getCredential()
773 # interface = api.registries[api.hrn]
774 # registry = api.server_proxy(interface, credential)
775 # records = registry.Resolve(xrn, credential)
777 # # make sure we get a local slice record
779 # for tmp_record in records:
780 # if tmp_record['type'] == 'slice' and \
781 # not tmp_record['peer_authority']:
782 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
783 # slice_record = SliceRecord(dict=tmp_record)
785 # raise RecordNotFound(slice_hrn)
787 # # similar to CreateSliver, we must verify that the required records exist
788 # # at this aggregate before we can issue a ticket
790 # rspec = RSpec(rspec_string)
791 # requested_attributes = rspec.version.get_slice_attributes()
793 # # ensure site record exists
794 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
795 # # ensure slice record exists
796 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
797 # # ensure person records exists
798 # # xxx users is undefined in this context
799 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
800 # # ensure slice attributes exists
801 # slices.verify_slice_attributes(slice, requested_attributes)
804 # slivers = slices.get_slivers(slice_hrn)
807 # raise SliverDoesNotExist(slice_hrn)
812 # 'timestamp': int(time.time()),
813 # 'initscripts': initscripts,
817 # # create the ticket
818 # object_gid = record.get_gid_object()
819 # new_ticket = SfaTicket(subject = object_gid.get_subject())
820 # new_ticket.set_gid_caller(api.auth.client_gid)
821 # new_ticket.set_gid_object(object_gid)
822 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
823 # new_ticket.set_pubkey(object_gid.get_pubkey())
824 # new_ticket.set_attributes(data)
825 # new_ticket.set_rspec(rspec)
826 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
827 # new_ticket.encode()
830 # return new_ticket.save_to_string(save_parents=True)