1 from sfa.util.faults import SfaInvalidArgument, InvalidRSpec, SfatablesRejected
2 from sfa.util.sfatime import datetime_to_string
3 from sfa.util.xrn import Xrn, urn_to_hrn
4 from sfa.util.method import Method
5 from sfa.util.sfatablesRuntime import run_sfatables
6 from sfa.trust.credential import Credential
7 from sfa.storage.parameter import Parameter, Mixed
8 from sfa.rspecs.rspec import RSpec
9 from sfa.util.sfalogging import logger
11 class Allocate(Method):
13 Allocate resources as described in a request RSpec argument
14 to a slice with the named URN. On success, one or more slivers
15 are allocated, containing resources satisfying the request, and
16 assigned to the given slice. This method returns a listing and
17 description of the resources reserved for the slice by this
18 operation, in the form of a manifest RSpec. Allocated slivers
19 are held for an aggregate-determined period. Clients must Renew
20 or Provision slivers before the expiration time (given in the
21 return struct), or the aggregate will automatically Delete them.
23 @param slice_urn (string) URN of slice to allocate to
24 @param credentials (dict) of credentials
25 @param rspec (string) rspec to allocate
28 The PL driver implements here an important option named
29 'append' that affects the management of slice tags.
30 It is recommended to set this option to True, and to not pass
31 any slice tag in the incoming rspec, in which case
32 you are guaranteed to leave slice tags alone.
34 See also http://svn.planet-lab.org/wiki/SFASliceTags
37 interfaces = ['aggregate', 'slicemgr']
39 Parameter(str, "Slice URN"),
40 Parameter(type([dict]), "List of credentials"),
41 Parameter(str, "RSpec"),
42 Parameter(dict, "options"),
44 returns = Parameter(str, "Allocated RSpec")
46 def call(self, xrn, creds, rspec, options):
47 xrn = Xrn(xrn, type='slice')
49 # Find the valid credentials
50 valid_creds = self.api.auth.checkCredentialsSpeaksFor(creds, 'createsliver', xrn.get_hrn(), options=options)
51 the_credential = Credential(cred=valid_creds[0])
53 # use the expiration from the first valid credential to determine when
54 # the slivers should expire.
55 expiration = datetime_to_string(the_credential.expiration)
57 self.api.logger.debug("Allocate, received expiration from credential: %s"%expiration)
59 # turned off, as passing an empty rspec is indeed useful for cleaning up the slice
60 # # make sure request is not empty
61 # slivers = RSpec(rspec).version.get_nodes_with_slivers()
63 # raise InvalidRSpec("Missing <sliver_type> or <sliver> element. Request rspec must explicitly allocate slivers")
65 # flter rspec through sfatables
66 if self.api.interface in ['aggregate']:
67 chain_name = 'INCOMING'
68 elif self.api.interface in ['slicemgr']:
69 chain_name = 'FORWARD-INCOMING'
70 self.api.logger.debug("Allocate: sfatables on chain %s"%chain_name)
71 actual_caller_hrn = the_credential.actual_caller_hrn()
72 self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, actual_caller_hrn, xrn.get_hrn(), self.name))
73 rspec = run_sfatables(chain_name, xrn.get_hrn(), actual_caller_hrn, rspec)
74 # turned off, as passing an empty rspec is indeed useful for cleaning up the slice
75 # slivers = RSpec(rspec).version.get_nodes_with_slivers()
77 # raise SfatablesRejected(slice_xrn)
79 # pass this to the driver code in case they need it
80 options['actual_caller_hrn'] = actual_caller_hrn
81 result = self.api.manager.Allocate(self.api, xrn.get_urn(), creds, rspec, expiration, options)