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, origin_hrn=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()
153 for net_hrn in rspecs:
155 # if we are directly connected to the aggregate then we can just
156 # send them the request. if not, then we may be connected to an sm
157 # thats connected to the aggregate
158 if net_hrn in aggregates:
160 ticket = aggregates[net_hrn].get_ticket(credential, slice_hrn, \
161 rspecs[net_hrn], None, origin_hrn)
162 tickets[net_hrn] = ticket
164 arg_list = [credential,hrn,rspecs[net_hrn]]
165 request_hash = api.key.compute_hash(arg_list)
166 ticket = aggregates[net_hrn].get_ticket(credential, slice_hrn, \
167 rspecs[net_hrn], request_hash, origin_hrn)
168 tickets[net_hrn] = ticket
170 # lets forward this rspec to a sm that knows about the network
171 arg_list = [credential, net_hrn]
172 request_hash = api.key.compute_hash(arg_list)
173 for agg in aggregates:
175 network_found = aggregates[agg].get_aggregates(credential, \
178 network_found = aggregates[agg].get_aggregates(credential, \
179 net_hrn, request_hash)
182 ticket = aggregates[aggregate].get_ticket(credential, \
183 slice_hrn, rspecs[net_hrn], None, origin_hrn)
184 tickets[aggregate] = ticket
186 arg_list = [credential, hrn, rspecs[net_hrn]]
187 request_hash = api.key.compute_hash(arg_list)
188 aggregates[aggregate].get_ticket(credential, slice_hrn, \
189 rspecs[net_hrn], request_hash, origin_hrn)
190 tickets[aggregate] = ticket
192 print >> log, "Error getting ticket for %(slice_hrn)s at aggregate %(net_hrn)s" % \
195 # create a new ticket
196 new_ticket = SfaTicket(subject = slice_hrn)
197 new_ticket.set_gid_caller(api.auth.client_gid)
202 # merge data from aggregate ticket into new ticket
203 for agg_ticket in tickets.values():
204 agg_ticket = SfaTicket(string=agg_ticket)
205 object_gid = agg_ticket.get_gid_object()
206 new_ticket.set_gid_object(object_gid)
207 new_ticket.set_issuer(key=api.key, subject=api.hrn)
208 new_ticket.set_pubkey(object_gid.get_pubkey())
210 #new_ticket.set_attributes(data)
211 tmp_rspec.parseString(agg_ticket.get_rspec())
212 networks.extend([{'NetSpec': tmp_rspec.getDictsByTagName('NetSpec')}])
214 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
215 resources = {'networks': networks, 'start_time': 0, 'duration': 0}
216 resourceDict = {'RSpec': resources}
217 tmp_rspec.parseDict(resourceDict)
218 new_ticket.set_rspec(tmp_rspec.toxml())
222 return new_ticket.save_to_string(save_parents=True)
224 def start_slice(api, hrn, origin_hrn=None):
225 slicename = hrn_to_pl_slicename(hrn)
226 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
228 raise RecordNotFound(hrn)
230 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
231 attribute_id = attreibutes[0]['slice_attribute_id']
232 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
236 def stop_slice(api, hrn, origin_hrn):
237 slicename = hrn_to_pl_slicename(hrn)
238 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
240 raise RecordNotFound(hrn)
241 slice_id = slices[0]['slice_id']
242 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
243 attribute_id = attributes[0]['slice_attribute_id']
244 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
247 def reset_slice(api, hrn, origin_hrn):
248 # XX not implemented at this interface
252 # XX just import the legacy module and excute that until
253 # we transition the code to this module
254 from sfa.plc.slices import Slices
259 def get_rspec(api, hrn=None, origin_hrn=None):
260 from sfa.plc.nodes import Nodes
261 nodes = Nodes(api, origin_hrn=origin_hrn)
263 rspec = nodes.get_rspec(hrn)
266 rspec = nodes['rspec']
271 Returns the request context required by sfatables. At some point, this mechanism should be changed
272 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
273 return the basic information needed in a dict.
275 def fetch_context(slice_hrn, user_hrn, contexts):
276 base_context = {'sfa':{'user':{'hrn':user_hrn}}}
281 r.parseFile(sys.argv[1])
283 create_slice(None,'plc.princeton.tmacktestslice',rspec)
285 if __name__ == "__main__":