Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a max lease length and a default length #147

Merged
merged 1 commit into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion esi_leap/api/controllers/v1/lease.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@ def post(self, new_lease):
lease_dict['start_time'] = datetime.datetime.now()

if 'end_time' not in lease_dict:
lease_dict['end_time'] = datetime.datetime.max
lease_dict['end_time'] = lease_dict['start_time'] + \
datetime.timedelta(days=CONF.api.default_lease_time)
else:
utils.check_lease_length(cdict,
lease_dict['start_time'],
lease_dict['end_time'],
CONF.api.max_lease_time)

try:
utils.check_resource_admin(cdict, resource, request.project_id)
Expand Down
12 changes: 12 additions & 0 deletions esi_leap/api/controllers/v1/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from oslo_policy import policy as oslo_policy
from oslo_utils import uuidutils

import datetime

from esi_leap.common import exception
from esi_leap.common import keystone
from esi_leap.common import policy
Expand Down Expand Up @@ -167,3 +169,13 @@ def lease_get_dict_with_added_info(lease, project_list=None, node_list=None):
lease_dict['resource'] = resource.get_name(node_list)
lease_dict['resource_class'] = resource.get_resource_class(node_list)
return lease_dict


def check_lease_length(cdict, start_time, end_time, max_time):
if (end_time - start_time) > datetime.timedelta(days=max_time):
# Check if the current project is admin
# Only admin project can set a lease beyond the max length
try:
policy_authorize('esi_leap:lease:lease_admin', cdict, cdict)
except exception.HTTPForbidden:
raise exception.LeaseExceedMaxTimeRange(max_time=max_time)
6 changes: 6 additions & 0 deletions esi_leap/common/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ def __init__(self, message=None, **kwargs):
super(ESILeapException, self).__init__(message)


class LeaseExceedMaxTimeRange(ESILeapException):
code = http_client.FORBIDDEN
msg_fmt = _('Attempted to create lease with an invalid '
'time range. The max time range is %(max_time)s days.')


class HTTPForbidden(ESILeapException):
code = http_client.FORBIDDEN
msg_fmt = _('Access was denied to %(rule)s.')
Expand Down
2 changes: 2 additions & 0 deletions esi_leap/conf/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
cfg.IntOpt('api_workers'),
cfg.BoolOpt('enable_ssl_api', default=False),
cfg.StrOpt('default_resource_type', default='ironic_node'),
cfg.IntOpt('max_lease_time', default=21),
cfg.IntOpt('default_lease_time', default=7),
]


Expand Down
45 changes: 45 additions & 0 deletions esi_leap/tests/api/controllers/v1/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,3 +694,48 @@ def test_lease_get_dict_with_added_info(self, mock_gro, mock_gpn, mock_gn):
self.assertEqual(2, mock_gpn.call_count)
mock_gn.assert_called_once()
self.assertEqual(expected_output_dict, output_dict)


class TestCheckLeaseLength(testtools.TestCase):
def setUp(self):
super(TestCheckLeaseLength, self).setUp()
self.max_time = 21
self.start_time = datetime.datetime(2016, 7, 16, 19, 20, 30)
self.end_time = datetime.datetime(2016, 8, 16, 19, 20, 30)
self.end_time_1 = datetime.datetime(2016, 7, 20, 19, 20, 30)

@mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize')
def test_check_lease_length_admin_exceed_max(self, mock_authorize):
utils.check_lease_length(admin_ctx.to_policy_values(),
self.start_time,
self.end_time,
self.max_time)

mock_authorize.assert_called_once_with('esi_leap:lease:lease_admin',
admin_ctx.to_policy_values(),
admin_ctx.to_policy_values())

@mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize')
def test_check_lease_length_exception(self, mock_authorize):
mock_authorize.side_effect = exception.HTTPForbidden(
'esi_leap:lease:lease_admin')

self.assertRaises(exception.LeaseExceedMaxTimeRange,
utils.check_lease_length,
lessee_ctx.to_policy_values(),
self.start_time,
self.end_time,
self.max_time)

mock_authorize.assert_called_once_with('esi_leap:lease:lease_admin',
lessee_ctx.to_policy_values(),
lessee_ctx.to_policy_values())

@mock.patch('esi_leap.api.controllers.v1.utils.policy_authorize')
def test_check_lease_length_non_admin_valid(self, mock_authorize):
utils.check_lease_length(lessee_ctx.to_policy_values(),
self.start_time,
self.end_time_1,
self.max_time)

assert not mock_authorize.called