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 $
8 from copy import deepcopy
10 from StringIO import StringIO
11 from types import StringTypes
13 from sfa.util.namespace import *
14 from sfa.util.rspec import *
15 from sfa.util.specdict import *
16 from sfa.util.faults import *
17 from sfa.util.record import SfaRecord
18 from sfa.util.policy import Policy
19 from sfa.util.prefixTree import prefixTree
20 from sfa.util.rspec import *
21 from sfa.util.sfaticket import *
22 from sfa.util.debug import log
23 from sfa.server.registry import Registries
24 from sfa.server.aggregate import Aggregates
25 import sfa.plc.peers as peers
27 def delete_slice(api, xrn, origin_hrn=None):
28 credential = api.getCredential()
29 aggregates = Aggregates(api)
30 for aggregate in aggregates:
32 # request hash is optional so lets try the call without it
34 aggregates[aggregate].delete_slice(credential, xrn, origin_hrn)
37 print >> log, "%s" % (traceback.format_exc())
38 print >> log, "Error calling delete slice at aggregate %s" % aggregate
41 def create_slice(api, xrn, rspec, origin_hrn=None):
42 hrn, type = urn_to_hrn(xrn)
43 aggs = Aggregates(api)
44 cred = api.getCredential()
46 # Validate the RSpec here against PlanetLab's schema
48 aggs = Aggregates(api)
49 cred = api.getCredential()
51 if agg not in [api.auth.client_cred.get_gid_caller().get_hrn()]:
53 # Just send entire RSpec to each aggregate
54 aggs[agg].create_slice(cred, xrn, rspec, origin_hrn)
56 print >> log, "Error creating slice %s at %s" % (hrn, agg)
61 def get_ticket(api, xrn, rspec, origin_hrn=None):
62 slice_hrn, type = urn_to_hrn(xrn)
63 # get the netspecs contained within the clients rspec
64 client_rspec = RSpec(xml=rspec)
65 netspecs = client_rspec.getDictsByTagName('NetSpec')
67 # create an rspec for each individual rspec
70 for netspec in netspecs:
71 net_hrn = netspec['name']
72 resources = {'start_time': 0, 'end_time': 0 ,
73 'network': {'NetSpec' : netspec}}
74 resourceDict = {'RSpec': resources}
75 temp_rspec.parseDict(resourceDict)
76 rspecs[net_hrn] = temp_rspec.toxml()
78 # send the rspec to the appropiate aggregate/sm
79 aggregates = Aggregates(api)
80 credential = api.getCredential()
82 for net_hrn in rspecs:
83 net_urn = urn_to_hrn(net_hrn)
85 # if we are directly connected to the aggregate then we can just
86 # send them the request. if not, then we may be connected to an sm
87 # thats connected to the aggregate
88 if net_hrn in aggregates:
89 ticket = aggregates[net_hrn].get_ticket(credential, xrn, \
90 rspecs[net_hrn], origin_hrn)
91 tickets[net_hrn] = ticket
93 # lets forward this rspec to a sm that knows about the network
94 for agg in aggregates:
95 network_found = aggregates[agg].get_aggregates(credential, net_urn)
97 ticket = aggregates[aggregate].get_ticket(credential, \
98 slice_hrn, rspecs[net_hrn], origin_hrn)
99 tickets[aggregate] = ticket
101 print >> log, "Error getting ticket for %(slice_hrn)s at aggregate %(net_hrn)s" % \
104 # create a new ticket
105 new_ticket = SfaTicket(subject = slice_hrn)
106 new_ticket.set_gid_caller(api.auth.client_gid)
107 new_ticket.set_issuer(key=api.key, subject=api.hrn)
112 'timestamp': int(time.time()),
116 # merge data from aggregate ticket into new ticket
117 for agg_ticket in tickets.values():
118 # get data from this ticket
119 agg_ticket = SfaTicket(string=agg_ticket)
120 attributes = agg_ticket.get_attributes()
121 if attributes.get('initscripts', []) != None:
122 valid_data['initscripts'].extend(attributes.get('initscripts', []))
123 if attributes.get('slivers', []) != None:
124 valid_data['slivers'].extend(attributes.get('slivers', []))
127 object_gid = agg_ticket.get_gid_object()
128 new_ticket.set_gid_object(object_gid)
129 new_ticket.set_pubkey(object_gid.get_pubkey())
132 tmp_rspec.parseString(agg_ticket.get_rspec())
133 networks.extend([{'NetSpec': tmp_rspec.getDictsByTagName('NetSpec')}])
135 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
136 new_ticket.set_attributes(valid_data)
137 resources = {'networks': networks, 'start_time': 0, 'duration': 0}
138 resourceDict = {'RSpec': resources}
139 tmp_rspec.parseDict(resourceDict)
140 new_ticket.set_rspec(tmp_rspec.toxml())
143 return new_ticket.save_to_string(save_parents=True)
145 def start_slice(api, xrn):
146 hrn, type = urn_to_hrn(xrn)
147 slicename = hrn_to_pl_slicename(hrn)
148 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
150 raise RecordNotFound(hrn)
152 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
153 attribute_id = attreibutes[0]['slice_attribute_id']
154 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
158 def stop_slice(api, xrn):
159 hrn, type = urn_to_hrn(xrn)
160 slicename = hrn_to_pl_slicename(hrn)
161 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
163 raise RecordNotFound(hrn)
164 slice_id = slices[0]['slice_id']
165 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
166 attribute_id = attributes[0]['slice_attribute_id']
167 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
170 def reset_slice(api, xrn):
171 # XX not implemented at this interface
175 # XX just import the legacy module and excute that until
176 # we transition the code to this module
177 from sfa.plc.slices import Slices
180 return [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slices['hrn']]
182 def get_rspec(api, xrn=None, origin_hrn=None):
183 hrn, type = urn_to_hrn(xrn)
186 aggs = Aggregates(api)
187 cred = api.getCredential()
189 if agg not in [api.auth.client_cred.get_gid_caller().get_hrn()]:
191 # get the rspec from the aggregate
192 agg_rspec = aggs[agg].get_resources(cred, xrn, origin_hrn)
194 tree = etree.parse(StringIO(agg_rspec))
195 root = tree.getroot()
196 if root.get("type") in ["Planetlab", "VINI"]:
197 # Validate the aggregate's RSpec?
202 for network in root.iterfind("./network"):
203 rspec.append(deepcopy(network))
205 # XX print out to some error log
206 print >> log, "Error getting resources at aggregate %s" % agg
207 traceback.print_exc(log)
208 print >> log, "%s" % (traceback.format_exc())
211 return etree.tostring(rspec, xml_declaration=True, pretty_print=True)
214 Returns the request context required by sfatables. At some point, this
215 mechanism should be changed to refer to "contexts", which is the
216 information that sfatables is requesting. But for now, we just return
217 the basic information needed in a dict.
219 def fetch_context(slice_hrn, user_hrn, contexts):
220 #slice_hrn = urn_to_hrn(slice_xrn)[0]
221 #user_hrn = urn_to_hrn(user_xrn)[0]
222 base_context = {'sfa':{'user':{'hrn':user_hrn}, 'slice':{'hrn':slice_hrn}}}
227 r.parseFile(sys.argv[1])
229 create_slice(None,'plc.princeton.tmacktestslice',rspec)
231 if __name__ == "__main__":