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.persistentobjs 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 if (type == "slice"):
473 # all slice users are researchers
474 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
476 record['researcher'] = []
477 for person_id in record.get('person_ids', []):
478 hrns = [person.hrn for person in persons[person_id]]
479 record['researcher'].extend(hrns)
481 # pis at the slice's site
482 if 'site_id' in record and record['site_id'] in site_pis:
483 pl_pis = site_pis[record['site_id']]
484 pi_ids = [pi['person_id'] for pi in pl_pis]
485 for person_id in pi_ids:
486 hrns = [person.hrn for person in persons[person_id]]
487 record['PI'].extend(hrns)
488 record['geni_creator'] = record['PI']
490 elif (type.startswith("authority")):
492 if record['pointer'] != -1:
494 record['operator'] = []
496 for pointer in record.get('person_ids', []):
497 if pointer not in persons or pointer not in pl_persons:
498 # this means there is not sfa or pl record for this user
500 hrns = [person.hrn for person in persons[pointer]]
501 roles = pl_persons[pointer]['roles']
503 record['PI'].extend(hrns)
505 record['operator'].extend(hrns)
507 record['owner'].extend(hrns)
508 # xxx TODO: OrganizationName
509 elif (type == "node"):
510 sfa_info['dns'] = record.get("hostname", "")
511 # xxx TODO: URI, LatLong, IP, DNS
513 elif (type == "user"):
514 sfa_info['email'] = record.get("email", "")
515 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
516 sfa_info['geni_certificate'] = record['gid']
517 # xxx TODO: PostalAddress, Phone
518 record.update(sfa_info)
522 # plcapi works by changes, compute what needs to be added/deleted
523 def update_relation (self, subject_type, target_type, subject_id, target_ids):
524 # hard-wire the code for slice/user for now, could be smarter if needed
525 if subject_type =='slice' and target_type == 'user':
526 subject=self.shell.GetSlices (subject_id)[0]
527 current_target_ids = subject['person_ids']
528 add_target_ids = list ( set (target_ids).difference(current_target_ids))
529 del_target_ids = list ( set (current_target_ids).difference(target_ids))
530 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
531 for target_id in add_target_ids:
532 self.shell.AddPersonToSlice (target_id,subject_id)
533 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
534 for target_id in del_target_ids:
535 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
536 self.shell.DeletePersonFromSlice (target_id, subject_id)
538 logger.info('unexpected relation to maintain, %s -> %s'%(subject_type,target_type))
541 ########################################
542 ########## aggregate oriented
543 ########################################
545 def testbed_name (self): return "myplc"
547 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
548 def aggregate_version (self):
549 version_manager = VersionManager()
550 ad_rspec_versions = []
551 request_rspec_versions = []
552 for rspec_version in version_manager.versions:
553 if rspec_version.content_type in ['*', 'ad']:
554 ad_rspec_versions.append(rspec_version.to_dict())
555 if rspec_version.content_type in ['*', 'request']:
556 request_rspec_versions.append(rspec_version.to_dict())
558 'testbed':self.testbed_name(),
559 'geni_request_rspec_versions': request_rspec_versions,
560 'geni_ad_rspec_versions': ad_rspec_versions,
563 def list_slices (self, creds, options):
564 # look in cache first
566 slices = self.cache.get('slices')
568 logger.debug("PlDriver.list_slices returns from cache")
572 slices = self.shell.GetSlices({'peer_id': None}, ['name'])
573 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
574 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
578 logger.debug ("PlDriver.list_slices stores value in cache")
579 self.cache.add('slices', slice_urns)
583 # first 2 args are None in case of resource discovery
584 def list_resources (self, slice_urn, slice_hrn, creds, options):
585 cached_requested = options.get('cached', True)
587 version_manager = VersionManager()
588 # get the rspec's return format from options
589 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
590 version_string = "rspec_%s" % (rspec_version)
592 #panos adding the info option to the caching key (can be improved)
593 if options.get('info'):
594 version_string = version_string + "_"+options.get('info', 'default')
596 # look in cache first
597 if cached_requested and self.cache and not slice_hrn:
598 rspec = self.cache.get(version_string)
600 logger.debug("PlDriver.ListResources: returning cached advertisement")
603 #panos: passing user-defined options
604 #print "manager options = ",options
605 aggregate = PlAggregate(self)
606 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
610 if self.cache and not slice_hrn:
611 logger.debug("PlDriver.ListResources: stores advertisement in cache")
612 self.cache.add(version_string, rspec)
616 def sliver_status (self, slice_urn, slice_hrn):
617 # find out where this slice is currently running
618 slicename = hrn_to_pl_slicename(slice_hrn)
620 slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
622 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
625 # report about the local nodes only
626 nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
627 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
630 raise SliverDoesNotExist("You have not allocated any slivers here")
632 site_ids = [node['site_id'] for node in nodes]
635 top_level_status = 'unknown'
637 top_level_status = 'ready'
638 result['geni_urn'] = slice_urn
639 result['pl_login'] = slice['name']
640 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
645 res['pl_hostname'] = node['hostname']
646 res['pl_boot_state'] = node['boot_state']
647 res['pl_last_contact'] = node['last_contact']
648 if node['last_contact'] is not None:
650 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
651 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'])
652 res['geni_urn'] = sliver_id
653 if node['boot_state'] == 'boot':
654 res['geni_status'] = 'ready'
656 res['geni_status'] = 'failed'
657 top_level_status = 'failed'
659 res['geni_error'] = ''
661 resources.append(res)
663 result['geni_status'] = top_level_status
664 result['geni_resources'] = resources
667 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
669 aggregate = PlAggregate(self)
670 slices = PlSlices(self)
671 peer = slices.get_peer(slice_hrn)
672 sfa_peer = slices.get_sfa_peer(slice_hrn)
675 slice_record = users[0].get('slice_record', {})
678 rspec = RSpec(rspec_string)
679 requested_attributes = rspec.version.get_slice_attributes()
681 # ensure site record exists
682 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
683 # ensure slice record exists
684 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
685 # ensure person records exists
686 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
687 # ensure slice attributes exists
688 slices.verify_slice_attributes(slice, requested_attributes, options=options)
690 # add/remove slice from nodes
691 requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
692 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
694 # add/remove links links
695 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
697 # handle MyPLC peer association.
698 # only used by plc and ple.
699 slices.handle_peer(site, slice, persons, peer)
701 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
703 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
704 slicename = hrn_to_pl_slicename(slice_hrn)
705 slices = self.shell.GetSlices({'name': slicename})
710 # determine if this is a peer slice
711 # xxx I wonder if this would not need to use PlSlices.get_peer instead
712 # in which case plc.peers could be deprecated as this here
713 # is the only/last call to this last method in plc.peers
714 peer = peers.get_peer(self, slice_hrn)
717 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
718 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
721 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
724 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
725 slicename = hrn_to_pl_slicename(slice_hrn)
726 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
728 raise RecordNotFound(slice_hrn)
730 requested_time = utcparse(expiration_time)
731 record = {'expires': int(datetime_to_epoch(requested_time))}
733 self.shell.UpdateSlice(slice['slice_id'], record)
738 # remove the 'enabled' tag
739 def start_slice (self, slice_urn, slice_hrn, creds):
740 slicename = hrn_to_pl_slicename(slice_hrn)
741 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
743 raise RecordNotFound(slice_hrn)
744 slice_id = slices[0]['slice_id']
745 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
746 # just remove the tag if it exists
748 self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
751 # set the 'enabled' tag to 0
752 def stop_slice (self, slice_urn, slice_hrn, creds):
753 slicename = hrn_to_pl_slicename(slice_hrn)
754 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
756 raise RecordNotFound(slice_hrn)
757 slice_id = slices[0]['slice_id']
758 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
760 self.shell.AddSliceTag(slice_id, 'enabled', '0')
761 elif slice_tags[0]['value'] != "0":
762 tag_id = slice_tags[0]['slice_tag_id']
763 self.shell.UpdateSliceTag(tag_id, '0')
766 def reset_slice (self, slice_urn, slice_hrn, creds):
767 raise SfaNotImplemented ("reset_slice not available at this interface")
769 # xxx this code is quite old and has not run for ages
770 # it is obviously totally broken and needs a rewrite
771 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
772 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
773 # please keep this code for future reference
774 # slices = PlSlices(self)
775 # peer = slices.get_peer(slice_hrn)
776 # sfa_peer = slices.get_sfa_peer(slice_hrn)
778 # # get the slice record
779 # credential = api.getCredential()
780 # interface = api.registries[api.hrn]
781 # registry = api.server_proxy(interface, credential)
782 # records = registry.Resolve(xrn, credential)
784 # # make sure we get a local slice record
786 # for tmp_record in records:
787 # if tmp_record['type'] == 'slice' and \
788 # not tmp_record['peer_authority']:
789 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
790 # slice_record = SliceRecord(dict=tmp_record)
792 # raise RecordNotFound(slice_hrn)
794 # # similar to CreateSliver, we must verify that the required records exist
795 # # at this aggregate before we can issue a ticket
797 # rspec = RSpec(rspec_string)
798 # requested_attributes = rspec.version.get_slice_attributes()
800 # # ensure site record exists
801 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
802 # # ensure slice record exists
803 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
804 # # ensure person records exists
805 # # xxx users is undefined in this context
806 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
807 # # ensure slice attributes exists
808 # slices.verify_slice_attributes(slice, requested_attributes)
811 # slivers = slices.get_slivers(slice_hrn)
814 # raise SliverDoesNotExist(slice_hrn)
819 # 'timestamp': int(time.time()),
820 # 'initscripts': initscripts,
824 # # create the ticket
825 # object_gid = record.get_gid_object()
826 # new_ticket = SfaTicket(subject = object_gid.get_subject())
827 # new_ticket.set_gid_caller(api.auth.client_gid)
828 # new_ticket.set_gid_object(object_gid)
829 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
830 # new_ticket.set_pubkey(object_gid.get_pubkey())
831 # new_ticket.set_attributes(data)
832 # new_ticket.set_rspec(rspec)
833 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
834 # new_ticket.encode()
837 # return new_ticket.save_to_string(save_parents=True)