Rollback quota in os_tenant_network
when we call API with 'os_tenant_networks' to delete an existing network it might fail due to unexpected reason, we should rollback the quota we reserved otherwise we will face no quota later. Change-Id: Ic74a7a8df337070f17b1ea6916809fa93880a287 Closes-Bug: 1296489
This commit is contained in:
parent
cded075dcf
commit
6169e05a48
|
@ -115,6 +115,7 @@ class NetworkController(object):
|
|||
def delete(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
reservation = None
|
||||
try:
|
||||
if CONF.enable_network_quota:
|
||||
reservation = QUOTAS.reserve(context, networks=-1)
|
||||
|
@ -125,19 +126,27 @@ class NetworkController(object):
|
|||
|
||||
LOG.info(_LI("Deleting network with id %s"), id)
|
||||
|
||||
def _rollback_quota(reservation):
|
||||
if CONF.enable_network_quota and reservation:
|
||||
QUOTAS.rollback(context, reservation)
|
||||
|
||||
try:
|
||||
self.network_api.delete(context, id)
|
||||
if CONF.enable_network_quota and reservation:
|
||||
QUOTAS.commit(context, reservation)
|
||||
response = exc.HTTPAccepted()
|
||||
except exception.PolicyNotAuthorized as e:
|
||||
_rollback_quota(reservation)
|
||||
raise exc.HTTPForbidden(explanation=str(e))
|
||||
except exception.NetworkInUse as e:
|
||||
_rollback_quota(reservation)
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
except exception.NetworkNotFound:
|
||||
_rollback_quota(reservation)
|
||||
msg = _("Network not found")
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
if CONF.enable_network_quota and reservation:
|
||||
QUOTAS.commit(context, reservation)
|
||||
response = exc.HTTPAccepted()
|
||||
|
||||
return response
|
||||
|
||||
def create(self, req, body):
|
||||
|
|
|
@ -19,12 +19,14 @@ import datetime
|
|||
import math
|
||||
import uuid
|
||||
|
||||
import mock
|
||||
import netaddr
|
||||
from oslo.config import cfg
|
||||
import webob
|
||||
|
||||
from nova.api.openstack.compute.contrib import networks_associate
|
||||
from nova.api.openstack.compute.contrib import os_networks as networks
|
||||
from nova.api.openstack.compute.contrib import os_tenant_networks as tnet
|
||||
import nova.context
|
||||
from nova import exception
|
||||
from nova import test
|
||||
|
@ -394,3 +396,42 @@ class NetworksTest(test.NoDBTestCase):
|
|||
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||
controller._disassociate_host_and_project,
|
||||
req, uuid, {'disassociate': None})
|
||||
|
||||
|
||||
class TenantNetworksTest(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super(TenantNetworksTest, self).setUp()
|
||||
self.controller = tnet.NetworkController()
|
||||
self.flags(enable_network_quota=True)
|
||||
|
||||
@mock.patch('nova.quota.QUOTAS.reserve')
|
||||
@mock.patch('nova.quota.QUOTAS.rollback')
|
||||
@mock.patch('nova.network.api.API.delete')
|
||||
def _test_network_delete_exception(self, ex, expex, delete_mock,
|
||||
rollback_mock, reserve_mock):
|
||||
req = fakes.HTTPRequest.blank('/v2/1234/os-tenant-networks')
|
||||
ctxt = req.environ['nova.context']
|
||||
|
||||
reserve_mock.return_value = 'rv'
|
||||
delete_mock.side_effect = ex
|
||||
|
||||
self.assertRaises(expex, self.controller.delete, req, 1)
|
||||
|
||||
delete_mock.assert_called_once_with(ctxt, 1)
|
||||
rollback_mock.assert_called_once_with(ctxt, 'rv')
|
||||
reserve_mock.assert_called_once_with(ctxt, networks=-1)
|
||||
|
||||
def test_network_delete_exception_network_not_found(self):
|
||||
ex = exception.NetworkNotFound(network_id=1)
|
||||
expex = webob.exc.HTTPNotFound
|
||||
self._test_network_delete_exception(ex, expex)
|
||||
|
||||
def test_network_delete_exception_policy_failed(self):
|
||||
ex = exception.PolicyNotAuthorized(action='dummy')
|
||||
expex = webob.exc.HTTPForbidden
|
||||
self._test_network_delete_exception(ex, expex)
|
||||
|
||||
def test_network_delete_exception_network_in_use(self):
|
||||
ex = exception.NetworkInUse(network_id=1)
|
||||
expex = webob.exc.HTTPConflict
|
||||
self._test_network_delete_exception(ex, expex)
|
||||
|
|
Loading…
Reference in New Issue