1 # Thierry Parmentelat -- INRIA
3 from PLC.Faults import *
4 from PLC.Auth import Auth
5 from PLC.Method import Method
6 from PLC.Parameter import Parameter, Mixed
7 from PLC.Table import Row
9 from PLC.Leases import Leases, Lease
10 from PLC.Nodes import Nodes, Node
11 from PLC.Slices import Slices, Slice
12 from PLC.Timestamp import Timestamp
14 can_update = ['name', 'instantiation', 'url', 'description', 'max_nodes']
16 class AddLeases(Method):
19 Mandatory arguments are node(s), slice, t_from and t_until
20 times can be either integers, datetime's, or human readable (see Timestamp)
22 PIs may only add leases associated with their own sites (i.e.,
23 to a slice that belongs to their site).
24 Users may only add leases associated with their own slices.
26 Returns the new lease_ids if successful, faults otherwise.
29 roles = ['admin', 'pi', 'user']
33 Mixed(Node.fields['node_id'],[Node.fields['node_id']],
34 Node.fields['hostname'],[Node.fields['hostname']],),
35 Mixed(Slice.fields['slice_id'],
36 Slice.fields['name']),
37 Mixed(Lease.fields['t_from']),
38 Mixed(Lease.fields['t_until']),
41 returns = Parameter(dict, " 'new_ids' is the list of newly created ids, 'errors' is a list of error strings")
43 def call(self, auth, node_id_or_hostname_s, slice_id_or_name, t_from, t_until):
45 # xxx - round to plain hours somewhere
47 # Get node information
48 nodes = Nodes(self.api, node_id_or_hostname_s)
50 raise PLCInvalidArgument, "No such node(s) %r"%node_id_or_hostname_s
52 if node['node_type'] != 'reservable':
53 raise PLCInvalidArgument, "Node %s is not reservable"%node['hostname']
55 # Get slice information
56 slices = Slices(self.api, [slice_id_or_name])
58 raise PLCInvalidArgument, "No such slice %r"%slice_id_or_name
62 if 'admin' not in self.caller['roles']:
63 if self.caller['person_id'] in slice['person_ids']:
65 elif 'pi' not in self.caller['roles']:
66 raise PLCPermissionDenied, "Not a member of the specified slice"
67 elif slice['site_id'] not in self.caller['site_ids']:
68 raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
70 # normalize timestamps
71 t_from = Timestamp.sql_validate_utc(t_from)
72 t_until = Timestamp.sql_validate_utc(t_until)
74 ########## create stuff
78 if node['peer_id'] is not None:
79 errors.append("Cannot set lease on remote node %r"%node['hostname'])
81 # let the DB check for time consistency
83 lease = Lease (self.api, {'node_id':node['node_id'], 'slice_id': slice['slice_id'],
84 't_from':t_from, 't_until':t_until})
86 result_ids.append(lease['lease_id'])
88 errors.append("Could not create lease on n=%s s=%s [%s .. %s] -- %r" % \
89 (node['hostname'],slice['name'],t_from,t_until,e))
92 self.event_objects = {'Slice': [slice['slice_id']],
93 'Node': [node['node_id'] for node in nodes]}
94 self.message = "New leases %r on n=%r s=%s [%s -> %s]" % \
95 (result_ids,[node['hostname'] for node in nodes],slice['name'],t_from,t_until)
97 return {'new_ids': result_ids,