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.planetlab.plshell import PlShell
27 import sfa.planetlab.peers as peers
28 from sfa.planetlab.plaggregate import PlAggregate
29 from sfa.planetlab.plslices import PlSlices
30 from sfa.planetlab.plxrn import PlXrn, slicename_to_hrn, hostname_to_hrn, hrn_to_pl_slicename
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 def augment_records_with_testbed_info (self, sfa_records):
64 return self.fill_record_info (sfa_records)
67 def register (self, sfa_record, hrn, pub_key):
68 type = sfa_record['type']
69 pl_record = self.sfa_fields_to_pl_fields(type, hrn, sfa_record)
71 if type == 'authority':
72 sites = self.shell.GetSites([pl_record['login_base']])
74 # xxx when a site gets registered through SFA we need to set its max_slices
75 if 'max_slices' not in pl_record:
76 pl_record['max_slices']=2
77 pointer = self.shell.AddSite(pl_record)
79 pointer = sites[0]['site_id']
82 acceptable_fields=['url', 'instantiation', 'name', 'description']
83 for key in pl_record.keys():
84 if key not in acceptable_fields:
86 slices = self.shell.GetSlices([pl_record['name']])
88 pointer = self.shell.AddSlice(pl_record)
90 pointer = slices[0]['slice_id']
93 persons = self.shell.GetPersons({'email':sfa_record['email']})
95 for key in ['first_name','last_name']:
96 if key not in sfa_record: sfa_record[key]='*from*sfa*'
97 pointer = self.shell.AddPerson(dict(sfa_record))
99 pointer = persons[0]['person_id']
101 if 'enabled' in sfa_record and sfa_record['enabled']:
102 self.shell.UpdatePerson(pointer, {'enabled': sfa_record['enabled']})
103 # add this person to the site only if she is being added for the first
104 # time by sfa and doesont already exist in plc
105 if not persons or not persons[0]['site_ids']:
106 login_base = get_leaf(sfa_record['authority'])
107 self.shell.AddPersonToSite(pointer, login_base)
109 # What roles should this user have?
111 if 'roles' in sfa_record:
112 # if specified in xml, but only low-level roles
113 roles = [ role for role in sfa_record['roles'] if role in ['user','tech'] ]
114 # at least user if no other cluse could be found
118 self.shell.AddRoleToPerson(role, pointer)
121 self.shell.AddPersonKey(pointer, {'key_type' : 'ssh', 'key' : pub_key})
124 login_base = PlXrn(xrn=sfa_record['authority'],type='node').pl_login_base()
125 nodes = self.shell.GetNodes([pl_record['hostname']])
127 pointer = self.shell.AddNode(login_base, pl_record)
129 pointer = nodes[0]['node_id']
134 # xxx actually old_sfa_record comes filled with plc stuff as well in the original code
135 def update (self, old_sfa_record, new_sfa_record, hrn, new_key):
136 pointer = old_sfa_record['pointer']
137 type = old_sfa_record['type']
139 # new_key implemented for users only
140 if new_key and type not in [ 'user' ]:
141 raise UnknownSfaType(type)
143 if (type == "authority"):
144 self.shell.UpdateSite(pointer, new_sfa_record)
146 elif type == "slice":
147 pl_record=self.sfa_fields_to_pl_fields(type, hrn, new_sfa_record)
148 if 'name' in pl_record:
149 pl_record.pop('name')
150 self.shell.UpdateSlice(pointer, pl_record)
153 # SMBAKER: UpdatePerson only allows a limited set of fields to be
154 # updated. Ideally we should have a more generic way of doing
155 # this. I copied the field names from UpdatePerson.py...
157 all_fields = new_sfa_record
158 for key in all_fields.keys():
159 if key in ['first_name', 'last_name', 'title', 'email',
160 'password', 'phone', 'url', 'bio', 'accepted_aup',
162 update_fields[key] = all_fields[key]
163 self.shell.UpdatePerson(pointer, update_fields)
166 # must check this key against the previous one if it exists
167 persons = self.shell.GetPersons([pointer], ['key_ids'])
169 keys = person['key_ids']
170 keys = self.shell.GetKeys(person['key_ids'])
172 # Delete all stale keys
175 if new_key != key['key']:
176 self.shell.DeleteKey(key['key_id'])
180 self.shell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': new_key})
183 self.shell.UpdateNode(pointer, new_sfa_record)
189 def remove (self, sfa_record):
190 type=sfa_record['type']
191 pointer=sfa_record['pointer']
193 persons = self.shell.GetPersons(pointer)
194 # only delete this person if he has site ids. if he doesnt, it probably means
195 # he was just removed from a site, not actually deleted
196 if persons and persons[0]['site_ids']:
197 self.shell.DeletePerson(pointer)
198 elif type == 'slice':
199 if self.shell.GetSlices(pointer):
200 self.shell.DeleteSlice(pointer)
202 if self.shell.GetNodes(pointer):
203 self.shell.DeleteNode(pointer)
204 elif type == 'authority':
205 if self.shell.GetSites(pointer):
206 self.shell.DeleteSite(pointer)
215 # Convert SFA fields to PLC fields for use when registering or updating
216 # registry record in the PLC database
219 def sfa_fields_to_pl_fields(self, type, hrn, sfa_record):
224 pl_record["name"] = hrn_to_pl_slicename(hrn)
225 if "instantiation" in sfa_record:
226 pl_record['instantiation']=sfa_record['instantiation']
228 pl_record["instantiation"] = "plc-instantiated"
229 if "url" in sfa_record:
230 pl_record["url"] = sfa_record["url"]
231 if "description" in sfa_record:
232 pl_record["description"] = sfa_record["description"]
233 if "expires" in sfa_record:
234 date = utcparse(sfa_record['expires'])
235 expires = datetime_to_epoch(date)
236 pl_record["expires"] = expires
239 if not "hostname" in pl_record:
240 # fetch from sfa_record
241 if "hostname" not in sfa_record:
242 raise MissingSfaInfo("hostname")
243 pl_record["hostname"] = sfa_record["hostname"]
244 if "model" in sfa_record:
245 pl_record["model"] = sfa_record["model"]
247 pl_record["model"] = "geni"
249 elif type == "authority":
250 pl_record["login_base"] = PlXrn(xrn=hrn,type='authority').pl_login_base()
251 if "name" not in sfa_record:
252 pl_record["name"] = hrn
253 if "abbreviated_name" not in sfa_record:
254 pl_record["abbreviated_name"] = hrn
255 if "enabled" not in sfa_record:
256 pl_record["enabled"] = True
257 if "is_public" not in sfa_record:
258 pl_record["is_public"] = True
263 def fill_record_info(self, records):
265 Given a (list of) SFA record, fill in the PLC specific
266 and SFA specific fields in the record.
268 if not isinstance(records, list):
271 self.fill_record_pl_info(records)
272 self.fill_record_hrns(records)
273 self.fill_record_sfa_info(records)
276 def fill_record_pl_info(self, records):
278 Fill in the planetlab specific fields of a SFA record. This
279 involves calling the appropriate PLC method to retrieve the
280 database record for the object.
282 @param record: record to fill in field (in/out param)
285 node_ids, site_ids, slice_ids = [], [], []
286 person_ids, key_ids = [], []
287 type_map = {'node': node_ids, 'authority': site_ids,
288 'slice': slice_ids, 'user': person_ids}
290 for record in records:
291 for type in type_map:
292 if type == record['type']:
293 type_map[type].append(record['pointer'])
296 nodes, sites, slices, persons, keys = {}, {}, {}, {}, {}
298 node_list = self.shell.GetNodes(node_ids)
299 nodes = list_to_dict(node_list, 'node_id')
301 site_list = self.shell.GetSites(site_ids)
302 sites = list_to_dict(site_list, 'site_id')
304 slice_list = self.shell.GetSlices(slice_ids)
305 slices = list_to_dict(slice_list, 'slice_id')
307 person_list = self.shell.GetPersons(person_ids)
308 persons = list_to_dict(person_list, 'person_id')
309 for person in persons:
310 key_ids.extend(persons[person]['key_ids'])
312 pl_records = {'node': nodes, 'authority': sites,
313 'slice': slices, 'user': persons}
316 key_list = self.shell.GetKeys(key_ids)
317 keys = list_to_dict(key_list, 'key_id')
320 for record in records:
321 # records with pointer==-1 do not have plc info.
322 # for example, the top level authority records which are
323 # authorities, but not PL "sites"
324 if record['pointer'] == -1:
327 for type in pl_records:
328 if record['type'] == type:
329 if record['pointer'] in pl_records[type]:
330 record.update(pl_records[type][record['pointer']])
333 if record['type'] == 'user':
334 if 'key_ids' not in record:
335 logger.info("user record has no 'key_ids' - need to import from myplc ?")
337 pubkeys = [keys[key_id]['key'] for key_id in record['key_ids'] if key_id in keys]
338 record['keys'] = pubkeys
342 def fill_record_hrns(self, records):
344 convert pl ids to hrns
348 slice_ids, person_ids, site_ids, node_ids = [], [], [], []
349 for record in records:
350 if 'site_id' in record:
351 site_ids.append(record['site_id'])
352 if 'site_ids' in record:
353 site_ids.extend(record['site_ids'])
354 if 'person_ids' in record:
355 person_ids.extend(record['person_ids'])
356 if 'slice_ids' in record:
357 slice_ids.extend(record['slice_ids'])
358 if 'node_ids' in record:
359 node_ids.extend(record['node_ids'])
362 slices, persons, sites, nodes = {}, {}, {}, {}
364 site_list = self.shell.GetSites(site_ids, ['site_id', 'login_base'])
365 sites = list_to_dict(site_list, 'site_id')
367 person_list = self.shell.GetPersons(person_ids, ['person_id', 'email'])
368 persons = list_to_dict(person_list, 'person_id')
370 slice_list = self.shell.GetSlices(slice_ids, ['slice_id', 'name'])
371 slices = list_to_dict(slice_list, 'slice_id')
373 node_list = self.shell.GetNodes(node_ids, ['node_id', 'hostname'])
374 nodes = list_to_dict(node_list, 'node_id')
376 # convert ids to hrns
377 for record in records:
378 # get all relevant data
379 type = record['type']
380 pointer = record['pointer']
386 if 'site_id' in record:
387 site = sites[record['site_id']]
388 login_base = site['login_base']
389 record['site'] = ".".join([auth_hrn, login_base])
390 if 'person_ids' in record:
391 emails = [persons[person_id]['email'] for person_id in record['person_ids'] \
392 if person_id in persons]
393 usernames = [email.split('@')[0] for email in emails]
394 person_hrns = [".".join([auth_hrn, login_base, username]) for username in usernames]
395 record['persons'] = person_hrns
396 if 'slice_ids' in record:
397 slicenames = [slices[slice_id]['name'] for slice_id in record['slice_ids'] \
398 if slice_id in slices]
399 slice_hrns = [slicename_to_hrn(auth_hrn, slicename) for slicename in slicenames]
400 record['slices'] = slice_hrns
401 if 'node_ids' in record:
402 hostnames = [nodes[node_id]['hostname'] for node_id in record['node_ids'] \
404 node_hrns = [hostname_to_hrn(auth_hrn, login_base, hostname) for hostname in hostnames]
405 record['nodes'] = node_hrns
406 if 'site_ids' in record:
407 login_bases = [sites[site_id]['login_base'] for site_id in record['site_ids'] \
409 site_hrns = [".".join([auth_hrn, lbase]) for lbase in login_bases]
410 record['sites'] = site_hrns
412 if 'expires' in record:
413 date = utcparse(record['expires'])
414 datestring = datetime_to_string(date)
415 record['expires'] = datestring
419 def fill_record_sfa_info(self, records):
421 def startswith(prefix, values):
422 return [value for value in values if value.startswith(prefix)]
427 for record in records:
428 person_ids.extend(record.get("person_ids", []))
429 site_ids.extend(record.get("site_ids", []))
430 if 'site_id' in record:
431 site_ids.append(record['site_id'])
433 # get all pis from the sites we've encountered
434 # and store them in a dictionary keyed on site_id
437 pi_filter = {'|roles': ['pi'], '|site_ids': site_ids}
438 pi_list = self.shell.GetPersons(pi_filter, ['person_id', 'site_ids'])
440 # we will need the pi's hrns also
441 person_ids.append(pi['person_id'])
443 # we also need to keep track of the sites these pis
445 for site_id in pi['site_ids']:
446 if site_id in site_pis:
447 site_pis[site_id].append(pi)
449 site_pis[site_id] = [pi]
451 # get sfa records for all records associated with these records.
452 # we'll replace pl ids (person_ids) with hrns from the sfa records
455 # get the registry records
456 person_list, persons = [], {}
457 person_list = dbsession.query (RegRecord).filter(RegRecord.pointer.in_(person_ids))
458 # create a hrns keyed on the sfa record's pointer.
459 # Its possible for multiple records to have the same pointer so
460 # the dict's value will be a list of hrns.
461 persons = defaultdict(list)
462 for person in person_list:
463 persons[person.pointer].append(person)
466 pl_person_list, pl_persons = [], {}
467 pl_person_list = self.shell.GetPersons(person_ids, ['person_id', 'roles'])
468 pl_persons = list_to_dict(pl_person_list, 'person_id')
471 for record in records:
472 # skip records with no pl info (top level authorities)
473 #if record['pointer'] == -1:
476 type = record['type']
477 logger.info("fill_record_sfa_info - incoming record typed %s"%type)
478 if (type == "slice"):
479 # all slice users are researchers
480 record['geni_urn'] = hrn_to_urn(record['hrn'], 'slice')
482 record['researcher'] = []
483 for person_id in record.get('person_ids', []):
484 hrns = [person.hrn for person in persons[person_id]]
485 record['researcher'].extend(hrns)
487 # pis at the slice's site
488 if 'site_id' in record and record['site_id'] in site_pis:
489 pl_pis = site_pis[record['site_id']]
490 pi_ids = [pi['person_id'] for pi in pl_pis]
491 for person_id in pi_ids:
492 hrns = [person.hrn for person in persons[person_id]]
493 record['PI'].extend(hrns)
494 record['geni_creator'] = record['PI']
496 elif (type.startswith("authority")):
498 logger.info("fill_record_sfa_info - authority xherex")
499 if record['pointer'] != -1:
501 record['operator'] = []
503 for pointer in record.get('person_ids', []):
504 if pointer not in persons or pointer not in pl_persons:
505 # this means there is not sfa or pl record for this user
507 hrns = [person.hrn for person in persons[pointer]]
508 roles = pl_persons[pointer]['roles']
510 record['PI'].extend(hrns)
512 record['operator'].extend(hrns)
514 record['owner'].extend(hrns)
515 # xxx TODO: OrganizationName
516 elif (type == "node"):
517 sfa_info['dns'] = record.get("hostname", "")
518 # xxx TODO: URI, LatLong, IP, DNS
520 elif (type == "user"):
521 logger.info('setting user.email')
522 sfa_info['email'] = record.get("email", "")
523 sfa_info['geni_urn'] = hrn_to_urn(record['hrn'], 'user')
524 sfa_info['geni_certificate'] = record['gid']
525 # xxx TODO: PostalAddress, Phone
526 record.update(sfa_info)
530 # plcapi works by changes, compute what needs to be added/deleted
531 def update_relation (self, subject_type, target_type, relation_name, subject_id, target_ids):
532 # hard-wire the code for slice/user for now, could be smarter if needed
533 if subject_type =='slice' and target_type == 'user' and relation_name == 'researcher':
534 subject=self.shell.GetSlices (subject_id)[0]
535 current_target_ids = subject['person_ids']
536 add_target_ids = list ( set (target_ids).difference(current_target_ids))
537 del_target_ids = list ( set (current_target_ids).difference(target_ids))
538 logger.debug ("subject_id = %s (type=%s)"%(subject_id,type(subject_id)))
539 for target_id in add_target_ids:
540 self.shell.AddPersonToSlice (target_id,subject_id)
541 logger.debug ("add_target_id = %s (type=%s)"%(target_id,type(target_id)))
542 for target_id in del_target_ids:
543 logger.debug ("del_target_id = %s (type=%s)"%(target_id,type(target_id)))
544 self.shell.DeletePersonFromSlice (target_id, subject_id)
545 elif subject_type == 'authority' and target_type == 'user' and relation_name == 'pi':
546 # due to the plcapi limitations this means essentially adding pi role to all people in the list
547 # it's tricky to remove any pi role here, although it might be desirable
548 persons = self.shell.GetPersons (target_ids)
549 for person in persons:
550 if 'pi' not in person['roles']:
551 self.shell.AddRoleToPerson('pi',person['person_id'])
553 logger.info('unexpected relation %s to maintain, %s -> %s'%(relation_name,subject_type,target_type))
556 ########################################
557 ########## aggregate oriented
558 ########################################
560 def testbed_name (self): return "myplc"
562 # 'geni_request_rspec_versions' and 'geni_ad_rspec_versions' are mandatory
563 def aggregate_version (self):
564 version_manager = VersionManager()
565 ad_rspec_versions = []
566 request_rspec_versions = []
567 for rspec_version in version_manager.versions:
568 if rspec_version.content_type in ['*', 'ad']:
569 ad_rspec_versions.append(rspec_version.to_dict())
570 if rspec_version.content_type in ['*', 'request']:
571 request_rspec_versions.append(rspec_version.to_dict())
573 'testbed':self.testbed_name(),
574 'geni_request_rspec_versions': request_rspec_versions,
575 'geni_ad_rspec_versions': ad_rspec_versions,
578 def list_slices (self, creds, options):
579 # look in cache first
581 slices = self.cache.get('slices')
583 logger.debug("PlDriver.list_slices returns from cache")
587 slices = self.shell.GetSlices({'peer_id': None}, ['name'])
588 slice_hrns = [slicename_to_hrn(self.hrn, slice['name']) for slice in slices]
589 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
593 logger.debug ("PlDriver.list_slices stores value in cache")
594 self.cache.add('slices', slice_urns)
598 # first 2 args are None in case of resource discovery
599 def list_resources (self, slice_urn, slice_hrn, creds, options):
600 cached_requested = options.get('cached', True)
602 version_manager = VersionManager()
603 # get the rspec's return format from options
604 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
605 version_string = "rspec_%s" % (rspec_version)
607 #panos adding the info option to the caching key (can be improved)
608 if options.get('info'):
609 version_string = version_string + "_"+options.get('info', 'default')
611 # look in cache first
612 if cached_requested and self.cache and not slice_hrn:
613 rspec = self.cache.get(version_string)
615 logger.debug("PlDriver.ListResources: returning cached advertisement")
618 #panos: passing user-defined options
619 #print "manager options = ",options
620 aggregate = PlAggregate(self)
621 rspec = aggregate.get_rspec(slice_xrn=slice_urn, version=rspec_version,
625 if self.cache and not slice_hrn:
626 logger.debug("PlDriver.ListResources: stores advertisement in cache")
627 self.cache.add(version_string, rspec)
631 def sliver_status (self, slice_urn, slice_hrn):
632 # find out where this slice is currently running
633 slicename = hrn_to_pl_slicename(slice_hrn)
635 slices = self.shell.GetSlices([slicename], ['slice_id', 'node_ids','person_ids','name','expires'])
637 raise SliverDoesNotExist("%s (used %s as slicename internally)" % (slice_hrn, slicename))
640 # report about the local nodes only
641 nodes = self.shell.GetNodes({'node_id':slice['node_ids'],'peer_id':None},
642 ['node_id', 'hostname', 'site_id', 'boot_state', 'last_contact'])
645 raise SliverDoesNotExist("You have not allocated any slivers here")
649 if slice['person_ids']:
650 persons = self.shell.GetPersons(slice['person_ids'], ['key_ids'])
651 key_ids = [key_id for person in persons for key_id in person['key_ids']]
652 person_keys = self.shell.GetKeys(key_ids)
653 keys = [key['key'] for key in keys]
655 user.update({'urn': slice_urn,
656 'login': slice['name'],
661 site_ids = [node['site_id'] for node in nodes]
664 top_level_status = 'unknown'
666 top_level_status = 'ready'
667 result['geni_urn'] = slice_urn
668 result['pl_login'] = slice['name']
669 result['pl_expires'] = datetime_to_string(utcparse(slice['expires']))
670 result['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
675 res['pl_hostname'] = node['hostname']
676 res['pl_boot_state'] = node['boot_state']
677 res['pl_last_contact'] = node['last_contact']
678 res['geni_expires'] = datetime_to_string(utcparse(slice['expires']))
679 if node['last_contact'] is not None:
681 res['pl_last_contact'] = datetime_to_string(utcparse(node['last_contact']))
682 sliver_id = urn_to_sliver_id(slice_urn, slice['slice_id'], node['node_id'], authority=self.hrn)
683 res['geni_urn'] = sliver_id
684 if node['boot_state'] == 'boot':
685 res['geni_status'] = 'ready'
687 res['geni_status'] = 'failed'
688 top_level_status = 'failed'
690 res['geni_error'] = ''
691 res['users'] = [user]
693 resources.append(res)
695 result['geni_status'] = top_level_status
696 result['geni_resources'] = resources
699 def create_sliver (self, slice_urn, slice_hrn, creds, rspec_string, users, options):
701 aggregate = PlAggregate(self)
702 slices = PlSlices(self)
703 peer = slices.get_peer(slice_hrn)
704 sfa_peer = slices.get_sfa_peer(slice_hrn)
707 slice_record = users[0].get('slice_record', {})
710 rspec = RSpec(rspec_string)
711 requested_attributes = rspec.version.get_slice_attributes()
713 # ensure site record exists
714 site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer, options=options)
715 # ensure slice record exists
716 slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer, options=options)
717 # ensure person records exists
718 persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer, options=options)
719 # ensure slice attributes exists
720 slices.verify_slice_attributes(slice, requested_attributes, options=options)
722 # add/remove slice from nodes
723 requested_slivers = []
724 for node in rspec.version.get_nodes_with_slivers():
726 if node.get('component_name'):
727 hostname = node.get('component_name').strip()
728 elif node.get('component_id'):
729 hostname = xrn_to_hostname(node.get('component_id').strip())
731 requested_slivers.append(hostname)
732 nodes = slices.verify_slice_nodes(slice, requested_slivers, peer)
734 # add/remove links links
735 slices.verify_slice_links(slice, rspec.version.get_link_requests(), nodes)
737 # handle MyPLC peer association.
738 # only used by plc and ple.
739 slices.handle_peer(site, slice, persons, peer)
741 return aggregate.get_rspec(slice_xrn=slice_urn, version=rspec.version)
743 def delete_sliver (self, slice_urn, slice_hrn, creds, options):
744 slicename = hrn_to_pl_slicename(slice_hrn)
745 slices = self.shell.GetSlices({'name': slicename})
750 # determine if this is a peer slice
751 # xxx I wonder if this would not need to use PlSlices.get_peer instead
752 # in which case plc.peers could be deprecated as this here
753 # is the only/last call to this last method in plc.peers
754 peer = peers.get_peer(self, slice_hrn)
757 self.shell.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
758 self.shell.DeleteSliceFromNodes(slicename, slice['node_ids'])
761 self.shell.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
764 def renew_sliver (self, slice_urn, slice_hrn, creds, expiration_time, options):
765 slicename = hrn_to_pl_slicename(slice_hrn)
766 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
768 raise RecordNotFound(slice_hrn)
770 requested_time = utcparse(expiration_time)
771 record = {'expires': int(datetime_to_epoch(requested_time))}
773 self.shell.UpdateSlice(slice['slice_id'], record)
778 # remove the 'enabled' tag
779 def start_slice (self, slice_urn, slice_hrn, creds):
780 slicename = hrn_to_pl_slicename(slice_hrn)
781 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
783 raise RecordNotFound(slice_hrn)
784 slice_id = slices[0]['slice_id']
785 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
786 # just remove the tag if it exists
788 self.shell.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
791 # set the 'enabled' tag to 0
792 def stop_slice (self, slice_urn, slice_hrn, creds):
793 slicename = hrn_to_pl_slicename(slice_hrn)
794 slices = self.shell.GetSlices({'name': slicename}, ['slice_id'])
796 raise RecordNotFound(slice_hrn)
797 slice_id = slices[0]['slice_id']
798 slice_tags = self.shell.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
800 self.shell.AddSliceTag(slice_id, 'enabled', '0')
801 elif slice_tags[0]['value'] != "0":
802 tag_id = slice_tags[0]['slice_tag_id']
803 self.shell.UpdateSliceTag(tag_id, '0')
806 def reset_slice (self, slice_urn, slice_hrn, creds):
807 raise SfaNotImplemented ("reset_slice not available at this interface")
809 # xxx this code is quite old and has not run for ages
810 # it is obviously totally broken and needs a rewrite
811 def get_ticket (self, slice_urn, slice_hrn, creds, rspec_string, options):
812 raise SfaNotImplemented,"PlDriver.get_ticket needs a rewrite"
813 # please keep this code for future reference
814 # slices = PlSlices(self)
815 # peer = slices.get_peer(slice_hrn)
816 # sfa_peer = slices.get_sfa_peer(slice_hrn)
818 # # get the slice record
819 # credential = api.getCredential()
820 # interface = api.registries[api.hrn]
821 # registry = api.server_proxy(interface, credential)
822 # records = registry.Resolve(xrn, credential)
824 # # make sure we get a local slice record
826 # for tmp_record in records:
827 # if tmp_record['type'] == 'slice' and \
828 # not tmp_record['peer_authority']:
829 # #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
830 # slice_record = SliceRecord(dict=tmp_record)
832 # raise RecordNotFound(slice_hrn)
834 # # similar to CreateSliver, we must verify that the required records exist
835 # # at this aggregate before we can issue a ticket
837 # rspec = RSpec(rspec_string)
838 # requested_attributes = rspec.version.get_slice_attributes()
840 # # ensure site record exists
841 # site = slices.verify_site(slice_hrn, slice_record, peer, sfa_peer)
842 # # ensure slice record exists
843 # slice = slices.verify_slice(slice_hrn, slice_record, peer, sfa_peer)
844 # # ensure person records exists
845 # # xxx users is undefined in this context
846 # persons = slices.verify_persons(slice_hrn, slice, users, peer, sfa_peer)
847 # # ensure slice attributes exists
848 # slices.verify_slice_attributes(slice, requested_attributes)
851 # slivers = slices.get_slivers(slice_hrn)
854 # raise SliverDoesNotExist(slice_hrn)
859 # 'timestamp': int(time.time()),
860 # 'initscripts': initscripts,
864 # # create the ticket
865 # object_gid = record.get_gid_object()
866 # new_ticket = SfaTicket(subject = object_gid.get_subject())
867 # new_ticket.set_gid_caller(api.auth.client_gid)
868 # new_ticket.set_gid_object(object_gid)
869 # new_ticket.set_issuer(key=api.key, subject=self.hrn)
870 # new_ticket.set_pubkey(object_gid.get_pubkey())
871 # new_ticket.set_attributes(data)
872 # new_ticket.set_rspec(rspec)
873 # #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
874 # new_ticket.encode()
877 # return new_ticket.save_to_string(save_parents=True)