1 ### $Id: slices.py 15842 2009-11-22 09:56:13Z anil $
2 ### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/plc/slices.py $
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.record import GeniRecord
15 from sfa.util.policy import Policy
16 from sfa.util.prefixTree import prefixTree
17 from sfa.util.rspec import *
18 from sfa.util.sfaticket import *
19 from sfa.util.debug import log
20 from sfa.server.registry import Registries
21 from sfa.server.aggregate import Aggregates
22 import sfa.plc.peers as peers
24 def delete_slice(api, hrn, gid_origin_caller=None):
25 credential = api.getCredential()
26 credential.set_gid_origin_caller(gid_origin_caller)
27 aggregates = Aggregates(api)
28 for aggregate in aggregates:
30 # request hash is optional so lets try the call without it
33 aggregates[aggregate].delete_slice(credential, hrn, request_hash, origin_hrn)
36 print >> log, "%s" % (traceback.format_exc())
37 print >> log, "Error calling delete slice at aggregate %s" % aggregate
39 # try sending the request hash if the previous call failed
42 arg_list = [credential, hrn]
43 request_hash = api.key.compute_hash(arg_list)
44 aggregates[aggregate].delete_slice(credential, hrn, request_hash)
47 print >> log, "%s" % (traceback.format_exc())
48 print >> log, "Error calling list nodes at aggregate %s" % aggregate
51 def create_slice(api, hrn, rspec, gid_origin_caller=None):
54 spec.parseString(rspec)
55 slicename = hrn_to_pl_slicename(hrn)
56 specDict = spec.toDict()
57 if specDict.has_key('RSpec'): specDict = specDict['RSpec']
58 if specDict.has_key('start_time'): start_time = specDict['start_time']
60 if specDict.has_key('end_time'): end_time = specDict['end_time']
64 aggregates = Aggregates(api)
65 credential = api.getCredential()
66 credential.set_gid_origin_caller(gid_origin_caller)
67 # split the netspecs into individual rspecs
68 netspecs = spec.getDictsByTagName('NetSpec')
69 for netspec in netspecs:
70 net_hrn = netspec['name']
71 resources = {'start_time': start_time, 'end_time': end_time, 'networks': netspec}
72 resourceDict = {'RSpec': resources}
73 tempspec.parseDict(resourceDict)
74 rspecs[net_hrn] = tempspec.toxml()
76 #print "rspecs:", rspecs.keys()
77 #print "aggregates:", aggregates.keys()
78 # send each rspec to the appropriate aggregate/sm
79 for net_hrn in rspecs:
81 # if we are directly connected to the aggregate then we can just
82 # send them the rspec. if not, then we may be connected to an sm
83 # thats connected to the aggregate
84 if net_hrn in aggregates:
85 # send the whloe rspec to the local aggregate
86 if net_hrn in [api.hrn]:
89 aggregates[net_hrn].create_slice(credential, hrn, \
92 arg_list = [credential,hrn,rspec]
93 request_hash = api.key.compute_hash(arg_list)
94 aggregates[net_hrn].create_slice(credential, hrn, \
99 aggregates[net_hrn].create_slice(credential, hrn, \
100 rspecs[net_hrn], request_hash)
102 arg_list = [credential,hrn,rspecs[net_hrn]]
103 request_hash = api.key.compute_hash(arg_list)
104 aggregates[net_hrn].create_slice(credential, hrn, \
105 rspecs[net_hrn], request_hash)
107 # lets forward this rspec to a sm that knows about the network
108 arg_list = [credential, net_hrn]
109 request_hash = api.key.compute_hash(arg_list)
110 for aggregate in aggregates:
112 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn)
114 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn, request_hash)
118 aggregates[aggregate].create_slice(credential, hrn, \
119 rspecs[net_hrn], request_hash, origin_hrn)
121 arg_list = [credential, hrn, rspecs[net_hrn]]
122 request_hash = api.key.compute_hash(arg_list)
123 aggregates[aggregate].create_slice(credential, hrn, \
124 rspecs[net_hrn], request_hash, origin_hrn)
127 print >> log, "Error creating slice %(hrn)s at aggregate %(net_hrn)s" % \
129 traceback.print_exc()
132 def get_ticket(api, slice_hrn, rspec, gid_origin_caller=None):
134 # get the netspecs contained within the clients rspec
135 client_rspec = RSpec(xml=rspec)
136 netspecs = client_rspec.getDictsByTagName('NetSpec')
138 # create an rspec for each individual rspec
141 for netspec in netspecs:
142 net_hrn = netspec['name']
143 resources = {'start_time': 0, 'end_time': 0 ,
145 resourceDict = {'RSpec': resources}
146 temp_rspec.parseDict(resourceDict)
147 rspecs[net_hrn] = temp_rspec.toxml()
149 # send the rspec to the appropiate aggregate/sm
150 aggregates = Aggregates(api)
151 credential = api.getCredential()
152 credential.set_gid_origin_caller(gid_origin_caller)
154 for net_hrn in rspecs:
156 # if we are directly connected to the aggregate then we can just
157 # send them the request. if not, then we may be connected to an sm
158 # thats connected to the aggregate
159 if net_hrn in aggregates:
161 ticket = aggregates[net_hrn].get_ticket(credential, slice_hrn, \
162 rspecs[net_hrn], None)
163 tickets[net_hrn] = ticket
165 arg_list = [credential,hrn,rspecs[net_hrn]]
166 request_hash = api.key.compute_hash(arg_list)
167 ticket = aggregates[net_hrn].get_ticket(credential, slice_hrn, \
168 rspecs[net_hrn], request_hash)
169 tickets[net_hrn] = ticket
171 # lets forward this rspec to a sm that knows about the network
172 arg_list = [credential, net_hrn]
173 request_hash = api.key.compute_hash(arg_list)
174 for agg in aggregates:
176 network_found = aggregates[agg].get_aggregates(credential, \
179 network_found = aggregates[agg].get_aggregates(credential, \
180 net_hrn, request_hash)
183 ticket = aggregates[aggregate].get_ticket(credential, \
184 slice_hrn, rspecs[net_hrn], None)
185 tickets[aggregate] = ticket
187 arg_list = [credential, hrn, rspecs[net_hrn]]
188 request_hash = api.key.compute_hash(arg_list)
189 aggregates[aggregate].get_ticket(credential, slice_hrn, \
190 rspecs[net_hrn], request_hash)
191 tickets[aggregate] = ticket
193 print >> log, "Error getting ticket for %(slice_hrn)s at aggregate %(net_hrn)s" % \
196 # create a new ticket
197 new_ticket = SfaTicket(subject = slice_hrn)
198 new_ticket.set_gid_caller(api.auth.client_gid)
203 # merge data from aggregate ticket into new ticket
204 for agg_ticket in tickets.values():
205 agg_ticket = SfaTicket(string=agg_ticket)
206 object_gid = agg_ticket.get_gid_object()
207 new_ticket.set_gid_object(object_gid)
208 new_ticket.set_issuer(key=api.key, subject=api.hrn)
209 new_ticket.set_pubkey(object_gid.get_pubkey())
211 #new_ticket.set_attributes(data)
212 tmp_rspec.parseString(agg_ticket.get_rspec())
213 networks.extend([{'NetSpec': tmp_rspec.getDictsByTagName('NetSpec')}])
215 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
216 resources = {'networks': networks, 'start_time': 0, 'duration': 0}
217 resourceDict = {'RSpec': resources}
218 tmp_rspec.parseDict(resourceDict)
219 new_ticket.set_rspec(tmp_rspec.toxml())
223 return new_ticket.save_to_string(save_parents=True)
225 def start_slice(api, hrn, origin_hrn=None):
226 slicename = hrn_to_pl_slicename(hrn)
227 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
229 raise RecordNotFound(hrn)
231 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
232 attribute_id = attreibutes[0]['slice_attribute_id']
233 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
237 def stop_slice(api, hrn, origin_hrn):
238 slicename = hrn_to_pl_slicename(hrn)
239 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
241 raise RecordNotFound(hrn)
242 slice_id = slices[0]['slice_id']
243 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
244 attribute_id = attributes[0]['slice_attribute_id']
245 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
248 def reset_slice(api, hrn, origin_hrn):
249 # XX not implemented at this interface
253 # XX just import the legacy module and excute that until
254 # we transition the code to this module
255 from sfa.plc.slices import Slices
260 def get_rspec(api, hrn=None, origin_gid_caller=None):
261 from sfa.plc.nodes import Nodes
262 nodes = Nodes(api, origin_gid_caller=origin_gid_caller)
264 rspec = nodes.get_rspec(hrn)
267 rspec = nodes['rspec']
272 Returns the request context required by sfatables. At some point, this mechanism should be changed
273 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
274 return the basic information needed in a dict.
276 def fetch_context(slice_hrn, user_hrn, contexts):
277 base_context = {'sfa':{'user':{'hrn':user_hrn}}}
282 r.parseFile(sys.argv[1])
284 create_slice(None,'plc.princeton.tmacktestslice',rspec)
286 if __name__ == "__main__":