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?
114 if 'roles' in sfa_record:
115 # if specified in xml, but only low-level roles
116 roles = [ role for role in sfa_record['roles'] if role in ['user','tech'] ]
117 # at least user if no other cluse could be found
121 self.shell.AddRoleToPerson(role, pointer)
124 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
127 login_base = hrn_to_pl_login_base(sfa_record['authority'])
128 nodes = self.shell.GetNodes([pl_record['hostname']])
130 pointer = self.shell.AddNode(login_base, pl_record)
132 pointer = nodes[0]['node_id']
137 # xxx actually old_sfa_record comes filled with plc stuff as well in the original code
138 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
139 pointer = old_sfa_record['pointer']
140 type = old_sfa_record['type']
142 # new_key implemented for users only
143 if new_key and type not in [ 'user' ]:
144 raise UnknownSfaType(type)
146 if (type == "authority"):
147 self.shell.UpdateSite(pointer, new_sfa_record)
149 elif type == "slice":
150 pl_record=self.sfa_fields_to_pl_fields(type, hrn, new_sfa_record)
151 if 'name' in pl_record:
152 pl_record.pop('name')
153 self.shell.UpdateSlice(pointer, pl_record)
156 # SMBAKER: UpdatePerson only allows a limited set of fields to be
157 # updated. Ideally we should have a more generic way of doing
158 # this. I copied the field names from UpdatePerson.py...
160 all_fields = new_sfa_record
161 for key in all_fields.keys():
162 if key in ['first_name', 'last_name', 'title', 'email',
163 'password', 'phone', 'url', 'bio', 'accepted_aup',
165 update_fields[key] = all_fields[key]
166 self.shell.UpdatePerson(pointer, update_fields)
169 # must check this key against the previous one if it exists
170 persons = self.shell.GetPersons([pointer], ['key_ids'])
172 keys = person['key_ids']
173 keys = self.shell.GetKeys(person['key_ids'])
175 # Delete all stale keys
178 if new_key != key['key']:
179 self.shell.DeleteKey(key['key_id'])
183 self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
186 self.shell.UpdateNode(pointer, new_sfa_record)
192 def remove (self, sfa_record):
193 type=sfa_record['type']
194 pointer=sfa_record['pointer']
196 persons = self.shell.GetPersons(pointer)
197 # only delete this person if he has site ids. if he doesnt, it probably means
198 # he was just removed from a site, not actually deleted
199 if persons and persons[0]['site_ids']:
200 self.shell.DeletePerson(pointer)
201 elif type == 'slice':
202 if self.shell.GetSlices(pointer):
203 self.shell.DeleteSlice(pointer)
205 if self.shell.GetNodes(pointer):
206 self.shell.DeleteNode(pointer)
207 elif type == 'authority':
208 if self.shell.GetSites(pointer):
209 self.shell.DeleteSite(pointer)
218 # Convert SFA fields to PLC fields for use when registering or updating
219 # registry record in the PLC database
222 def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
227 pl_record["name"] = hrn_to_pl_slicename(hrn)
228 if "instantiation" in sfa_record:
229 pl_record['instantiation']=sfa_record['instantiation']
231 pl_record["instantiation"] = "plc-instantiated"
232 if "url" in sfa_record:
233 pl_record["url"] = sfa_record["url"]
234 if "description" in sfa_record:
235 pl_record["description"] = sfa_record["description"]
236 if "expires" in sfa_record:
237 date = utcparse(sfa_record['expires'])
238 expires = datetime_to_epoch(date)
239 pl_record["expires"] = expires
242 if not "hostname" in pl_record:
243 # fetch from sfa_record
244 if "hostname" not in sfa_record:
245 raise MissingSfaInfo("hostname")
246 pl_record["hostname"] = sfa_record["hostname"]
247 if "model" in sfa_record:
248 pl_record["model"] = sfa_record["model"]
250 pl_record["model"] = "geni"
252 elif type == "authority":
253 pl_record["login_base"] = hrn_to_pl_login_base(hrn)
254 if "name" not in sfa_record:
255 pl_record["name"] = hrn
256 if "abbreviated_name" not in sfa_record:
257 pl_record["abbreviated_name"] = hrn
258 if "enabled" not in sfa_record:
259 pl_record["enabled"] = True
260 if "is_public" not in sfa_record:
261 pl_record["is_public"] = True
266 def fill_record_info(self, records):
268 Given a (list of) SFA record, fill in the PLC specific
269 and SFA specific fields in the record.
271 if not isinstance(records, list):
274 self.fill_record_pl_info(records)
275 self.fill_record_hrns(records)
276 self.fill_record_sfa_info(records)
279 def fill_record_pl_info(self, records):
281 Fill in the planetlab specific fields of a SFA record. This
282 involves calling the appropriate PLC method to retrieve the
283 database record for the object.
285 @param record: record to fill in field (in/out param)
288 node_ids, site_ids, slice_ids = [], [], []
289 person_ids, key_ids = [], []
290 type_map = {'node': node_ids, 'authority': site_ids,
291 'slice': slice_ids, 'user': person_ids}
293 for record in records:
294 for type in type_map:
295 if type == record['type']:
296 type_map[type].append(record['pointer'])
299 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
301 node_list = self.shell.GetNodes(node_ids)
302 nodes = list_to_dict(node_list, 'node_id')
304 site_list = self.shell.GetSites(site_ids)
305 sites = list_to_dict(site_list, 'site_id')
307 slice_list = self.shell.GetSlices(slice_ids)
308 slices = list_to_dict(slice_list, 'slice_id')
310 person_list = self.shell.GetPersons(person_ids)
311 persons = list_to_dict(person_list, 'person_id')
312 for person in persons:
313 key_ids.extend(persons[person]['key_ids'])
315 pl_records = {'node': nodes, 'authority': sites,
316 'slice': slices, 'user': persons}
319 key_list = self.shell.GetKeys(key_ids)
320 keys = list_to_dict(key_list, 'key_id')
323 for record in records:
324 # records with pointer==-1 do not have plc info.
325 # for example, the top level authority records which are
326 # authorities, but not PL "sites"
327 if record['pointer'] == -1:
330 for type in pl_records:
331 if record['type'] == type:
332 if record['pointer'] in pl_records[type]:
333 record.update(pl_records[type][record['pointer']])
336 if record['type'] == 'user':
337 if 'key_ids' not in record:
338 logger.info("user record has no 'key_ids' - need to import from myplc ?")
340 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
341 record['keys'] = pubkeys
345 def fill_record_hrns(self, records):
347 convert pl ids to hrns
351 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
352 for record in records:
353 if 'site_id' in record:
354 site_ids.append(record['site_id'])
355 if 'site_ids' in record:
356 site_ids.extend(record['site_ids'])
357 if 'person_ids' in record:
358 person_ids.extend(record['person_ids'])
359 if 'slice_ids' in record:
360 slice_ids.extend(record['slice_ids'])
361 if 'node_ids' in record:
362 node_ids.extend(record['node_ids'])
365 slices, persons, sites, nodes = {}, {}, {}, {}
367 site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
368 sites = list_to_dict(site_list, 'site_id')
370 person_list = self.shell.GetPersons(person_ids, ['person_id', 'email'])
371 persons = list_to_dict(person_list, 'person_id')
373 slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
374 slices = list_to_dict(slice_list, 'slice_id')
376 node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
377 nodes = list_to_dict(node_list, 'node_id')
379 # convert ids to hrns
380 for record in records:
381 # get all relevant data
382 type = record['type']
383 pointer = record['pointer']
389 if 'site_id' in record:
390 site = sites[record['site_id']]
391 login_base = site['login_base']
392 record['site'] = ".".join([auth_hrn, login_base])
393 if 'person_ids' in record:
394 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
395 if person_id in persons]
396 usernames = [email.split('@')[0] for email in emails]
397 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
398 record['persons'] = person_hrns
399 if 'slice_ids' in record:
400 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
401 if slice_id in slices]
402 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
403 record['slices'] = slice_hrns
404 if 'node_ids' in record:
405 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
407 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
408 record['nodes'] = node_hrns
409 if 'site_ids' in record:
410 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
412 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
413 record['sites'] = site_hrns
415 if 'expires' in record:
416 date = utcparse(record['expires'])
417 datestring = datetime_to_string(date)
418 record['expires'] = datestring
422 def fill_record_sfa_info(self, records):
424 def startswith(prefix, values):
425 return [value for value in values if value.startswith(prefix)]
430 for record in records:
431 person_ids.extend(record.get("person_ids", []))
432 site_ids.extend(record.get("site_ids", []))
433 if 'site_id' in record:
434 site_ids.append(record['site_id'])
436 # get all pis from the sites we've encountered
437 # and store them in a dictionary keyed on site_id
440 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
441 pi_list = self.shell.GetPersons(pi_filter, ['person_id', 'site_ids'])
443 # we will need the pi's hrns also
444 person_ids.append(pi['person_id'])
446 # we also need to keep track of the sites these pis
448 for site_id in pi['site_ids']:
449 if site_id in site_pis:
450 site_pis[site_id].append(pi)
452 site_pis[site_id] = [pi]
454 # get sfa records for all records associated with these records.
455 # we'll replace pl ids (person_ids) with hrns from the sfa records
458 # get the registry records
459 person_list, persons = [], {}
460 person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
461 # create a hrns keyed on the sfa record's pointer.
462 # Its possible for multiple records to have the same pointer so
463 # the dict's value will be a list of hrns.
464 persons = defaultdict(list)
465 for person in person_list:
466 persons[person.pointer].append(person)
469 pl_person_list, pl_persons = [], {}
470 pl_person_list = self.shell.GetPersons(person_ids, ['person_id', 'roles'])
471 pl_persons = list_to_dict(pl_person_list, 'person_id')
474 for record in records:
475 # skip records with no pl info (top level authorities)
476 #if record['pointer'] == -1:
479 type = record['type']
480 logger.info("fill_record_sfa_info - incoming record typed %s"%type)
481 if (type == "slice"):
482 # all slice users are researchers
483 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
485 record['researcher'] = []
486 for person_id in record.get('person_ids', []):
487 hrns = [person.hrn for person in persons[person_id]]
488 record['researcher'].extend(hrns)
490 # pis at the slice's site
491 if 'site_id' in record and record['site_id'] in site_pis:
492 pl_pis = site_pis[record['site_id']]
493 pi_ids = [pi['person_id'] for pi in pl_pis]
494 for person_id in pi_ids:
495 hrns = [person.hrn for person in persons[person_id]]
496 record['PI'].extend(hrns)
497 record['geni_creator'] = record['PI']
499 elif (type.startswith("authority")):
501 logger.info("fill_record_sfa_info - authority xherex")
502 if record['pointer'] != -1:
504 record['operator'] = []
506 for pointer in record.get('person_ids', []):
507 if pointer not in persons or pointer not in pl_persons:
508 # this means there is not sfa or pl record for this user
510 hrns = [person.hrn for person in persons[pointer]]
511 roles = pl_persons[pointer]['roles']
513 record['PI'].extend(hrns)
515 record['operator'].extend(hrns)
517 record['owner'].extend(hrns)
518 # xxx TODO: OrganizationName
519 elif (type == "node"):
520 sfa_info['dns'] = record.get("hostname", "")
521 # xxx TODO: URI, LatLong, IP, DNS
523 elif (type == "user"):
524 logger.info('setting user.email')
525 sfa_info['email'] = record.get("email", "")
526 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
527 sfa_info['geni_certificate'] = record['gid']
528 # xxx TODO: PostalAddress, Phone
529 record.update(sfa_info)
533 # plcapi works by changes, compute what needs to be added/deleted
534 def update_relation (self, subject_type, target_type, subject_id, target_ids):
535 # hard-wire the code for slice/user for now, could be smarter if needed
536 if subject_type =='slice' and target_type == 'user':
537 subject=self.shell.GetSlices (subject_id)[0]
538 current_target_ids = subject['person_ids']
539 add_target_ids = list ( set (target_ids).difference(current_target_ids))
540 del_target_ids = list ( set (current_target_ids).difference(target_ids))
541 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
542 for target_id in add_target_ids:
543 self.shell.AddPersonToSlice (target_id,subject_id)
544 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
545 for target_id in del_target_ids:
546 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
547 self.shell.DeletePersonFromSlice (target_id, subject_id)
549 logger.info('unexpected relation to maintain, %s -> %s'%(subject_type,target_type))
552 ########################################
553 ########## aggregate oriented
554 ########################################
556 def testbed_name (self): return "myplc"
558 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
559 def aggregate_version (self):
560 version_manager = VersionManager()
561 ad_rspec_versions = []
562 request_rspec_versions = []
563 for rspec_version in version_manager.versions:
564 if rspec_version.content_type in ['*', 'ad']:
565 ad_rspec_versions.append(rspec_version.to_dict())
566 if rspec_version.content_type in ['*', 'request']:
567 request_rspec_versions.append(rspec_version.to_dict())
569 'testbed':self.testbed_name(),
570 'geni_request_rspec_versions': request_rspec_versions,
571 'geni_ad_rspec_versions': ad_rspec_versions,
574 def list_slices (self, creds, options):
575 # look in cache first
577 slices = self.cache.get('slices')
579 logger.debug("PlDriver.list_slices returns from cache")
583 slices = self.shell.GetSlices({'peer_id': None}, ['name'])
584 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
585 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
589 logger.debug ("PlDriver.list_slices stores value in cache")
590 self.cache.add('slices', slice_urns)
594 # first 2 args are None in case of resource discovery
595 def list_resources (self, slice_urn, slice_hrn, creds, options):
596 cached_requested = options.get('cached', True)
598 version_manager = VersionManager()
599 # get the rspec's return format from options
600 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
601 version_string = "rspec_%s" % (rspec_version)
603 #panos adding the info option to the caching key (can be improved)
604 if options.get('info'):
605 version_string = version_string + "_"+options.get('info', 'default')
607 # look in cache first
608 if cached_requested and self.cache and not slice_hrn:
609 rspec = self.cache.get(version_string)
611 logger.debug("PlDriver.ListResources: returning cached advertisement")
614 #panos: passing user-defined options
615 #print "manager options = ",options
616 aggregate = PlAggregate(self)
617 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
621 if self.cache and not slice_hrn:
622 logger.debug("PlDriver.ListResources: stores advertisement in cache")
623 self.cache.add(version_string, rspec)
627 def sliver_status (self, slice_urn, slice_hrn):
628 # find out where this slice is currently running
629 slicename = hrn_to_pl_slicename(slice_hrn)
631 slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
633 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
636 # report about the local nodes only
637 nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
638 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
641 raise SliverDoesNotExist("You have not allocated any slivers here")
643 site_ids = [node['site_id'] for node in nodes]
646 top_level_status = 'unknown'
648 top_level_status = 'ready'
649 result['geni_urn'] = slice_urn
650 result['pl_login'] = slice['name']
651 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
656 res['pl_hostname'] = node['hostname']
657 res['pl_boot_state'] = node['boot_state']
658 res['pl_last_contact'] = node['last_contact']
659 if node['last_contact'] is not None:
661 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
662 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'])
663 res['geni_urn'] = sliver_id
664 if node['boot_state'] == 'boot':
665 res['geni_status'] = 'ready'
667 res['geni_status'] = 'failed'
668 top_level_status = 'failed'
670 res['geni_error'] = ''
672 resources.append(res)
674 result['geni_status'] = top_level_status
675 result['geni_resources'] = resources
678 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
680 aggregate = PlAggregate(self)
681 slices = PlSlices(self)
682 peer = slices.get_peer(slice_hrn)
683 sfa_peer = slices.get_sfa_peer(slice_hrn)
686 slice_record = users[0].get('slice_record', {})
689 rspec = RSpec(rspec_string)
690 requested_attributes = rspec.version.get_slice_attributes()
692 # ensure site record exists
693 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
694 # ensure slice record exists
695 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
696 # ensure person records exists
697 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
698 # ensure slice attributes exists
699 slices.verify_slice_attributes(slice, requested_attributes, options=options)
701 # add/remove slice from nodes
702 requested_slivers = [node.get('component_name') for node in rspec.version.get_nodes_with_slivers()]
703 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
705 # add/remove links links
706 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
708 # handle MyPLC peer association.
709 # only used by plc and ple.
710 slices.handle_peer(site, slice, persons, peer)
712 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
714 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
715 slicename = hrn_to_pl_slicename(slice_hrn)
716 slices = self.shell.GetSlices({'name': slicename})
721 # determine if this is a peer slice
722 # xxx I wonder if this would not need to use PlSlices.get_peer instead
723 # in which case plc.peers could be deprecated as this here
724 # is the only/last call to this last method in plc.peers
725 peer = peers.get_peer(self, slice_hrn)
728 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
729 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
732 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
735 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
736 slicename = hrn_to_pl_slicename(slice_hrn)
737 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
739 raise RecordNotFound(slice_hrn)
741 requested_time = utcparse(expiration_time)
742 record = {'expires': int(datetime_to_epoch(requested_time))}
744 self.shell.UpdateSlice(slice['slice_id'], record)
749 # remove the 'enabled' tag
750 def start_slice (self, slice_urn, slice_hrn, creds):
751 slicename = hrn_to_pl_slicename(slice_hrn)
752 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
754 raise RecordNotFound(slice_hrn)
755 slice_id = slices[0]['slice_id']
756 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
757 # just remove the tag if it exists
759 self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
762 # set the 'enabled' tag to 0
763 def stop_slice (self, slice_urn, slice_hrn, creds):
764 slicename = hrn_to_pl_slicename(slice_hrn)
765 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
767 raise RecordNotFound(slice_hrn)
768 slice_id = slices[0]['slice_id']
769 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
771 self.shell.AddSliceTag(slice_id, 'enabled', '0')
772 elif slice_tags[0]['value'] != "0":
773 tag_id = slice_tags[0]['slice_tag_id']
774 self.shell.UpdateSliceTag(tag_id, '0')
777 def reset_slice (self, slice_urn, slice_hrn, creds):
778 raise SfaNotImplemented ("reset_slice not available at this interface")
780 # xxx this code is quite old and has not run for ages
781 # it is obviously totally broken and needs a rewrite
782 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
783 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
784 # please keep this code for future reference
785 # slices = PlSlices(self)
786 # peer = slices.get_peer(slice_hrn)
787 # sfa_peer = slices.get_sfa_peer(slice_hrn)
789 # # get the slice record
790 # credential = api.getCredential()
791 # interface = api.registries[api.hrn]
792 # registry = api.server_proxy(interface, credential)
793 # records = registry.Resolve(xrn, credential)
795 # # make sure we get a local slice record
797 # for tmp_record in records:
798 # if tmp_record['type'] == 'slice' and \
799 # not tmp_record['peer_authority']:
800 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
801 # slice_record = SliceRecord(dict=tmp_record)
803 # raise RecordNotFound(slice_hrn)
805 # # similar to CreateSliver, we must verify that the required records exist
806 # # at this aggregate before we can issue a ticket
808 # rspec = RSpec(rspec_string)
809 # requested_attributes = rspec.version.get_slice_attributes()
811 # # ensure site record exists
812 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
813 # # ensure slice record exists
814 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
815 # # ensure person records exists
816 # # xxx users is undefined in this context
817 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
818 # # ensure slice attributes exists
819 # slices.verify_slice_attributes(slice, requested_attributes)
822 # slivers = slices.get_slivers(slice_hrn)
825 # raise SliverDoesNotExist(slice_hrn)
830 # 'timestamp': int(time.time()),
831 # 'initscripts': initscripts,
835 # # create the ticket
836 # object_gid = record.get_gid_object()
837 # new_ticket = SfaTicket(subject = object_gid.get_subject())
838 # new_ticket.set_gid_caller(api.auth.client_gid)
839 # new_ticket.set_gid_object(object_gid)
840 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
841 # new_ticket.set_pubkey(object_gid.get_pubkey())
842 # new_ticket.set_attributes(data)
843 # new_ticket.set_rspec(rspec)
844 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
845 # new_ticket.encode()
848 # return new_ticket.save_to_string(save_parents=True)