9 from types import StringTypes
10 from sfa.util.misc import *
11 from sfa.util.rspec import *
12 from sfa.util.specdict import *
13 from sfa.util.faults import *
14 from sfa.util.storage import *
15 from sfa.util.record import GeniRecord
16 from sfa.util.policy import Policy
17 from sfa.util.prefixTree import prefixTree
18 from sfa.util.debug import log
19 from sfa.server.aggregate import Aggregates
20 from sfa.server.registry import Registries
24 class Slices(SimpleStorage):
26 rspec_to_slice_tag = {'max_rate':'net_max_rate'}
28 def __init__(self, api, ttl = .5, caller_cred=None):
32 path = self.api.config.SFA_DATA_DIR
33 filename = ".".join([self.api.interface, self.api.hrn, "slices"])
34 filepath = path + os.sep + filename
35 self.slices_file = filepath
36 SimpleStorage.__init__(self, self.slices_file)
37 self.policy = Policy(self.api)
39 self.caller_cred=caller_cred
41 def get_slivers(self, hrn, node=None):
43 slice_name = hrn_to_pl_slicename(hrn)
44 # XX Should we just call PLCAPI.GetSliceTicket(slice_name) instead
45 # of doing all of this?
46 #return self.api.GetSliceTicket(self.auth, slice_name)
48 # from PLCAPI.GetSlivers.get_slivers()
49 slice_fields = ['slice_id', 'name', 'instantiation', 'expires', 'person_ids', 'slice_tag_ids']
50 slices = self.api.plshell.GetSlices(self.api.plauth, slice_name, slice_fields)
51 # Build up list of users and slice attributes
53 all_slice_tag_ids = set()
55 person_ids.update(slice['person_ids'])
56 all_slice_tag_ids.update(slice['slice_tag_ids'])
57 person_ids = list(person_ids)
58 all_slice_tag_ids = list(all_slice_tag_ids)
59 # Get user information
60 all_persons_list = self.api.plshell.GetPersons(self.api.plauth, {'person_id':person_ids,'enabled':True}, ['person_id', 'enabled', 'key_ids'])
62 for person in all_persons_list:
63 all_persons[person['person_id']] = person
65 # Build up list of keys
67 for person in all_persons.values():
68 key_ids.update(person['key_ids'])
69 key_ids = list(key_ids)
70 # Get user account keys
71 all_keys_list = self.api.plshell.GetKeys(self.api.plauth, key_ids, ['key_id', 'key', 'key_type'])
73 for key in all_keys_list:
74 all_keys[key['key_id']] = key
75 # Get slice attributes
76 all_slice_tags_list = self.api.plshell.GetSliceTags(self.api.plauth, all_slice_tag_ids)
78 for slice_tag in all_slice_tags_list:
79 all_slice_tags[slice_tag['slice_tag_id']] = slice_tag
84 for person_id in slice['person_ids']:
85 if person_id in all_persons:
86 person = all_persons[person_id]
87 if not person['enabled']:
89 for key_id in person['key_ids']:
90 if key_id in all_keys:
91 key = all_keys[key_id]
92 keys += [{'key_type': key['key_type'],
95 # All (per-node and global) attributes for this slice
97 for slice_tag_id in slice['slice_tag_ids']:
98 if slice_tag_id in all_slice_tags:
99 slice_tags.append(all_slice_tags[slice_tag_id])
100 # Per-node sliver attributes take precedence over global
101 # slice attributes, so set them first.
102 # Then comes nodegroup slice attributes
103 # Followed by global slice attributes
104 sliver_attributes = []
107 for sliver_attribute in filter(lambda a: a['node_id'] == node['node_id'], slice_tags):
108 sliver_attributes.append(sliver_attribute['tagname'])
109 attributes.append({'tagname': sliver_attribute['tagname'],
110 'value': sliver_attribute['value']})
112 # set nodegroup slice attributes
113 for slice_tag in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_tags):
114 # Do not set any nodegroup slice attributes for
115 # which there is at least one sliver attribute
117 if slice_tag not in slice_tags:
118 attributes.append({'tagname': slice_tag['tagname'],
119 'value': slice_tag['value']})
121 for slice_tag in filter(lambda a: a['node_id'] is None, slice_tags):
122 # Do not set any global slice attributes for
123 # which there is at least one sliver attribute
125 if slice_tag['tagname'] not in sliver_attributes:
126 attributes.append({'tagname': slice_tag['tagname'],
127 'value': slice_tag['value']})
129 # XXX Sanity check; though technically this should be a system invariant
130 # checked with an assertion
131 if slice['expires'] > MAXINT: slice['expires']= MAXINT
135 'name': slice['name'],
136 'slice_id': slice['slice_id'],
137 'instantiation': slice['instantiation'],
138 'expires': slice['expires'],
140 'attributes': attributes
145 def get_peer(self, hrn):
146 # Becaues of myplc federation, we first need to determine if this
147 # slice belongs to out local plc or a myplc peer. We will assume it
148 # is a local site, unless we find out otherwise
151 # get this slice's authority (site)
152 slice_authority = get_authority(hrn)
154 # get this site's authority (sfa root authority or sub authority)
155 site_authority = get_authority(slice_authority).lower()
157 # check if we are already peered with this site_authority, if so
158 peers = self.api.plshell.GetPeers(self.api.plauth, {}, ['peer_id', 'peername', 'shortname', 'hrn_root'])
159 for peer_record in peers:
160 names = [name.lower() for name in peer_record.values() if isinstance(name, StringTypes)]
161 if site_authority in names:
162 peer = peer_record['shortname']
166 def get_sfa_peer(self, hrn):
167 # return the authority for this hrn or None if we are the authority
169 slice_authority = get_authority(hrn)
170 site_authority = get_authority(slice_authority)
172 if site_authority != self.api.hrn:
173 sfa_peer = site_authority
179 Update the cached list of slices
181 # Reload components list
182 now = datetime.datetime.now()
183 if not self.has_key('threshold') or not self.has_key('timestamp') or \
184 now > datetime.datetime.fromtimestamp(time.mktime(time.strptime(self['threshold'], self.api.time_format))):
185 if self.api.interface in ['aggregate']:
186 self.refresh_slices_aggregate()
187 elif self.api.interface in ['slicemgr']:
188 self.refresh_slices_smgr()
190 def refresh_slices_aggregate(self):
191 slices = self.api.plshell.GetSlices(self.api.plauth, {'peer_id': None}, ['name'])
192 slice_hrns = [slicename_to_hrn(self.api.hrn, slice['name']) for slice in slices]
194 # update timestamp and threshold
195 timestamp = datetime.datetime.now()
196 hr_timestamp = timestamp.strftime(self.api.time_format)
197 delta = datetime.timedelta(hours=self.ttl)
198 threshold = timestamp + delta
199 hr_threshold = threshold.strftime(self.api.time_format)
201 slice_details = {'hrn': slice_hrns,
202 'timestamp': hr_timestamp,
203 'threshold': hr_threshold
205 self.update(slice_details)
209 def refresh_slices_smgr(self):
211 aggregates = Aggregates(self.api)
212 credential = self.api.getCredential()
213 for aggregate in aggregates:
215 # request hash is optional so lets try the call without it
217 slices = aggregates[aggregate].get_slices(credential)
218 slice_hrns.extend(slices)
221 print >> log, "%s" % (traceback.format_exc())
222 print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
224 # try sending the request hash if the previous call failed
226 arg_list = [credential]
227 request_hash = self.api.key.compute_hash(arg_list)
229 slices = aggregates[aggregate].get_slices(credential, request_hash)
230 slice_hrns.extend(slices)
233 print >> log, "%s" % (traceback.format_exc())
234 print >> log, "Error calling slices at aggregate %(aggregate)s" % locals()
236 # update timestamp and threshold
237 timestamp = datetime.datetime.now()
238 hr_timestamp = timestamp.strftime(self.api.time_format)
239 delta = datetime.timedelta(hours=self.ttl)
240 threshold = timestamp + delta
241 hr_threshold = threshold.strftime(self.api.time_format)
243 slice_details = {'hrn': slice_hrns,
244 'timestamp': hr_timestamp,
245 'threshold': hr_threshold
247 self.update(slice_details)
251 def delete_slice(self, hrn):
252 if self.api.interface in ['aggregate']:
253 self.delete_slice_aggregate(hrn)
254 elif self.api.interface in ['slicemgr']:
255 self.delete_slice_smgr(hrn)
257 def delete_slice_aggregate(self, hrn):
259 slicename = hrn_to_pl_slicename(hrn)
260 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename})
265 # determine if this is a peer slice
266 peer = self.get_peer(hrn)
268 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', slice['slice_id'], peer)
269 self.api.plshell.DeleteSliceFromNodes(self.api.plauth, slicename, slice['node_ids'])
271 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
274 def delete_slice_smgr(self, hrn):
275 credential = self.api.getCredential()
276 caller_cred = self.caller_cred
277 aggregates = Aggregates(self.api)
278 for aggregate in aggregates:
280 # request hash is optional so lets try the call without it
283 aggregates[aggregate].delete_slice(credential, hrn, request_hash, caller_cred)
286 print >> log, "%s" % (traceback.format_exc())
287 print >> log, "Error calling list nodes at aggregate %s" % aggregate
289 # try sending the request hash if the previous call failed
292 arg_list = [credential, hrn]
293 request_hash = self.api.key.compute_hash(arg_list)
294 aggregates[aggregate].delete_slice(credential, hrn, request_hash, caller_cred)
297 print >> log, "%s" % (traceback.format_exc())
298 print >> log, "Error calling list nodes at aggregate %s" % aggregate
300 def create_slice(self, hrn, rspec):
302 # check our slice policy before we procede
303 whitelist = self.policy['slice_whitelist']
304 blacklist = self.policy['slice_blacklist']
306 if whitelist and hrn not in whitelist or \
307 blacklist and hrn in blacklist:
308 policy_file = self.policy.policy_file
309 print >> log, "Slice %(hrn)s not allowed by policy %(policy_file)s" % locals()
312 if self.api.interface in ['aggregate']:
313 self.create_slice_aggregate(hrn, rspec)
314 elif self.api.interface in ['slicemgr']:
315 self.create_slice_smgr(hrn, rspec)
317 def verify_site(self, registry, credential, slice_hrn, peer, sfa_peer):
318 authority = get_authority(slice_hrn)
320 site_records = registry.resolve(credential, authority)
322 arg_list = [credential, authority]
323 request_hash = self.api.key.compute_hash(arg_list)
324 site_records = registry.resolve(credential, authority, request_hash)
327 for site_record in site_records:
328 if site_record['type'] == 'authority':
331 raise RecordNotFound(authority)
332 remote_site_id = site.pop('site_id')
334 login_base = get_leaf(authority)
335 sites = self.api.plshell.GetSites(self.api.plauth, login_base)
337 site_id = self.api.plshell.AddSite(self.api.plauth, site)
339 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)
340 # mark this site as an sfa peer record
342 peer_dict = {'type': 'authority', 'hrn': authority, 'peer_authority': sfa_peer, 'pointer': site_id}
344 registry.register_peer_object(credential, peer_dict)
346 arg_list = [credential]
347 request_hash = self.api.key.compute_hash(arg_list)
348 registry.register_peer_object(credential, peer_dict, request_hash)
350 site_id = sites[0]['site_id']
351 remote_site_id = sites[0]['peer_site_id']
354 return (site_id, remote_site_id)
356 def verify_slice(self, registry, credential, slice_hrn, site_id, remote_site_id, peer, sfa_peer):
359 authority = get_authority(slice_hrn)
361 slice_records = registry.resolve(credential, slice_hrn)
363 arg_list = [credential, slice_hrn]
364 request_hash = self.api.key.compute_hash(arg_list)
365 slice_records = registry.resolve(credential, slice_hrn, request_hash)
367 for record in slice_records:
368 if record['type'] in ['slice']:
369 slice_record = record
371 raise RecordNotFound(hrn)
372 slicename = hrn_to_pl_slicename(slice_hrn)
373 parts = slicename.split("_")
374 login_base = parts[0]
375 slices = self.api.plshell.GetSlices(self.api.plauth, [slicename], ['slice_id', 'node_ids', 'site_id'])
378 slice_keys = ['name', 'url', 'description']
379 for key in slice_keys:
380 if key in slice_record and slice_record[key]:
381 slice_fields[key] = slice_record[key]
384 slice_id = self.api.plshell.AddSlice(self.api.plauth, slice_fields)
386 slice['slice_id'] = slice_id
388 # mark this slice as an sfa peer record
390 peer_dict = {'type': 'slice', 'hrn': slice_hrn, 'peer_authority': sfa_peer, 'pointer': slice_id}
392 registry.register_peer_object(credential, peer_dict)
394 arg_list = [credential]
395 request_hash = self.api.key.compute_hash(arg_list)
396 registry.register_peer_object(credential, peer_dict, request_hash)
398 #this belongs to a peer
400 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice_id, peer, slice_record['pointer'])
401 slice['node_ids'] = []
404 slice_id = slice['slice_id']
405 site_id = slice['site_id']
407 slice['peer_slice_id'] = slice_record['pointer']
408 self.verify_persons(registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer)
412 def verify_persons(self, registry, credential, slice_record, site_id, remote_site_id, peer, sfa_peer):
413 # get the list of valid slice users from the registry and make
414 # sure they are added to the slice
415 slicename = hrn_to_pl_slicename(slice_record['hrn'])
416 researchers = slice_record.get('researcher', [])
417 for researcher in researchers:
420 person_records = registry.resolve(credential, researcher)
422 arg_list = [credential, researcher]
423 request_hash = self.api.key.compute_hash(arg_list)
424 person_records = registry.resolve(credential, researcher, request_hash)
425 for record in person_records:
426 if record['type'] in ['user']:
427 person_record = record
428 if not person_record:
430 person_dict = person_record
433 peer_id = self.api.plshell.GetPeers(self.api.plauth, {'shortname': peer}, ['peer_id'])[0]['peer_id']
434 persons = self.api.plshell.GetPersons(self.api.plauth, {'email': [person_dict['email']], 'peer_id': peer_id}, ['person_id', 'key_ids'])
436 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
441 persons = self.api.plshell.GetPersons(self.api.plauth, [person_dict['email']], ['person_id', 'key_ids'])
444 person_id=self.api.plshell.AddPerson(self.api.plauth, person_dict)
445 self.api.plshell.UpdatePerson(self.api.plauth, person_id, {'enabled' : True})
447 # mark this person as an sfa peer record
449 peer_dict = {'type': 'user', 'hrn': researcher, 'peer_authority': sfa_peer, 'pointer': person_id}
451 registry.register_peer_object(credential, peer_dict)
453 arg_list = [credential]
454 request_hash = self.api.key.compute_hash(arg_list)
455 registry.register_peer_object(credential, peer_dict, request_hash)
458 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
461 person_id = persons[0]['person_id']
462 key_ids = persons[0]['key_ids']
465 # if this is a peer person, we must unbind them from the peer or PLCAPI will throw
468 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'person', person_id, peer)
469 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'site', site_id, peer)
471 self.api.plshell.AddPersonToSlice(self.api.plauth, person_dict['email'], slicename)
472 self.api.plshell.AddPersonToSite(self.api.plauth, person_dict['email'], site_id)
473 if peer and not local_person:
474 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
476 self.api.plshell.BindObjectToPeer(self.api.plauth, 'site', site_id, peer, remote_site_id)
478 self.verify_keys(registry, credential, person_dict, key_ids, person_id, peer, local_person)
480 def verify_keys(self, registry, credential, person_dict, key_ids, person_id, peer, local_person):
481 keylist = self.api.plshell.GetKeys(self.api.plauth, key_ids, ['key'])
482 keys = [key['key'] for key in keylist]
484 #add keys that arent already there
485 key_ids = person_dict['key_ids']
486 for personkey in person_dict['keys']:
487 if personkey not in keys:
488 key = {'key_type': 'ssh', 'key': personkey}
490 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'person', person_id, peer)
491 key_id = self.api.plshell.AddPersonKey(self.api.plauth, person_dict['email'], key)
492 if peer and not local_person:
493 self.api.plshell.BindObjectToPeer(self.api.plauth, 'person', person_id, peer, person_dict['pointer'])
495 try: self.api.plshell.BindObjectToPeer(self.api.plauth, 'key', key_id, peer, key_ids.pop(0))
499 def create_slice_aggregate(self, hrn, rspec):
501 # Determine if this is a peer slice
502 peer = self.get_peer(hrn)
503 sfa_peer = self.get_sfa_peer(hrn)
506 # Get the slice record from sfa
507 slicename = hrn_to_pl_slicename(hrn)
510 registries = Registries(self.api)
511 registry = registries[self.api.hrn]
512 credential = self.api.getCredential()
514 site_id, remote_site_id = self.verify_site(registry, credential, hrn, peer, sfa_peer)
515 slice = self.verify_slice(registry, credential, hrn, site_id, remote_site_id, peer, sfa_peer)
517 # find out where this slice is currently running
518 nodelist = self.api.plshell.GetNodes(self.api.plauth, slice['node_ids'], ['hostname'])
519 hostnames = [node['hostname'] for node in nodelist]
521 # get netspec details
522 nodespecs = spec.getDictsByTagName('NodeSpec')
524 # dict in which to store slice attributes to set for the nodes
526 for nodespec in nodespecs:
527 if isinstance(nodespec['name'], list):
528 for nodename in nodespec['name']:
530 for k in nodespec.keys():
531 rspec_attribute_value = nodespec[k]
532 if (self.rspec_to_slice_tag.has_key(k)):
533 slice_tag_name = self.rspec_to_slice_tag[k]
534 nodes[nodename][slice_tag_name] = rspec_attribute_value
535 elif isinstance(nodespec['name'], StringTypes):
536 nodename = nodespec['name']
538 for k in nodespec.keys():
539 rspec_attribute_value = nodespec[k]
540 if (self.rspec_to_slice_tag.has_key(k)):
541 slice_tag_name = self.rspec_to_slice_tag[k]
542 nodes[nodename][slice_tag_name] = rspec_attribute_value
544 for k in nodespec.keys():
545 rspec_attribute_value = nodespec[k]
546 if (self.rspec_to_slice_tag.has_key(k)):
547 slice_tag_name = self.rspec_to_slice_tag[k]
548 nodes[nodename][slice_tag_name] = rspec_attribute_value
550 node_names = nodes.keys()
551 # remove nodes not in rspec
552 deleted_nodes = list(set(hostnames).difference(node_names))
553 # add nodes from rspec
554 added_nodes = list(set(node_names).difference(hostnames))
557 self.api.plshell.UnBindObjectFromPeer(self.api.plauth, 'slice', slice['slice_id'], peer)
559 self.api.plshell.AddSliceToNodes(self.api.plauth, slicename, added_nodes)
561 # Add recognized slice tags
562 for node_name in node_names:
563 node = nodes[node_name]
564 for slice_tag in node.keys():
565 value = node[slice_tag]
566 if (isinstance(value, list)):
569 self.api.plshell.AddSliceTag(self.api.plauth, slicename, slice_tag, value, node_name)
571 self.api.plshell.DeleteSliceFromNodes(self.api.plauth, slicename, deleted_nodes)
573 self.api.plshell.BindObjectToPeer(self.api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
577 def create_slice_smgr(self, hrn, rspec):
580 spec.parseString(rspec)
581 slicename = hrn_to_pl_slicename(hrn)
582 specDict = spec.toDict()
583 if specDict.has_key('RSpec'): specDict = specDict['RSpec']
584 if specDict.has_key('start_time'): start_time = specDict['start_time']
586 if specDict.has_key('end_time'): end_time = specDict['end_time']
590 aggregates = Aggregates(self.api)
591 credential = self.api.getCredential()
593 # split the netspecs into individual rspecs
594 netspecs = spec.getDictsByTagName('NetSpec')
595 for netspec in netspecs:
596 net_hrn = netspec['name']
597 resources = {'start_time': start_time, 'end_time': end_time, 'networks': netspec}
598 resourceDict = {'RSpec': resources}
599 tempspec.parseDict(resourceDict)
600 rspecs[net_hrn] = tempspec.toxml()
602 # send each rspec to the appropriate aggregate/sm
603 caller_cred = self.caller_cred
604 for net_hrn in rspecs:
606 # if we are directly connected to the aggregate then we can just send them the rspec
607 # if not, then we may be connected to an sm thats connected to the aggregate
608 if net_hrn in aggregates:
609 # send the whloe rspec to the local aggregate
610 if net_hrn in [self.api.hrn]:
613 aggregates[net_hrn].create_slice(credential, hrn, rspec, request_hash, caller_cred)
615 arg_list = [credential,hrn,rspec]
616 request_hash = self.api.key.compute_hash(arg_list)
617 aggregates[net_hrn].create_slice(credential, hrn, rspec, request_hash, caller_cred)
621 aggregates[net_hrn].create_slice(credential, hrn, rspecs[net_hrn], request_hash, caller_cred)
623 arg_list = [credential,hrn,rspecs[net_hrn]]
624 request_hash = self.api.key.compute_hash(arg_list)
625 aggregates[net_hrn].create_slice(credential, hrn, rspecs[net_hrn], request_hash, caller_cred)
627 # lets forward this rspec to a sm that knows about the network
628 arg_list = [credential, net_hrn]
629 request_hash = self.api.compute_hash(arg_list)
630 for aggregate in aggregates:
632 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn)
634 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn, request_hash)
638 aggregates[aggregate].create_slice(credential, hrn, rspecs[net_hrn], request_hash, caller_cred)
640 arg_list = [credential, hrn, rspecs[net_hrn]]
641 request_hash = self.api.key.compute_hash(arg_list)
642 aggregates[aggregate].create_slice(credential, hrn, rspecs[net_hrn], request_hash, caller_cred)
645 print >> log, "Error creating slice %(hrn)s at aggregate %(net_hrn)s" % locals()
646 traceback.print_exc()
650 def start_slice(self, hrn):
651 if self.api.interface in ['aggregate']:
652 self.start_slice_aggregate(hrn)
653 elif self.api.interface in ['slicemgr']:
654 self.start_slice_smgr(hrn)
656 def start_slice_aggregate(self, hrn):
657 slicename = hrn_to_pl_slicename(hrn)
658 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename}, ['slice_id'])
660 raise RecordNotFound(hrn)
662 attributes = self.api.plshell.GetSliceAttributes(self.api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
663 attribute_id = attreibutes[0]['slice_attribute_id']
664 self.api.plshell.UpdateSliceAttribute(self.api.plauth, attribute_id, "1" )
667 def start_slice_smgr(self, hrn):
668 credential = self.api.getCredential()
669 aggregates = Aggregates(self.api)
670 for aggregate in aggregates:
671 aggregates[aggregate].start_slice(credential, hrn)
675 def stop_slice(self, hrn):
676 if self.api.interface in ['aggregate']:
677 self.stop_slice_aggregate(hrn)
678 elif self.api.interface in ['slicemgr']:
679 self.stop_slice_smgr(hrn)
681 def stop_slice_aggregate(self, hrn):
682 slicename = hrn_to_pl_slicename(hrn)
683 slices = self.api.plshell.GetSlices(self.api.plauth, {'name': slicename}, ['slice_id'])
685 raise RecordNotFound(hrn)
686 slice_id = slices[0]['slice_id']
687 attributes = self.api.plshell.GetSliceAttributes(self.api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
688 attribute_id = attributes[0]['slice_attribute_id']
689 self.api.plshell.UpdateSliceAttribute(self.api.plauth, attribute_id, "0")
692 def stop_slice_smgr(self, hrn):
693 credential = self.api.getCredential()
694 aggregates = Aggregates(self.api)
695 arg_list = [credential, hrn]
696 request_hash = self.api.key.compute_hash(arg_list)
697 for aggregate in aggregates:
699 aggregates[aggregate].stop_slice(credential, hrn)
701 aggregates[aggregate].stop_slice(credential, hrn, request_hash)