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