4 from sfa.util.sfalogging import logger
5 from sfa.util.faults import RecordNotFound, SliverDoesNotExist
6 from sfa.util.xrn import Xrn, get_authority, hrn_to_urn, urn_to_hrn, urn_to_sliver_id
7 from sfa.util.plxrn import slicename_to_hrn, hrn_to_pl_slicename
8 from sfa.util.version import version_core
9 from sfa.util.sfatime import utcparse
10 from sfa.util.callids import Callids
12 from sfa.trust.sfaticket import SfaTicket
13 from sfa.trust.credential import Credential
15 from sfa.rspecs.version_manager import VersionManager
16 from sfa.rspecs.rspec import RSpec
18 from sfa.server.sfaapi import SfaApi
20 import sfa.plc.peers as peers
21 from sfa.plc.plaggregate import PlAggregate
22 from sfa.plc.plslices import PlSlices
24 class AggregateManager:
27 # xxx Thierry : caching at the aggregate level sounds wrong...
31 # essentially a union of the core version, the generic version (this code) and
32 # whatever the driver needs to expose
33 def GetVersion(self, api, options):
36 version = version_core()
37 version_generic = {'interface':'aggregate',
43 version.update(version_generic)
44 testbed_version = self.driver.aggregate_version()
45 version.update(testbed_version)
48 def SliverStatus (self, api, slice_xrn, creds, options):
49 call_id = options.get('call_id')
50 if Callids().already_handled(call_id): return {}
53 slice_urn=xrn.get_urn()
54 slice_hrn=xrn.get_hrn()
56 return self.driver.sliver_status (slice_urn, slice_hrn)
58 def CreateSliver(self, api, slice_xrn, creds, rspec_string, users, options):
60 Create the sliver[s] (slice) at this aggregate.
61 Verify HRN and initialize the slice record in PLC if necessary.
63 call_id = options.get('call_id')
64 if Callids().already_handled(call_id): return ""
67 slice_urn=xrn.get_urn()
68 slice_hrn=xrn.get_hrn()
70 return self.driver.create_sliver (slice_urn, slice_hrn, creds, rspec_string, users, options)
72 def RenewSliver(self, api, xrn, creds, expiration_time, options):
73 call_id = options.get('call_id')
74 if Callids().already_handled(call_id): return True
77 slice_urn=xrn.get_urn()
78 slice_hrn=xrn.get_hrn()
80 return self.driver.renew_sliver (slice_urn, slice_hrn, creds, expiration_time, options)
82 def start_slice(self, api, xrn, creds):
83 (hrn, _) = urn_to_hrn(xrn)
84 slicename = hrn_to_pl_slicename(hrn)
85 slices = api.driver.GetSlices({'name': slicename}, ['slice_id'])
87 raise RecordNotFound(hrn)
88 slice_id = slices[0]['slice_id']
89 slice_tags = api.driver.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'}, ['slice_tag_id'])
90 # just remove the tag if it exists
92 api.driver.DeleteSliceTag(slice_tags[0]['slice_tag_id'])
96 def stop_slice(self, api, xrn, creds):
97 hrn, _ = urn_to_hrn(xrn)
98 slicename = hrn_to_pl_slicename(hrn)
99 slices = api.driver.GetSlices({'name': slicename}, ['slice_id'])
101 raise RecordNotFound(hrn)
102 slice_id = slices[0]['slice_id']
103 slice_tags = api.driver.GetSliceTags({'slice_id': slice_id, 'tagname': 'enabled'})
105 api.driver.AddSliceTag(slice_id, 'enabled', '0')
106 elif slice_tags[0]['value'] != "0":
107 tag_id = slice_tags[0]['slice_tag_id']
108 api.driver.UpdateSliceTag(tag_id, '0')
111 def reset_slice(self, api, xrn):
112 # XX not implemented at this interface
115 def DeleteSliver(self, api, xrn, creds, options):
116 call_id = options.get('call_id')
117 if Callids().already_handled(call_id): return ""
118 (hrn, _) = urn_to_hrn(xrn)
119 slicename = hrn_to_pl_slicename(hrn)
120 slices = api.driver.GetSlices({'name': slicename})
125 # determine if this is a peer slice
126 peer = peers.get_peer(api, hrn)
129 api.driver.UnBindObjectFromPeer('slice', slice['slice_id'], peer)
130 api.driver.DeleteSliceFromNodes(slicename, slice['node_ids'])
133 api.driver.BindObjectToPeer('slice', slice['slice_id'], peer, slice['peer_slice_id'])
136 def ListSlices(self, api, creds, options):
137 call_id = options.get('call_id')
138 if Callids().already_handled(call_id): return []
139 # look in cache first
140 if self.caching and api.cache:
141 slices = api.cache.get('slices')
146 slices = api.driver.GetSlices({'peer_id': None}, ['name'])
147 slice_hrns = [slicename_to_hrn(api.hrn, slice['name']) for slice in slices]
148 slice_urns = [hrn_to_urn(slice_hrn, 'slice') for slice_hrn in slice_hrns]
151 if self.caching and api.cache:
152 api.cache.add('slices', slice_urns)
156 def ListResources(self, api, creds, options):
157 call_id = options.get('call_id')
158 if Callids().already_handled(call_id): return ""
159 # get slice's hrn from options
160 xrn = options.get('geni_slice_urn', None)
161 cached = options.get('cached', True)
162 (hrn, _) = urn_to_hrn(xrn)
164 version_manager = VersionManager()
165 # get the rspec's return format from options
166 rspec_version = version_manager.get_version(options.get('geni_rspec_version'))
167 version_string = "rspec_%s" % (rspec_version)
169 #panos adding the info option to the caching key (can be improved)
170 if options.get('info'):
171 version_string = version_string + "_"+options.get('info', 'default')
173 # look in cache first
174 if self.caching and api.cache and not xrn and cached:
175 rspec = api.cache.get(version_string)
177 api.logger.info("aggregate.ListResources: returning cached value for hrn %s"%hrn)
180 #panos: passing user-defined options
181 #print "manager options = ",options
182 aggregate = PlAggregate(self.driver)
183 rspec = aggregate.get_rspec(slice_xrn=xrn, version=rspec_version, options=options)
186 if self.caching and api.cache and not xrn:
187 api.cache.add(version_string, rspec)
192 def GetTicket(self, api, xrn, creds, rspec, users, options):
194 (slice_hrn, _) = urn_to_hrn(xrn)
195 slices = PlSlices(self.driver)
196 peer = slices.get_peer(slice_hrn)
197 sfa_peer = slices.get_sfa_peer(slice_hrn)
199 # get the slice record
200 credential = api.getCredential()
201 interface = api.registries[api.hrn]
202 registry = api.server_proxy(interface, credential)
203 records = registry.Resolve(xrn, credential)
205 # make sure we get a local slice record
207 for tmp_record in records:
208 if tmp_record['type'] == 'slice' and \
209 not tmp_record['peer_authority']:
210 #Error (E0602, GetTicket): Undefined variable 'SliceRecord'
211 record = SliceRecord(dict=tmp_record)
213 raise RecordNotFound(slice_hrn)
215 # similar to CreateSliver, we must verify that the required records exist
216 # at this aggregate before we can issue a ticket
218 rspec = RSpec(rspec_string)
219 requested_attributes = rspec.version.get_slice_attributes()
221 # ensure site record exists
222 site = slices.verify_site(hrn, slice_record, peer, sfa_peer)
223 # ensure slice record exists
224 slice = slices.verify_slice(hrn, slice_record, peer, sfa_peer)
225 # ensure person records exists
226 persons = slices.verify_persons(hrn, slice, users, peer, sfa_peer)
227 # ensure slice attributes exists
228 slices.verify_slice_attributes(slice, requested_attributes)
231 slivers = slices.get_slivers(slice_hrn)
234 raise SliverDoesNotExist(slice_hrn)
239 'timestamp': int(time.time()),
240 'initscripts': initscripts,
245 object_gid = record.get_gid_object()
246 new_ticket = SfaTicket(subject = object_gid.get_subject())
247 new_ticket.set_gid_caller(api.auth.client_gid)
248 new_ticket.set_gid_object(object_gid)
249 new_ticket.set_issuer(key=api.key, subject=api.hrn)
250 new_ticket.set_pubkey(object_gid.get_pubkey())
251 new_ticket.set_attributes(data)
252 new_ticket.set_rspec(rspec)
253 #new_ticket.set_parent(api.auth.hierarchy.get_auth_ticket(auth_hrn))
257 return new_ticket.save_to_string(save_parents=True)