Skip to content

Commit

Permalink
Merge pull request #120 from ChameleonCloud/res_id_enforcement
Browse files Browse the repository at this point in the history
Res id enforcement
  • Loading branch information
Mark-Powers authored Nov 4, 2024
2 parents bbd20e8 + 12ea51c commit d89ab78
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 20 deletions.
4 changes: 2 additions & 2 deletions blazar/enforcement/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ class MaxLeaseUpdateWindowException(exceptions.NotAuthorized):
'seconds of the leases current end time.')


class ExternalServiceFilterException(exceptions.BlazarException):
class ExternalServiceFilterException(exceptions.NotAuthorized):
code = 400
msg_fmt = _('%(message)s')


class ExternalServiceUnsupportedHTTPResponse(exceptions.BlazarException):
code = 400
msg_fmt = _('External Service Filter returned a %(status)s http response. '
'Only 204 and 403 responses are supported.')
'Only 204 and 403 responses are supported.')
17 changes: 10 additions & 7 deletions blazar/manager/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,6 @@ def create_lease(self, lease_values):

allocations = self._allocation_candidates(
lease_values, reservations)
try:
self.enforcement.check_create(
context.current(), lease_values, reservations, allocations)
except common_ex.NotAuthorized as e:
LOG.error("Enforcement checks failed. %s", str(e))
raise common_ex.NotAuthorized(e)

events.append({'event_type': 'start_lease',
'time': start_date,
Expand Down Expand Up @@ -431,14 +425,22 @@ def create_lease(self, lease_values):
reservation['start_date'] = lease['start_date']
reservation['end_date'] = lease['end_date']
reservation['project_id'] = lease['project_id']
self._create_reservation(reservation)
reservation["id"] = self._create_reservation(reservation)
except Exception:
with save_and_reraise_exception():
LOG.exception("Failed to create reservation for a "
"lease. Rollback the lease and "
"associated reservations")
db_api.lease_destroy(lease_id)

try:
self.enforcement.check_create(
context.current(), lease_values, reservations, allocations)
except common_ex.NotAuthorized as e:
LOG.error("Enforcement checks failed. %s", str(e))
db_api.lease_destroy(lease_id)
raise common_ex.NotAuthorized(e)

try:
for event in events:
event['lease_id'] = lease['id']
Expand Down Expand Up @@ -808,6 +810,7 @@ def _create_reservation(self, values):
)
db_api.reservation_update(reservation['id'],
{'resource_id': resource_id})
return reservation["id"]

def _allocation_candidates(self, lease, reservations):
"""Returns dict by resource type of reservation candidates."""
Expand Down
20 changes: 12 additions & 8 deletions blazar/tests/enforcement/filters/test_external_service_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ def setUp(self):
CONF.set_override(
'external_service_base_endpoint', 'http://localhost',
group='enforcement')
CONF.set_override(
'external_service_token', 'test_token', group='enforcement')
self.addCleanup(CONF.clear_override, 'external_service_base_endpoint',
group='enforcement')

Expand All @@ -163,7 +165,7 @@ def test_check_create_allowed(self, post_mock):
self.filter.check_create(self.ctx, self.lease)
post_mock.assert_called_with(
"http://localhost/check-create",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"lease": {"is_lease": true}}')

Expand All @@ -175,7 +177,7 @@ def test_check_create_denied(self, post_mock):
self.ctx, self.lease)
post_mock.assert_called_with(
"http://localhost/check-create",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"lease": {"is_lease": true}}')

Expand All @@ -187,7 +189,7 @@ def test_check_create_failed(self, post_mock):
self.ctx, self.lease)
post_mock.assert_called_with(
"http://localhost/check-create",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"lease": {"is_lease": true}}')

Expand All @@ -197,7 +199,7 @@ def test_check_update_allowed(self, post_mock):
self.filter.check_update(self.ctx, self.old_lease, self.lease)
post_mock.assert_called_with(
"http://localhost/check-update",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"current_lease": {"is_old_lease": true}, '
'"lease": {"is_lease": true}}')
Expand All @@ -210,7 +212,7 @@ def test_check_update_denied(self, post_mock):
self.ctx, self.old_lease, self.lease)
post_mock.assert_called_with(
"http://localhost/check-update",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"current_lease": {"is_old_lease": true}, '
'"lease": {"is_lease": true}}')
Expand All @@ -224,7 +226,7 @@ def test_check_update_failed(self, post_mock):
self.ctx, self.old_lease, self.lease)
post_mock.assert_called_with(
"http://localhost/check-update",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"current_lease": {"is_old_lease": true}, '
'"lease": {"is_lease": true}}')
Expand All @@ -235,18 +237,20 @@ def test_on_end_success(self, post_mock):
self.filter.on_end(self.ctx, self.lease)
post_mock.assert_called_with(
"http://localhost/on-end",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"lease": {"is_lease": true}}')

@mock.patch("requests.post")
def test_on_end_failure(self, post_mock):
CONF.set_override(
'external_service_token', 'test_token', group='enforcement')
post_mock.return_value = FakeResponse500()
self.assertRaises(ExternalServiceFilterException,
self.filter.on_end,
self.ctx, self.lease)
post_mock.assert_called_with(
"http://localhost/on-end",
headers={'Content-Type': 'application/json'},
headers={'Content-Type': 'application/json', 'X-Auth-Token': 'test_token'},
data='{"context": {"is_context": true}, '
'"lease": {"is_lease": true}}')
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def setUp(self):
dict(
type='identity', endpoints=[
dict(
interface='internal', region=self.region,
interface='public', region=self.region,
url='https://fakeauth.com')
]
)
Expand Down
2 changes: 1 addition & 1 deletion blazar/tests/enforcement/test_enforcement.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def setUp(self):
dict(
type='identity', endpoints=[
dict(
interface='internal', region=self.region,
interface='public', region=self.region,
url='https://fakeauth.com')
]
)
Expand Down
3 changes: 2 additions & 1 deletion blazar/tests/manager/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@ def test_create_lease_without_required_params(self):

def test_create_lease_with_filter_exception(self):
lease_values = self.lease_values.copy()
self.lease_create.return_value = self.lease

self.enforcement.check_create.side_effect = (
enforcement_ex.MaxLeaseDurationException(lease_duration=200,
Expand All @@ -772,7 +773,7 @@ def test_create_lease_with_filter_exception(self):
self.assertRaises(exceptions.NotAuthorized,
self.manager.create_lease,
lease_values=lease_values)
self.lease_create.assert_not_called()
self.assertEqual(1, self.lease_create.call_count)

def test_update_lease_completed_lease_rename(self):
lease_values = {'name': 'renamed'}
Expand Down

0 comments on commit d89ab78

Please sign in to comment.