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, origin_hrn=None):
25 credential = api.getCredential()
26 aggregates = Aggregates(api)
27 for aggregate in aggregates:
29 # request hash is optional so lets try the call without it
32 aggregates[aggregate].delete_slice(credential, hrn, request_hash, origin_hrn)
35 print >> log, "%s" % (traceback.format_exc())
36 print >> log, "Error calling delete slice at aggregate %s" % aggregate
38 # try sending the request hash if the previous call failed
41 arg_list = [credential, hrn]
42 request_hash = api.key.compute_hash(arg_list)
43 aggregates[aggregate].delete_slice(credential, hrn, request_hash, origin_hrn)
46 print >> log, "%s" % (traceback.format_exc())
47 print >> log, "Error calling list nodes at aggregate %s" % aggregate
50 def create_slice(api, hrn, rspec, origin_hrn=None):
53 spec.parseString(rspec)
54 slicename = hrn_to_pl_slicename(hrn)
55 specDict = spec.toDict()
56 if specDict.has_key('RSpec'): specDict = specDict['RSpec']
57 if specDict.has_key('start_time'): start_time = specDict['start_time']
59 if specDict.has_key('end_time'): end_time = specDict['end_time']
63 aggregates = Aggregates(api)
64 credential = api.getCredential()
66 # split the netspecs into individual rspecs
67 netspecs = spec.getDictsByTagName('NetSpec')
68 for netspec in netspecs:
69 net_hrn = netspec['name']
70 resources = {'start_time': start_time, 'end_time': end_time, 'networks': netspec}
71 resourceDict = {'RSpec': resources}
72 tempspec.parseDict(resourceDict)
73 rspecs[net_hrn] = tempspec.toxml()
75 #print "rspecs:", rspecs.keys()
76 #print "aggregates:", aggregates.keys()
77 # send each rspec to the appropriate aggregate/sm
78 for net_hrn in rspecs:
80 # if we are directly connected to the aggregate then we can just
81 # send them the rspec. if not, then we may be connected to an sm
82 # thats connected to the aggregate
83 if net_hrn in aggregates:
84 # send the whloe rspec to the local aggregate
85 if net_hrn in [api.hrn]:
88 aggregates[net_hrn].create_slice(credential, hrn, \
89 rspec, request_hash, origin_hrn)
91 arg_list = [credential,hrn,rspec]
92 request_hash = api.key.compute_hash(arg_list)
93 aggregates[net_hrn].create_slice(credential, hrn, \
94 rspec, request_hash, origin_hrn)
98 aggregates[net_hrn].create_slice(credential, hrn, \
99 rspecs[net_hrn], request_hash, origin_hrn)
101 arg_list = [credential,hrn,rspecs[net_hrn]]
102 request_hash = api.key.compute_hash(arg_list)
103 aggregates[net_hrn].create_slice(credential, hrn, \
104 rspecs[net_hrn], request_hash, origin_hrn)
106 # lets forward this rspec to a sm that knows about the network
107 arg_list = [credential, net_hrn]
108 request_hash = api.key.compute_hash(arg_list)
109 for aggregate in aggregates:
111 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn)
113 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn, request_hash)
117 aggregates[aggregate].create_slice(credential, hrn, \
118 rspecs[net_hrn], request_hash, origin_hrn)
120 arg_list = [credential, hrn, rspecs[net_hrn]]
121 request_hash = api.key.compute_hash(arg_list)
122 aggregates[aggregate].create_slice(credential, hrn, \
123 rspecs[net_hrn], request_hash, origin_hrn)
126 print >> log, "Error creating slice %(hrn)s at aggregate %(net_hrn)s" % \
128 traceback.print_exc()
131 def get_ticket(api, slice_hrn, rspec, origin_hrn=None):
133 # get the netspecs contained within the clients rspec
134 client_rspec = RSpec(xml=rspec)
135 netspecs = client_rspec.getDictsByTagName('NetSpec')
137 # create an rspec for each individual rspec
140 for netspec in netspecs:
141 net_hrn = netspec['name']
142 resources = {'start_time': 0, 'end_time': 0 ,
144 resourceDict = {'RSpec': resources}
145 temp_rspec.parseDict(resourceDict)
146 rspecs[net_hrn] = temp_rspec.toxml()
148 # send the rspec to the appropiate aggregate/sm
149 aggregates = Aggregates(api)
150 credential = api.getCredential()
152 for net_hrn in rspecs:
154 # if we are directly connected to the aggregate then we can just
155 # send them the request. if not, then we may be connected to an sm
156 # thats connected to the aggregate
157 if net_hrn in aggregates:
159 ticket = aggregates[net_hrn].get_ticket(credential, hrn, \
160 rspecs[net_hrn], None, origin_hrn)
161 tickets[net_hrn] = ticket
163 arg_list = [credential,hrn,rspecs[net_hrn]]
164 request_hash = api.key.compute_hash(arg_list)
165 ticket = aggregates[net_hrn].get_ticket(credential, hrn, \
166 rspecs[net_hrn], request_hash, origin_hrn)
167 tickets[net_hrn] = ticket
169 # lets forward this rspec to a sm that knows about the network
170 arg_list = [credential, net_hrn]
171 request_hash = api.key.compute_hash(arg_list)
172 for agg in aggregates:
174 network_found = aggregates[agg].get_aggregates(credential, \
177 network_found = aggregates[agg].get_aggregates(credential, \
178 net_hrn, request_hash)
181 ticket = aggregates[aggregate].get_ticket(credential, \
182 hrn, rspecs[net_hrn], None, origin_hrn)
183 tickets[aggregate] = ticket
185 arg_list = [credential, hrn, rspecs[net_hrn]]
186 request_hash = api.key.compute_hash(arg_list)
187 aggregates[aggregate].get_ticket(credential, hrn, \
188 rspecs[net_hrn], request_hash, origin_hrn)
189 tickets[aggregate] = ticket
191 print >> log, "Error getting ticket for %(hrn)s at aggregate %(net_hrn)s" % \
194 # create a new ticket
195 new_ticket = SfaTicket(subject = slice_hrn)
196 new_ticket.set_gid_caller(api.auth.client_gid)
201 # merge data from aggregate ticket into new ticket
202 for agg_ticket in tickets.values():
203 agg_ticket = SfaTicket(string=agg_ticket)
204 object_gid = agg_ticket.get_gid_object()
205 new_ticket.set_gid_object(object_gid)
206 new_ticket.set_issuer(key=api.key, subject=api.hrn)
207 new_ticket.set_pubkey(object_gid.get_pubkey())
210 #new_ticket.set_attributes(data)
211 tmp_rspec.parseString(agg_ticket.get_rspec)
212 newtworks.extend([{'NetSpec': 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())
223 def start_slice(api, hrn, origin_hrn=None):
224 slicename = hrn_to_pl_slicename(hrn)
225 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
227 raise RecordNotFound(hrn)
229 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
230 attribute_id = attreibutes[0]['slice_attribute_id']
231 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
235 def stop_slice(api, hrn, origin_hrn):
236 slicename = hrn_to_pl_slicename(hrn)
237 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
239 raise RecordNotFound(hrn)
240 slice_id = slices[0]['slice_id']
241 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
242 attribute_id = attributes[0]['slice_attribute_id']
243 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
246 def reset_slice(api, hrn, origin_hrn):
247 # XX not implemented at this interface
251 # XX just import the legacy module and excute that until
252 # we transition the code to this module
253 from sfa.plc.slices import Slices
258 def get_rspec(api, hrn=None, origin_hrn=None):
259 from sfa.plc.nodes import Nodes
260 nodes = Nodes(api, origin_hrn=origin_hrn)
262 rspec = nodes.get_rspec(hrn)
265 rspec = nodes['rspec']
270 Returns the request context required by sfatables. At some point, this mechanism should be changed
271 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
272 return the basic information needed in a dict.
274 def fetch_context(slice_hrn, user_hrn, contexts):
275 base_context = {'sfa':{'user':{'hrn':user_hrn}}}
280 r.parseFile(sys.argv[1])
282 create_slice(None,'plc.princeton.tmacktestslice',rspec)
284 if __name__ == "__main__":