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.namespace 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 SfaRecord
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, xrn, 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
31 aggregates[aggregate].delete_slice(credential, xrn, origin_hrn)
34 print >> log, "%s" % (traceback.format_exc())
35 print >> log, "Error calling delete slice at aggregate %s" % aggregate
38 def create_slice(api, xrn, rspec, origin_hrn=None):
39 hrn, type = urn_to_hrn(xrn)
42 spec.parseString(rspec)
43 slicename = hrn_to_pl_slicename(hrn)
44 specDict = spec.toDict()
45 if specDict.has_key('RSpec'): specDict = specDict['RSpec']
46 if specDict.has_key('start_time'): start_time = specDict['start_time']
48 if specDict.has_key('end_time'): end_time = specDict['end_time']
52 aggregates = Aggregates(api)
53 credential = api.getCredential()
54 # split the netspecs into individual rspecs
55 netspecs = spec.getDictsByTagName('NetSpec')
56 for netspec in netspecs:
57 net_hrn = netspec['name']
58 resources = {'start_time': start_time, 'end_time': end_time, 'networks': {'NetSpec' : netspec}}
59 resourceDict = {'RSpec': resources}
60 tempspec.parseDict(resourceDict)
61 rspecs[net_hrn] = tempspec.toxml()
63 #print "rspecs:", rspecs.keys()
64 #print "aggregates:", aggregates.keys()
65 # send each rspec to the appropriate aggregate/sm
66 for net_hrn in rspecs:
67 net_urn = hrn_to_urn(net_hrn, 'authority')
69 # if we are directly connected to the aggregate then we can just
70 # send them the rspec. if not, then we may be connected to an sm
71 # thats connected to the aggregate
72 if net_hrn in aggregates:
73 # send the whloe rspec to the local aggregate
74 if net_hrn in [api.hrn]:
75 aggregates[net_hrn].create_slice(credential, xrn, rspec, \
78 aggregates[net_hrn].create_slice(credential, xrn, \
79 rspecs[net_hrn], origin_hrn)
81 # lets forward this rspec to a sm that knows about the network
82 for aggregate in aggregates:
83 network_found = aggregates[aggregate].get_aggregates(credential, net_hrn)
85 aggregates[aggregate].create_slice(credential, xrn, \
86 rspecs[net_hrn], origin_hrn)
89 print >> log, "Error creating slice %(hrn)s at aggregate %(net_hrn)s" % \
94 def get_ticket(api, xrn, rspec, origin_hrn=None):
95 slice_hrn, type = urn_to_hrn(xrn)
96 # get the netspecs contained within the clients rspec
97 client_rspec = RSpec(xml=rspec)
98 netspecs = client_rspec.getDictsByTagName('NetSpec')
100 # create an rspec for each individual rspec
103 for netspec in netspecs:
104 net_hrn = netspec['name']
105 resources = {'start_time': 0, 'end_time': 0 ,
106 'network': {'NetSpec' : netspec}}
107 resourceDict = {'RSpec': resources}
108 temp_rspec.parseDict(resourceDict)
109 rspecs[net_hrn] = temp_rspec.toxml()
111 # send the rspec to the appropiate aggregate/sm
112 aggregates = Aggregates(api)
113 credential = api.getCredential()
115 for net_hrn in rspecs:
116 net_urn = urn_to_hrn(net_hrn)
118 # if we are directly connected to the aggregate then we can just
119 # send them the request. if not, then we may be connected to an sm
120 # thats connected to the aggregate
121 if net_hrn in aggregates:
122 ticket = aggregates[net_hrn].get_ticket(credential, xrn, \
123 rspecs[net_hrn], origin_hrn)
124 tickets[net_hrn] = ticket
126 # lets forward this rspec to a sm that knows about the network
127 for agg in aggregates:
128 network_found = aggregates[agg].get_aggregates(credential, net_urn)
130 ticket = aggregates[aggregate].get_ticket(credential, \
131 slice_hrn, rspecs[net_hrn], origin_hrn)
132 tickets[aggregate] = ticket
134 print >> log, "Error getting ticket for %(slice_hrn)s at aggregate %(net_hrn)s" % \
137 # create a new ticket
138 new_ticket = SfaTicket(subject = slice_hrn)
139 new_ticket.set_gid_caller(api.auth.client_gid)
140 new_ticket.set_issuer(key=api.key, subject=api.hrn)
145 'timestamp': int(time.time()),
149 # merge data from aggregate ticket into new ticket
150 for agg_ticket in tickets.values():
151 # get data from this ticket
152 agg_ticket = SfaTicket(string=agg_ticket)
153 attributes = agg_ticket.get_attributes()
154 if attributes.get('initscripts', []) != None:
155 valid_data['initscripts'].extend(attributes.get('initscripts', []))
156 if attributes.get('slivers', []) != None:
157 valid_data['slivers'].extend(attributes.get('slivers', []))
160 object_gid = agg_ticket.get_gid_object()
161 new_ticket.set_gid_object(object_gid)
162 new_ticket.set_pubkey(object_gid.get_pubkey())
165 tmp_rspec.parseString(agg_ticket.get_rspec())
166 networks.extend([{'NetSpec': tmp_rspec.getDictsByTagName('NetSpec')}])
168 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
169 new_ticket.set_attributes(valid_data)
170 resources = {'networks': networks, 'start_time': 0, 'duration': 0}
171 resourceDict = {'RSpec': resources}
172 tmp_rspec.parseDict(resourceDict)
173 new_ticket.set_rspec(tmp_rspec.toxml())
176 return new_ticket.save_to_string(save_parents=True)
178 def start_slice(api, xrn):
179 hrn, type = urn_to_hrn(xrn)
180 slicename = hrn_to_pl_slicename(hrn)
181 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
183 raise RecordNotFound(hrn)
185 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
186 attribute_id = attreibutes[0]['slice_attribute_id']
187 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
191 def stop_slice(api, xrn):
192 hrn, type = urn_to_hrn(xrn)
193 slicename = hrn_to_pl_slicename(hrn)
194 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
196 raise RecordNotFound(hrn)
197 slice_id = slices[0]['slice_id']
198 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
199 attribute_id = attributes[0]['slice_attribute_id']
200 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
203 def reset_slice(api, xrn):
204 # XX not implemented at this interface
208 # XX just import the legacy module and excute that until
209 # we transition the code to this module
210 from sfa.plc.slices import Slices
213 return [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slices['hrn']]
215 def get_rspec(api, xrn=None, origin_hrn=None):
217 from sfa.plc.nodes import Nodes
218 nodes = Nodes(api, origin_hrn=origin_hrn)
220 rspec = nodes.get_rspec(xrn)
223 rspec = nodes['rspec']
228 Returns the request context required by sfatables. At some point, this mechanism should be changed
229 to refer to "contexts", which is the information that sfatables is requesting. But for now, we just
230 return the basic information needed in a dict.
232 def fetch_context(slice_hrn, user_hrn, contexts):
233 #slice_hrn = urn_to_hrn(slice_xrn)[0]
234 #user_hrn = urn_to_hrn(user_xrn)[0]
235 base_context = {'sfa':{'user':{'hrn':user_hrn}}}
240 r.parseFile(sys.argv[1])
242 create_slice(None,'plc.princeton.tmacktestslice',rspec)
244 if __name__ == "__main__":