# retrieve configured granularity
granularity = self.api.config.PLC_RESERVATION_GRANULARITY
# the trick for rounding up rather than down
- if round_up: timestamp += (granularity-1)
+ if round_up:
+ timestamp += (granularity-1)
# round down
timestamp = (timestamp/granularity) * granularity
# return a SQL string
return Timestamp.sql_validate_utc(timestamp)
# round UP
- def validate_t_from(self,timestamp):
- return self.validate_time (timestamp, round_up=True)
+ def validate_t_from(self, timestamp):
+ return self.validate_time(timestamp, round_up=True)
# round DOWN
def validate_t_until (self, timestamp):
- return self.validate_time (timestamp, round_up=False)
+ return self.validate_time(timestamp, round_up=False)
class Leases(Table):
"""
can_update = ['name', 'instantiation', 'url', 'description', 'max_nodes']
+
class AddLeases(Method):
"""
Adds a new lease.
accepts = [
Auth(),
- Mixed(Node.fields['node_id'],[Node.fields['node_id']],
- Node.fields['hostname'],[Node.fields['hostname']],),
+ Mixed(Node.fields['node_id'], [Node.fields['node_id']],
+ Node.fields['hostname'], [Node.fields['hostname']],),
Mixed(Slice.fields['slice_id'],
Slice.fields['name']),
Mixed(Lease.fields['t_from']),
Mixed(Lease.fields['t_until']),
- ]
-
- returns = Parameter(dict, " 'new_ids' is the list of newly created ids, 'errors' is a list of error strings")
+ ]
- def call(self, auth, node_id_or_hostname_s, slice_id_or_name, t_from, t_until):
+ returns = Parameter(
+ dict,
+ " 'new_ids' is the list of newly created ids,"
+ "'errors' is a list of error strings")
- # xxx - round to plain hours somewhere
+ def call(self, auth, node_id_or_hostname_s, slice_id_or_name,
+ t_from, t_until):
# Get node information
nodes = Nodes(self.api, node_id_or_hostname_s)
if not nodes:
- raise PLCInvalidArgument, "No such node(s) %r"%node_id_or_hostname_s
+ raise PLCInvalidArgument(
+ "No such node(s) {}".format(node_id_or_hostname_s))
for node in nodes:
if node['node_type'] != 'reservable':
- raise PLCInvalidArgument, "Node %s is not reservable"%node['hostname']
+ raise PLCInvalidArgument(
+ "Node {} is not reservable".format(node['hostname']))
# Get slice information
slices = Slices(self.api, [slice_id_or_name])
if not slices:
- raise PLCInvalidArgument, "No such slice %r"%slice_id_or_name
+ raise PLCInvalidArgument(
+ "No such slice {}".format(slice_id_or_name))
slice = slices[0]
# check access
if self.caller['person_id'] in slice['person_ids']:
pass
elif 'pi' not in self.caller['roles']:
- raise PLCPermissionDenied, "Not a member of the specified slice"
+ raise PLCPermissionDenied(
+ "Not a member of the specified slice")
elif slice['site_id'] not in self.caller['site_ids']:
- raise PLCPermissionDenied, "Specified slice not associated with any of your sites"
+ raise PLCPermissionDenied(
+ "Specified slice not associated with any of your sites")
- # normalize timestamps
+ # normalize timestamps - use granularity to round up limits
t_from = Timestamp.sql_validate_utc(t_from)
t_until = Timestamp.sql_validate_utc(t_until)
- ########## create stuff
- errors=[]
- result_ids=[]
+ # create stuff
+ errors = []
+ result_ids = []
for node in nodes:
if node['peer_id'] is not None:
- errors.append("Cannot set lease on remote node %r"%node['hostname'])
+ errors.append("Cannot set lease on remote node {}"
+ .format(node['hostname']))
continue
# let the DB check for time consistency
try:
- lease = Lease (self.api, {'node_id':node['node_id'], 'slice_id': slice['slice_id'],
- 't_from':t_from, 't_until':t_until})
+ lease = Lease(self.api, {'node_id': node['node_id'],
+ 'slice_id': slice['slice_id'],
+ 't_from': t_from, 't_until': t_until})
lease.sync()
result_ids.append(lease['lease_id'])
- except Exception,e:
- errors.append("Could not create lease on n=%s s=%s [%s .. %s] -- %r" % \
- (node['hostname'],slice['name'],t_from,t_until,e))
+
+ except PLCDBError as e:
+ errors.append(
+ "Timeslot busy - could not create overlapping lease"
+ " on n={} s={} [{} .. {}]"
+ .format(node['hostname'], slice['name'], t_from, t_until))
+ nodes.remove(node)
+ except Exception as e:
+ errors.append(
+ "Could not create lease on n={} s={} [{} .. {}] -- {}"
+ .format(node['hostname'], slice['name'], t_from, t_until, e))
nodes.remove(node)
self.event_objects = {'Slice': [slice['slice_id']],
'Node': [node['node_id'] for node in nodes]}
- self.message = "New leases %r on n=%r s=%s [%s -> %s]" % \
- (result_ids,[node['hostname'] for node in nodes],slice['name'],t_from,t_until)
+ self.message = "New leases {} on n={} s={} [{} -> {}]"\
+ .format(result_ids, [node['hostname'] for node in nodes],
+ slice['name'], t_from, t_until)
- return {'new_ids': result_ids,
- 'errors': errors}
+ return {'new_ids': result_ids, 'errors': errors}
+from __future__ import print_function
+
from PLC.Faults import *
from PLC.Method import Method
from PLC.Parameter import Parameter, Mixed
can_update = lambda (field, value): field in ['t_from', 't_until', 'duration']
+
class UpdateLeases(Method):
"""
Updates the parameters of a (set of) existing lease(s) with the values in
accepts = [
Auth(),
- Mixed (Lease.fields['lease_id'],
- [Lease.fields['lease_id']]),
+ Mixed(Lease.fields['lease_id'],
+ [Lease.fields['lease_id']]),
lease_fields
- ]
+ ]
- returns = Parameter(dict, " 'updated_ids' is the list ids updated, 'errors' is a list of error strings")
+ returns = Parameter(
+ dict,
+ " 'updated_ids' is the list ids updated,"
+ "'errors' is a list of error strings")
- debug=False
+ debug = False
# debug=True
def call(self, auth, lease_ids, input_fields):
if 'duration' in input_fields:
if 't_from' in input_fields and 't_until' in input_fields:
- raise PLCInvalidArgument, "Cannot set t_from AND t_until AND duration"
+ raise PLCInvalidArgument(
+ "Cannot set t_from AND t_until AND duration")
# specify 'duration':0 to keep duration unchanged
- if input_fields['duration'] : input_fields['duration']=Duration.validate(input_fields['duration'])
+ if input_fields['duration']:
+ input_fields['duration'] = Duration.validate(
+ input_fields['duration'])
# Get lease information
leases = Leases(self.api, lease_ids)
if not leases:
- raise PLCInvalidArgument, "No such leases %r"%lease_ids
+ raise PLCInvalidArgument("No such leases {}".format(lease_ids))
# fetch related slices
- slices = Slices(self.api, [ lease['slice_id'] for lease in leases],['slice_id','person_ids'])
+ slices = Slices(self.api,
+ [lease['slice_id'] for lease in leases],
+ ['slice_id', 'person_ids'])
# create hash on slice_id
- slice_map = dict ( [ (slice['slice_id'],slice) for slice in slices ] )
+ slice_map = dict([(slice['slice_id'], slice) for slice in slices])
- updated_ids=[]
- errors=[]
+ updated_ids = []
+ errors = []
- lease_ids=[lease['lease_id'] for lease in leases]
+ lease_ids = [lease['lease_id'] for lease in leases]
for lease in leases:
if 'admin' not in self.caller['roles']:
- slice=slice_map[lease['slice_id']]
+ slice = slice_map[lease['slice_id']]
# check slices only once
- if not slice.has_key('verified'):
+ if 'verified' not in slice:
if self.caller['person_id'] in slice['person_ids']:
pass
elif 'pi' not in self.caller['roles']:
- raise PLCPermissionDenied, "Not a member of slice %r"%slice['name']
+ raise PLCPermissionDenied(
+ "Not a member of slice {}".format(slice['name']))
elif slice['site_id'] not in self.caller['site_ids']:
- raise PLCPermissionDenied, "Slice %r not associated with any of your sites"%slice['name']
- slice['verified']=True
+ raise PLCPermissionDenied(
+ "Slice {} not associated with any of your sites"
+ .format(slice['name']))
+ slice['verified'] = True
try:
- # we've ruled out already the case where all 3 (from, to, duration) where specified
+ # we've ruled out already the case where all 3 (from, to,
+ # duration) where specified
if 'duration' not in input_fields:
- lease_fields=input_fields
+ lease_fields = input_fields
else:
# all arithmetics on longs..
- duration=Duration.validate(input_fields['duration'])
+ duration = Duration.validate(input_fields['duration'])
# specify 'duration':0 to keep duration unchanged
if not duration:
- duration = Timestamp.cast_long(lease['t_until'])-Timestamp.cast_long(lease['t_from'])
+ duration = Timestamp.cast_long(
+ lease['t_until']) \
+ - Timestamp.cast_long(lease['t_from'])
if 't_from' in input_fields:
- lease_fields={'t_from':input_fields['t_from'],
- 't_until':Timestamp.cast_long(input_fields['from'])+duration}
+ lease_fields = {
+ 't_from': input_fields['t_from'],
+ 't_until': Timestamp.cast_long(
+ input_fields['from']) + duration}
elif 't_until' in input_fields:
- lease_fields={'t_from':Timestamp.cast_long(input_fields['t_until'])-duration,
- 't_until':input_fields['t_until']}
+ lease_fields = {
+ 't_from': Timestamp.cast_long(
+ input_fields['t_until']) - duration,
+ 't_until': input_fields['t_until']}
else:
- lease_fields={'t_until':Timestamp.cast_long(lease['t_from'])+duration}
+ lease_fields = {'t_until': Timestamp.cast_long(
+ lease['t_from']) + duration}
if UpdateLeases.debug:
- print 'lease_fields',lease_fields
- for k in [ 't_from', 't_until'] :
+ for k in ['t_from', 't_until']:
if k in lease_fields:
- print k,'aka',Timestamp.sql_validate_utc(lease_fields[k])
+ print(k, 'aka', Timestamp.sql_validate_utc(
+ lease_fields[k]))
lease.update(lease_fields)
lease.sync()
updated_ids.append(lease['lease_id'])
- except Exception,e:
- errors.append("Could not update lease %d - check new time limits ? -- %r"%(lease['lease_id'],e))
+ except Exception, e:
+ errors.append(
+ "Could not update lease {} - check new time limits ? -- {}"
+ .format(lease['lease_id'], e))
# Logging variables
self.event_objects = {'Lease': updated_ids}
- self.message = 'lease %r updated: %s' % (lease_ids, ", ".join(input_fields.keys()))
+ self.message = 'lease {} updated: {}'\
+ .format(lease_ids, ", ".join(input_fields.keys()))
- return {'updated_ids' : updated_ids,
- 'errors' : errors }
+ return {'updated_ids': updated_ids,
+ 'errors': errors}
for this object, and are not marked as a read-only Parameter.
"""
- if obj is None: obj = self
+ if obj is None:
+ obj = self
db_fields = self.api.db.fields(self.table_name)
- return dict ( [ (key,value) for (key,value) in obj.items()
+ return dict ( [ (key, value) for (key, value) in obj.items()
if key in db_fields and
- Row.is_writable(key,value,self.fields) ] )
+ Row.is_writable(key, value, self.fields) ] )
def tag_fields (self, obj=None):
"""
else:
# Update existing row
columns = ["%s = %s" % (key, value) for (key, value) in zip(keys, values)]
- sql = "UPDATE %s SET " % self.table_name + \
- ", ".join(columns) + \
- " WHERE %s = %s" % \
- (self.primary_key,
- self.api.db.param(self.primary_key, self[self.primary_key]))
+ sql = "UPDATE {} SET {} WHERE {} = {}"\
+ .format(self.table_name,
+ ", ".join(columns),
+ self.primary_key,
+ self.api.db.param(self.primary_key, self[self.primary_key]))
self.api.db.do(sql, db_fields)