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.plc.plshell import PlShell
27 import sfa.plc.peers as peers
28 from sfa.plc.plaggregate import PlAggregate
29 from sfa.plc.plslices import PlSlices
30 from sfa.util.plxrn import slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename, hrn_to_pl_login_base
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 # PlShell 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 PlDriver (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 = PlShell (config)
54 if config.SFA_AGGREGATE_CACHING:
55 if PlDriver.cache is None:
56 PlDriver.cache = Cache()
57 self.cache = PlDriver.cache
59 ########################################
60 ########## registry oriented
61 ########################################
63 ########## disabled users
64 def is_enabled (self, record):
65 # the incoming record was augmented already, so 'enabled' should be set
66 if record['type'] == 'user':
67 return record['enabled']
68 # only users can be disabled
71 def augment_records_with_testbed_info (self, sfa_records):
72 return self.fill_record_info (sfa_records)
75 def register (self, sfa_record, hrn, pub_key):
76 type = sfa_record['type']
77 pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record)
79 if type == 'authority':
80 sites = self.shell.GetSites([pl_record['login_base']])
82 pointer = self.shell.AddSite(pl_record)
84 pointer = sites[0]['site_id']
87 acceptable_fields=['url', 'instantiation', 'name', 'description']
88 for key in pl_record.keys():
89 if key not in acceptable_fields:
91 slices = self.shell.GetSlices([pl_record['name']])
93 pointer = self.shell.AddSlice(pl_record)
95 pointer = slices[0]['slice_id']
98 persons = self.shell.GetPersons([sfa_record['email']])
100 pointer = self.shell.AddPerson(dict(sfa_record))
102 pointer = persons[0]['person_id']
104 if 'enabled' in sfa_record and sfa_record['enabled']:
105 self.shell.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
106 # add this person to the site only if she is being added for the first
107 # time by sfa and doesont already exist in plc
108 if not persons or not persons[0]['site_ids']:
109 login_base = get_leaf(sfa_record['authority'])
110 self.shell.AddPersonToSite(pointer, login_base)
112 # What roles should this user have?
113 self.shell.AddRoleToPerson('user', pointer)
116 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
119 login_base = hrn_to_pl_login_base(sfa_record['authority'])
120 nodes = self.shell.GetNodes([pl_record['hostname']])
122 pointer = self.shell.AddNode(login_base, pl_record)
124 pointer = nodes[0]['node_id']
129 # xxx actually old_sfa_record comes filled with plc stuff as well in the original code
130 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
131 pointer = old_sfa_record['pointer']
132 type = old_sfa_record['type']
134 # new_key implemented for users only
135 if new_key and type not in [ 'user' ]:
136 raise UnknownSfaType(type)
138 if (type == "authority"):
139 self.shell.UpdateSite(pointer, new_sfa_record)
141 elif type == "slice":
142 pl_record=self.sfa_fields_to_pl_fields(type, hrn, new_sfa_record)
143 if 'name' in pl_record:
144 pl_record.pop('name')
145 self.shell.UpdateSlice(pointer, pl_record)
148 # SMBAKER: UpdatePerson only allows a limited set of fields to be
149 # updated. Ideally we should have a more generic way of doing
150 # this. I copied the field names from UpdatePerson.py...
152 all_fields = new_sfa_record
153 for key in all_fields.keys():
154 if key in ['first_name', 'last_name', 'title', 'email',
155 'password', 'phone', 'url', 'bio', 'accepted_aup',
157 update_fields[key] = all_fields[key]
158 self.shell.UpdatePerson(pointer, update_fields)
161 # must check this key against the previous one if it exists
162 persons = self.shell.GetPersons([pointer], ['key_ids'])
164 keys = person['key_ids']
165 keys = self.shell.GetKeys(person['key_ids'])
167 # Delete all stale keys
170 if new_key != key['key']:
171 self.shell.DeleteKey(key['key_id'])
175 self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
178 self.shell.UpdateNode(pointer, new_sfa_record)
184 def remove (self, sfa_record):
185 type=sfa_record['type']
186 pointer=sfa_record['pointer']
188 persons = self.shell.GetPersons(pointer)
189 # only delete this person if he has site ids. if he doesnt, it probably means
190 # he was just removed from a site, not actually deleted
191 if persons and persons[0]['site_ids']:
192 self.shell.DeletePerson(pointer)
193 elif type == 'slice':
194 if self.shell.GetSlices(pointer):
195 self.shell.DeleteSlice(pointer)
197 if self.shell.GetNodes(pointer):
198 self.shell.DeleteNode(pointer)
199 elif type == 'authority':
200 if self.shell.GetSites(pointer):
201 self.shell.DeleteSite(pointer)
210 # Convert SFA fields to PLC fields for use when registering or updating
211 # registry record in the PLC database
214 def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
219 pl_record["name"] = hrn_to_pl_slicename(hrn)
220 if "instantiation" in sfa_record:
221 pl_record['instantiation']=sfa_record['instantiation']
223 pl_record["instantiation"] = "plc-instantiated"
224 if "url" in sfa_record:
225 pl_record["url"] = sfa_record["url"]
226 if "description" in sfa_record:
227 pl_record["description"] = sfa_record["description"]
228 if "expires" in sfa_record:
229 date = utcparse(sfa_record['expires'])
230 expires = datetime_to_epoch(date)
231 pl_record["expires"] = expires
234 if not "hostname" in pl_record:
235 # fetch from sfa_record
236 if "hostname" not in sfa_record:
237 raise MissingSfaInfo("hostname")
238 pl_record["hostname"] = sfa_record["hostname"]
239 if "model" in sfa_record:
240 pl_record["model"] = sfa_record["model"]
242 pl_record["model"] = "geni"
244 elif type == "authority":
245 pl_record["login_base"] = hrn_to_pl_login_base(hrn)
246 if "name" not in sfa_record:
247 pl_record["name"] = hrn
248 if "abbreviated_name" not in sfa_record:
249 pl_record["abbreviated_name"] = hrn
250 if "enabled" not in sfa_record:
251 pl_record["enabled"] = True
252 if "is_public" not in sfa_record:
253 pl_record["is_public"] = True
258 def fill_record_info(self, records):
260 Given a (list of) SFA record, fill in the PLC specific
261 and SFA specific fields in the record.
263 if not isinstance(records, list):
266 self.fill_record_pl_info(records)
267 self.fill_record_hrns(records)
268 self.fill_record_sfa_info(records)
271 def fill_record_pl_info(self, records):
273 Fill in the planetlab specific fields of a SFA record. This
274 involves calling the appropriate PLC method to retrieve the
275 database record for the object.
277 @param record: record to fill in field (in/out param)
280 node_ids, site_ids, slice_ids = [], [], []
281 person_ids, key_ids = [], []
282 type_map = {'node': node_ids, 'authority': site_ids,
283 'slice': slice_ids, 'user': person_ids}
285 for record in records:
286 for type in type_map:
287 if type == record['type']:
288 type_map[type].append(record['pointer'])
291 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
293 node_list = self.shell.GetNodes(node_ids)
294 nodes = list_to_dict(node_list, 'node_id')
296 site_list = self.shell.GetSites(site_ids)
297 sites = list_to_dict(site_list, 'site_id')
299 slice_list = self.shell.GetSlices(slice_ids)
300 slices = list_to_dict(slice_list, 'slice_id')
302 person_list = self.shell.GetPersons(person_ids)
303 persons = list_to_dict(person_list, 'person_id')
304 for person in persons:
305 key_ids.extend(persons[person]['key_ids'])
307 pl_records = {'node': nodes, 'authority': sites,
308 'slice': slices, 'user': persons}
311 key_list = self.shell.GetKeys(key_ids)
312 keys = list_to_dict(key_list, 'key_id')
315 for record in records:
316 # records with pointer==-1 do not have plc info.
317 # for example, the top level authority records which are
318 # authorities, but not PL "sites"
319 if record['pointer'] == -1:
322 for type in pl_records:
323 if record['type'] == type:
324 if record['pointer'] in pl_records[type]:
325 record.update(pl_records[type][record['pointer']])
328 if record['type'] == 'user':
329 if 'key_ids' not in record:
330 logger.info("user record has no 'key_ids' - need to import from myplc ?")
332 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
333 record['keys'] = pubkeys
337 def fill_record_hrns(self, records):
339 convert pl ids to hrns
343 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
344 for record in records:
345 if 'site_id' in record:
346 site_ids.append(record['site_id'])
347 if 'site_ids' in record:
348 site_ids.extend(record['site_ids'])
349 if 'person_ids' in record:
350 person_ids.extend(record['person_ids'])
351 if 'slice_ids' in record:
352 slice_ids.extend(record['slice_ids'])
353 if 'node_ids' in record:
354 node_ids.extend(record['node_ids'])
357 slices, persons, sites, nodes = {}, {}, {}, {}
359 site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
360 sites = list_to_dict(site_list, 'site_id')
362 person_list = self.shell.GetPersons(person_ids, ['person_id', 'email'])
363 persons = list_to_dict(person_list, 'person_id')
365 slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
366 slices = list_to_dict(slice_list, 'slice_id')
368 node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
369 nodes = list_to_dict(node_list, 'node_id')
371 # convert ids to hrns
372 for record in records:
373 # get all relevant data
374 type = record['type']
375 pointer = record['pointer']
381 if 'site_id' in record:
382 site = sites[record['site_id']]
383 login_base = site['login_base']
384 record['site'] = ".".join([auth_hrn, login_base])
385 if 'person_ids' in record:
386 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
387 if person_id in persons]
388 usernames = [email.split('@')[0] for email in emails]
389 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
390 record['persons'] = person_hrns
391 if 'slice_ids' in record:
392 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
393 if slice_id in slices]
394 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
395 record['slices'] = slice_hrns
396 if 'node_ids' in record:
397 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
399 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
400 record['nodes'] = node_hrns
401 if 'site_ids' in record:
402 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
404 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
405 record['sites'] = site_hrns
407 if 'expires' in record:
408 date = utcparse(record['expires'])
409 datestring = datetime_to_string(date)
410 record['expires'] = datestring
414 def fill_record_sfa_info(self, records):
416 def startswith(prefix, values):
417 return [value for value in values if value.startswith(prefix)]
422 for record in records:
423 person_ids.extend(record.get("person_ids", []))
424 site_ids.extend(record.get("site_ids", []))
425 if 'site_id' in record:
426 site_ids.append(record['site_id'])
428 # get all pis from the sites we've encountered
429 # and store them in a dictionary keyed on site_id
432 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
433 pi_list = self.shell.GetPersons(pi_filter, ['person_id', 'site_ids'])
435 # we will need the pi's hrns also
436 person_ids.append(pi['person_id'])
438 # we also need to keep track of the sites these pis
440 for site_id in pi['site_ids']:
441 if site_id in site_pis:
442 site_pis[site_id].append(pi)
444 site_pis[site_id] = [pi]
446 # get sfa records for all records associated with these records.
447 # we'll replace pl ids (person_ids) with hrns from the sfa records
450 # get the registry records
451 person_list, persons = [], {}
452 person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
453 # create a hrns keyed on the sfa record's pointer.
454 # Its possible for multiple records to have the same pointer so
455 # the dict's value will be a list of hrns.
456 persons = defaultdict(list)
457 for person in person_list:
458 persons[person.pointer].append(person)
461 pl_person_list, pl_persons = [], {}
462 pl_person_list = self.shell.GetPersons(person_ids, ['person_id', 'roles'])
463 pl_persons = list_to_dict(pl_person_list, 'person_id')
466 for record in records:
467 # skip records with no pl info (top level authorities)
468 #if record['pointer'] == -1:
471 type = record['type']
472 logger.info("fill_record_sfa_info - incoming record typed %s"%type)
473 if (type == "slice"):
474 # all slice users are researchers
475 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
477 record['researcher'] = []
478 for person_id in record.get('person_ids', []):
479 hrns = [person.hrn for person in persons[person_id]]
480 record['researcher'].extend(hrns)
482 # pis at the slice's site
483 if 'site_id' in record and record['site_id'] in site_pis:
484 pl_pis = site_pis[record['site_id']]
485 pi_ids = [pi['person_id'] for pi in pl_pis]
486 for person_id in pi_ids:
487 hrns = [person.hrn for person in persons[person_id]]
488 record['PI'].extend(hrns)
489 record['geni_creator'] = record['PI']
491 elif (type.startswith("authority")):
493 logger.info("fill_record_sfa_info - authority xherex")
494 if record['pointer'] != -1:
496 record['operator'] = []
498 for pointer in record.get('person_ids', []):
499 if pointer not in persons or pointer not in pl_persons:
500 # this means there is not sfa or pl record for this user
502 hrns = [person.hrn for person in persons[pointer]]
503 roles = pl_persons[pointer]['roles']
505 record['PI'].extend(hrns)
507 record['operator'].extend(hrns)
509 record['owner'].extend(hrns)
510 # xxx TODO: OrganizationName
511 elif (type == "node"):
512 sfa_info['dns'] = record.get("hostname", "")
513 # xxx TODO: URI, LatLong, IP, DNS
515 elif (type == "user"):
516 logger.info('setting user.email')
517 sfa_info['email'] = record.get("email", "")
518 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
519 sfa_info['geni_certificate'] = record['gid']
520 # xxx TODO: PostalAddress, Phone
521 record.update(sfa_info)
525 # plcapi works by changes, compute what needs to be added/deleted
526 def update_relation (self, subject_type, target_type, subject_id, target_ids):
527 # hard-wire the code for slice/user for now, could be smarter if needed
528 if subject_type =='slice' and target_type == 'user':
529 subject=self.shell.GetSlices (subject_id)[0]
530 current_target_ids = subject['person_ids']
531 add_target_ids = list ( set (target_ids).difference(current_target_ids))
532 del_target_ids = list ( set (current_target_ids).difference(target_ids))
533 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
534 for target_id in add_target_ids:
535 self.shell.AddPersonToSlice (target_id,subject_id)
536 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
537 for target_id in del_target_ids:
538 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
539 self.shell.DeletePersonFromSlice (target_id, subject_id)
541 logger.info('unexpected relation to maintain, %s -> %s'%(subject_type,target_type))
544 ########################################
545 ########## aggregate oriented
546 ########################################
548 def testbed_name (self): return "myplc"
550 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
551 def aggregate_version (self):
552 version_manager = VersionManager()
553 ad_rspec_versions = []
554 request_rspec_versions = []
555 for rspec_version in version_manager.versions:
556 if rspec_version.content_type in ['*', 'ad']:
557 ad_rspec_versions.append(rspec_version.to_dict())
558 if rspec_version.content_type in ['*', 'request']:
559 request_rspec_versions.append(rspec_version.to_dict())
561 'testbed':self.testbed_name(),
562 'geni_request_rspec_versions': request_rspec_versions,
563 'geni_ad_rspec_versions': ad_rspec_versions,
566 def list_slices (self, creds, options):
567 # look in cache first
569 slices = self.cache.get('slices')
571 logger.debug("PlDriver.list_slices returns from cache")
575 slices = self.shell.GetSlices({'peer_id': None}, ['name'])
576 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
577 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
581 logger.debug ("PlDriver.list_slices stores value in cache")
582 self.cache.add('slices', slice_urns)
586 # first 2 args are None in case of resource discovery
587 def list_resources (self, slice_urn, slice_hrn, creds, options):
588 cached_requested = options.get('cached', True)
590 version_manager = VersionManager()
591 # get the rspec's return format from options
592 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
593 version_string = "rspec_%s" % (rspec_version)
595 #panos adding the info option to the caching key (can be improved)
596 if options.get('info'):
597 version_string = version_string + "_"+options.get('info', 'default')
599 # look in cache first
600 if cached_requested and self.cache and not slice_hrn:
601 rspec = self.cache.get(version_string)
603 logger.debug("PlDriver.ListResources: returning cached advertisement")
606 #panos: passing user-defined options
607 #print "manager options = ",options
608 aggregate = PlAggregate(self)
609 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
613 if self.cache and not slice_hrn:
614 logger.debug("PlDriver.ListResources: stores advertisement in cache")
615 self.cache.add(version_string, rspec)
619 def sliver_status (self, slice_urn, slice_hrn):
620 # find out where this slice is currently running
621 slicename = hrn_to_pl_slicename(slice_hrn)
623 slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
625 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
628 # report about the local nodes only
629 nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
630 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
633 raise SliverDoesNotExist("You have not allocated any slivers here")
635 site_ids = [node['site_id'] for node in nodes]
638 top_level_status = 'unknown'
640 top_level_status = 'ready'
641 result['geni_urn'] = slice_urn
642 result['pl_login'] = slice['name']
643 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
648 res['pl_hostname'] = node['hostname']
649 res['pl_boot_state'] = node['boot_state']
650 res['pl_last_contact'] = node['last_contact']
651 if node['last_contact'] is not None:
653 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
654 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'])
655 res['geni_urn'] = sliver_id
656 if node['boot_state'] == 'boot':
657 res['geni_status'] = 'ready'
659 res['geni_status'] = 'failed'
660 top_level_status = 'failed'
662 res['geni_error'] = ''
664 resources.append(res)
666 result['geni_status'] = top_level_status
667 result['geni_resources'] = resources
670 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
672 aggregate = PlAggregate(self)
673 slices = PlSlices(self)
674 peer = slices.get_peer(slice_hrn)
675 sfa_peer = slices.get_sfa_peer(slice_hrn)
678 slice_record = users[0].get('slice_record', {})
681 rspec = RSpec(rspec_string)
682 requested_attributes = rspec.version.get_slice_attributes()
684 # ensure site record exists
685 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
686 # ensure slice record exists
687 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
688 # ensure person records exists
689 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
690 # ensure slice attributes exists
691 slices.verify_slice_attributes(slice, requested_attributes, options=options)
693 # add/remove slice from nodes
694 requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
695 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
697 # add/remove links links
698 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
700 # handle MyPLC peer association.
701 # only used by plc and ple.
702 slices.handle_peer(site, slice, persons, peer)
704 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
706 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
707 slicename = hrn_to_pl_slicename(slice_hrn)
708 slices = self.shell.GetSlices({'name': slicename})
713 # determine if this is a peer slice
714 # xxx I wonder if this would not need to use PlSlices.get_peer instead
715 # in which case plc.peers could be deprecated as this here
716 # is the only/last call to this last method in plc.peers
717 peer = peers.get_peer(self, slice_hrn)
720 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
721 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
724 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
727 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
728 slicename = hrn_to_pl_slicename(slice_hrn)
729 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
731 raise RecordNotFound(slice_hrn)
733 requested_time = utcparse(expiration_time)
734 record = {'expires': int(datetime_to_epoch(requested_time))}
736 self.shell.UpdateSlice(slice['slice_id'], record)
741 # remove the 'enabled' tag
742 def start_slice (self, slice_urn, slice_hrn, creds):
743 slicename = hrn_to_pl_slicename(slice_hrn)
744 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
746 raise RecordNotFound(slice_hrn)
747 slice_id = slices[0]['slice_id']
748 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
749 # just remove the tag if it exists
751 self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
754 # set the 'enabled' tag to 0
755 def stop_slice (self, slice_urn, slice_hrn, creds):
756 slicename = hrn_to_pl_slicename(slice_hrn)
757 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
759 raise RecordNotFound(slice_hrn)
760 slice_id = slices[0]['slice_id']
761 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
763 self.shell.AddSliceTag(slice_id, 'enabled', '0')
764 elif slice_tags[0]['value'] != "0":
765 tag_id = slice_tags[0]['slice_tag_id']
766 self.shell.UpdateSliceTag(tag_id, '0')
769 def reset_slice (self, slice_urn, slice_hrn, creds):
770 raise SfaNotImplemented ("reset_slice not available at this interface")
772 # xxx this code is quite old and has not run for ages
773 # it is obviously totally broken and needs a rewrite
774 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
775 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
776 # please keep this code for future reference
777 # slices = PlSlices(self)
778 # peer = slices.get_peer(slice_hrn)
779 # sfa_peer = slices.get_sfa_peer(slice_hrn)
781 # # get the slice record
782 # credential = api.getCredential()
783 # interface = api.registries[api.hrn]
784 # registry = api.server_proxy(interface, credential)
785 # records = registry.Resolve(xrn, credential)
787 # # make sure we get a local slice record
789 # for tmp_record in records:
790 # if tmp_record['type'] == 'slice' and \
791 # not tmp_record['peer_authority']:
792 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
793 # slice_record = SliceRecord(dict=tmp_record)
795 # raise RecordNotFound(slice_hrn)
797 # # similar to CreateSliver, we must verify that the required records exist
798 # # at this aggregate before we can issue a ticket
800 # rspec = RSpec(rspec_string)
801 # requested_attributes = rspec.version.get_slice_attributes()
803 # # ensure site record exists
804 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
805 # # ensure slice record exists
806 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
807 # # ensure person records exists
808 # # xxx users is undefined in this context
809 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
810 # # ensure slice attributes exists
811 # slices.verify_slice_attributes(slice, requested_attributes)
814 # slivers = slices.get_slivers(slice_hrn)
817 # raise SliverDoesNotExist(slice_hrn)
822 # 'timestamp': int(time.time()),
823 # 'initscripts': initscripts,
827 # # create the ticket
828 # object_gid = record.get_gid_object()
829 # new_ticket = SfaTicket(subject = object_gid.get_subject())
830 # new_ticket.set_gid_caller(api.auth.client_gid)
831 # new_ticket.set_gid_object(object_gid)
832 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
833 # new_ticket.set_pubkey(object_gid.get_pubkey())
834 # new_ticket.set_attributes(data)
835 # new_ticket.set_rspec(rspec)
836 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
837 # new_ticket.encode()
840 # return new_ticket.save_to_string(save_parents=True)