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.record import *
17 from sfa.util.sfaticket import SfaTicket
18 from sfa.util.debug import log
19 from sfa.plc.slices import Slices
20 from sfa.trust.credential import Credential
21 import sfa.plc.peers as peers
22 from sfa.plc.network import *
23 from sfa.plc.api import SfaAPI
24 from sfa.plc.slices import *
28 version['geni_api'] = 1
31 def delete_slice(api, xrn):
32 hrn, type = urn_to_hrn(xrn)
33 slicename = hrn_to_pl_slicename(hrn)
34 slices = api.plshell.GetSlices(api.plauth, {'name': slicename})
39 # determine if this is a peer slice
40 peer = peers.get_peer(api, hrn)
42 api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice['slice_id'], peer)
43 api.plshell.DeleteSliceFromNodes(api.plauth, slicename, slice['node_ids'])
45 api.plshell.BindObjectToPeer(api.plauth, 'slice', slice['slice_id'], peer, slice['peer_slice_id'])
48 def __get_hostnames(nodes):
51 hostnames.append(node.hostname)
54 def create_slice(api, xrn, xml, reg_objects=None):
56 Verify HRN and initialize the slice record in PLC if necessary.
59 hrn, type = urn_to_hrn(xrn)
62 peer = slices.get_peer(hrn)
63 sfa_peer = slices.get_sfa_peer(hrn)
64 registry = api.registries[api.hrn]
65 credential = api.getCredential()
66 site_id, remote_site_id = slices.verify_site(registry, credential, hrn,
67 peer, sfa_peer, reg_objects)
69 slice = slices.verify_slice(registry, credential, hrn, site_id,
70 remote_site_id, peer, sfa_peer, reg_objects)
72 network = Network(api)
74 slice = network.get_slice(api, hrn)
75 current = __get_hostnames(slice.get_nodes())
77 network.addRSpec(xml, api.config.SFA_AGGREGATE_RSPEC_SCHEMA)
78 request = __get_hostnames(network.nodesWithSlivers())
80 # remove nodes not in rspec
81 deleted_nodes = list(set(current).difference(request))
83 # add nodes from rspec
84 added_nodes = list(set(request).difference(current))
89 api.plshell.UnBindObjectFromPeer(api.plauth, 'slice', slice.id, peer)
91 api.plshell.AddSliceToNodes(api.plauth, slice.name, added_nodes)
92 api.plshell.DeleteSliceFromNodes(api.plauth, slice.name, deleted_nodes)
94 network.updateSliceTags()
97 api.plshell.BindObjectToPeer(api.plauth, 'slice', slice.id, peer,
100 # print network.toxml()
105 def get_ticket(api, xrn, rspec, origin_hrn=None, reg_objects=None):
107 slice_hrn, type = urn_to_hrn(xrn)
109 peer = slices.get_peer(slice_hrn)
110 sfa_peer = slices.get_sfa_peer(slice_hrn)
112 # get the slice record
113 registry = api.registries[api.hrn]
114 credential = api.getCredential()
115 records = registry.resolve(credential, xrn)
117 # similar to create_slice, we must verify that the required records exist
118 # at this aggregate before we can issue a ticket
119 site_id, remote_site_id = slices.verify_site(registry, credential, slice_hrn,
120 peer, sfa_peer, reg_objects)
121 slice = slices.verify_slice(registry, credential, slice_hrn, site_id,
122 remote_site_id, peer, sfa_peer, reg_objects)
124 # make sure we get a local slice record
126 for tmp_record in records:
127 if tmp_record['type'] == 'slice' and \
128 not tmp_record['peer_authority']:
129 record = SliceRecord(dict=tmp_record)
131 raise RecordNotFound(slice_hrn)
134 slivers = Slices(api).get_slivers(slice_hrn)
136 raise SliverDoesNotExist(slice_hrn)
141 'timestamp': int(time.time()),
142 'initscripts': initscripts,
147 object_gid = record.get_gid_object()
148 new_ticket = SfaTicket(subject = object_gid.get_subject())
149 new_ticket.set_gid_caller(api.auth.client_gid)
150 new_ticket.set_gid_object(object_gid)
151 new_ticket.set_issuer(key=api.key, subject=api.hrn)
152 new_ticket.set_pubkey(object_gid.get_pubkey())
153 new_ticket.set_attributes(data)
154 new_ticket.set_rspec(rspec)
155 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
159 return new_ticket.save_to_string(save_parents=True)
161 def start_slice(api, xrn):
162 hrn, type = urn_to_hrn(xrn)
163 slicename = hrn_to_pl_slicename(hrn)
164 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
166 raise RecordNotFound(hrn)
168 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
169 attribute_id = attributes[0]['slice_attribute_id']
170 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "1" )
174 def stop_slice(api, xrn):
175 hrn, type = urn_to_hrn(xrn)
176 slicename = hrn_to_pl_slicename(hrn)
177 slices = api.plshell.GetSlices(api.plauth, {'name': slicename}, ['slice_id'])
179 raise RecordNotFound(hrn)
180 slice_id = slices[0]['slice_id']
181 attributes = api.plshell.GetSliceTags(api.plauth, {'slice_id': slice_id, 'name': 'enabled'}, ['slice_attribute_id'])
182 attribute_id = attributes[0]['slice_attribute_id']
183 api.plshell.UpdateSliceTag(api.plauth, attribute_id, "0")
186 def reset_slice(api, xrn):
187 # XX not implemented at this interface
191 # look in cache first
193 slices = api.cache.get('slices')
198 slices = api.plshell.GetSlices(api.plauth, {'peer_id': None}, ['name'])
199 slice_hrns = [slicename_to_hrn(api.hrn, slice['name']) for slice in slices]
200 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
204 api.cache.add('slices', slice_urns)
208 def get_rspec(api, creds, options):
209 # get slice's hrn from options
210 xrn = options.get('geni_slice_urn', None)
211 hrn, type = urn_to_hrn(xrn)
213 # get hrn of the original caller
214 origin_hrn = options.get('origin_hrn', None)
216 origin_hrn = Credential(string=creds[0]).get_gid_caller().get_hrn()
218 # look in cache first
219 if api.cache and not xrn:
220 rspec = api.cache.get('nodes')
224 network = Network(api)
226 if network.get_slice(api, hrn):
229 rspec = network.toxml()
232 if api.cache and not xrn:
233 api.cache.add('nodes', rspec)
239 Returns the request context required by sfatables. At some point, this
240 mechanism should be changed to refer to "contexts", which is the
241 information that sfatables is requesting. But for now, we just return
242 the basic information needed in a dict.
244 def fetch_context(slice_xrn, user_xrn, contexts):
245 slice_hrn, type = urn_to_hrn(slice_xrn)
246 user_hrn, type = urn_to_hrn(user_xrn)
247 base_context = {'sfa':{'user':{'hrn':user_hrn}, 'slice':{'hrn':slice_hrn}}}
253 rspec = get_rspec(api, "plc.princeton.sapan", None)
254 #rspec = get_rspec(api, "plc.princeton.coblitz", None)
255 #rspec = get_rspec(api, "plc.pl.sirius", None)
258 f = open(sys.argv[1])
261 create_slice(api, "plc.princeton.sapan", xml)
263 if __name__ == "__main__":