Merge "Returns 503 if the NVP cluster is in maintenance mode"

This commit is contained in:
Jenkins 2013-08-16 18:40:27 +00:00 committed by Gerrit Code Review
commit b04837e0a5
7 changed files with 79 additions and 12 deletions

View File

@ -59,7 +59,7 @@ class NotAuthorized(NeutronException):
class ServiceUnavailable(NeutronException): class ServiceUnavailable(NeutronException):
message = _("The service is unailable") message = _("The service is unavailable")
class AdminRequired(NotAuthorized): class AdminRequired(NotAuthorized):

View File

@ -757,7 +757,9 @@ class NvpPluginV2(db_base_plugin_v2.NeutronDbPluginV2,
base.FAULT_MAP.update({nvp_exc.NvpInvalidNovaZone: base.FAULT_MAP.update({nvp_exc.NvpInvalidNovaZone:
webob.exc.HTTPBadRequest, webob.exc.HTTPBadRequest,
nvp_exc.NvpNoMorePortsException: nvp_exc.NvpNoMorePortsException:
webob.exc.HTTPBadRequest}) webob.exc.HTTPBadRequest,
nvp_exc.MaintenanceInProgress:
webob.exc.HTTPServiceUnavailable})
def _handle_provider_create(self, context, attrs): def _handle_provider_create(self, context, attrs):
# NOTE(salvatore-orlando): This method has been borrowed from # NOTE(salvatore-orlando): This method has been borrowed from

View File

@ -147,7 +147,7 @@ class NVPApiHelper(client_eventlet.NvpApiClientEventlet):
if status in self.error_codes: if status in self.error_codes:
LOG.error(_("Received error code: %s"), status) LOG.error(_("Received error code: %s"), status)
LOG.error(_("Server Error Message: %s"), response.body) LOG.error(_("Server Error Message: %s"), response.body)
self.error_codes[status](self) self.error_codes[status](self, response)
# Continue processing for non-error condition. # Continue processing for non-error condition.
if (status != httplib.OK and status != httplib.CREATED if (status != httplib.OK and status != httplib.CREATED
@ -174,19 +174,22 @@ class NVPApiHelper(client_eventlet.NvpApiClientEventlet):
'Plugin might not work as expected.')) 'Plugin might not work as expected.'))
return self._nvp_version return self._nvp_version
def fourZeroFour(self): def fourZeroFour(self, response=None):
raise ResourceNotFound() raise ResourceNotFound()
def fourZeroNine(self): def fourZeroNine(self, response=None):
raise Conflict() raise Conflict()
def fiveZeroThree(self): def fiveZeroThree(self, response=None):
raise ServiceUnavailable() raise ServiceUnavailable()
def fourZeroThree(self): def fourZeroThree(self, response=None):
raise Forbidden() if 'read-only' in response.body:
raise ReadOnlyMode()
else:
raise Forbidden()
def zero(self): def zero(self, response=None):
raise NvpApiException() raise NvpApiException()
# TODO(del): ensure error_codes are handled/raised appropriately # TODO(del): ensure error_codes are handled/raised appropriately
@ -247,5 +250,9 @@ class Forbidden(NvpApiException):
"referenced resource.") "referenced resource.")
class ReadOnlyMode(Forbidden):
message = _("Create/Update actions are forbidden when in read-only mode.")
class RequestTimeout(NvpApiException): class RequestTimeout(NvpApiException):
message = _("The request has timed out.") message = _("The request has timed out.")

View File

@ -56,3 +56,9 @@ class NvpNatRuleMismatch(NvpPluginException):
class NvpInvalidAttachmentType(NvpPluginException): class NvpInvalidAttachmentType(NvpPluginException):
message = _("Invalid NVP attachment type '%(attachment_type)s'") message = _("Invalid NVP attachment type '%(attachment_type)s'")
class MaintenanceInProgress(NvpPluginException):
message = _("The networking backend is currently in maintenance mode and "
"therefore unable to accept requests which modify its state. "
"Please try later.")

View File

@ -950,6 +950,8 @@ def do_request(*args, **kwargs):
return json.loads(res) return json.loads(res)
except NvpApiClient.ResourceNotFound: except NvpApiClient.ResourceNotFound:
raise exception.NotFound() raise exception.NotFound()
except NvpApiClient.ReadOnlyMode:
raise nvp_exc.MaintenanceInProgress()
def mk_body(**kwargs): def mk_body(**kwargs):

View File

@ -30,6 +30,7 @@ from neutron.extensions import providernet as pnet
from neutron.extensions import securitygroup as secgrp from neutron.extensions import securitygroup as secgrp
from neutron import manager from neutron import manager
from neutron.openstack.common import uuidutils from neutron.openstack.common import uuidutils
from neutron.plugins.nicira.common import exceptions as nvp_exc
from neutron.plugins.nicira.dbexts import nicira_db from neutron.plugins.nicira.dbexts import nicira_db
from neutron.plugins.nicira.dbexts import nicira_qos_db as qos_db from neutron.plugins.nicira.dbexts import nicira_qos_db as qos_db
from neutron.plugins.nicira.extensions import nvp_networkgw from neutron.plugins.nicira.extensions import nvp_networkgw
@ -192,6 +193,22 @@ class TestNiciraPortsV2(NiciraPluginV2TestCase,
webob.exc.HTTPInternalServerError.code) webob.exc.HTTPInternalServerError.code)
self._verify_no_orphan_left(net_id) self._verify_no_orphan_left(net_id)
def test_create_port_maintenance_returns_503(self):
with self.network() as net:
with mock.patch.object(nvplib, 'do_request',
side_effect=nvp_exc.MaintenanceInProgress):
data = {'port': {'network_id': net['network']['id'],
'admin_state_up': False,
'fixed_ips': [],
'tenant_id': self._tenant_id}}
plugin = manager.NeutronManager.get_plugin()
with mock.patch.object(plugin, 'get_network',
return_value=net['network']):
port_req = self.new_create_request('ports', data, self.fmt)
res = port_req.get_response(self.api)
self.assertEqual(webob.exc.HTTPServiceUnavailable.code,
res.status_int)
class TestNiciraNetworksV2(test_plugin.TestNetworksV2, class TestNiciraNetworksV2(test_plugin.TestNetworksV2,
NiciraPluginV2TestCase): NiciraPluginV2TestCase):
@ -276,6 +293,17 @@ class TestNiciraNetworksV2(test_plugin.TestNetworksV2,
# Assert neutron name is not truncated # Assert neutron name is not truncated
self.assertEqual(net['network']['name'], name) self.assertEqual(net['network']['name'], name)
def test_create_network_maintenance_returns_503(self):
data = {'network': {'name': 'foo',
'admin_state_up': True,
'tenant_id': self._tenant_id}}
with mock.patch.object(nvplib, 'do_request',
side_effect=nvp_exc.MaintenanceInProgress):
net_req = self.new_create_request('networks', data, self.fmt)
res = net_req.get_response(self.api)
self.assertEqual(webob.exc.HTTPServiceUnavailable.code,
res.status_int)
class NiciraPortSecurityTestCase(psec.PortSecurityDBTestCase): class NiciraPortSecurityTestCase(psec.PortSecurityDBTestCase):
@ -706,6 +734,23 @@ class TestNiciraL3NatTestCase(test_l3_plugin.L3NatDBTestCase,
self.assertIsNone(body['floatingip']['port_id']) self.assertIsNone(body['floatingip']['port_id'])
self.assertIsNone(body['floatingip']['fixed_ip_address']) self.assertIsNone(body['floatingip']['fixed_ip_address'])
def test_create_router_maintenance_returns_503(self):
with self._create_l3_ext_network() as net:
with self.subnet(network=net) as s:
with mock.patch.object(
nvplib,
'do_request',
side_effect=nvp_exc.MaintenanceInProgress):
data = {'router': {'tenant_id': 'whatever'}}
data['router']['name'] = 'router1'
data['router']['external_gateway_info'] = {
'network_id': s['subnet']['network_id']}
router_req = self.new_create_request(
'routers', data, self.fmt)
res = router_req.get_response(self.ext_api)
self.assertEqual(webob.exc.HTTPServiceUnavailable.code,
res.status_int)
class NvpQoSTestExtensionManager(object): class NvpQoSTestExtensionManager(object):

View File

@ -1318,7 +1318,7 @@ class TestNvplibLogicalPorts(NvplibTestCase):
self.assertIn(res_port['uuid'], switch_port_uuids) self.assertIn(res_port['uuid'], switch_port_uuids)
class TestNvplibClusterVersion(NvplibTestCase): class TestNvplibClusterManagement(NvplibTestCase):
def test_get_cluster_version(self): def test_get_cluster_version(self):
@ -1330,7 +1330,6 @@ class TestNvplibClusterVersion(NvplibTestCase):
return {'result_count': 1, return {'result_count': 1,
'results': [{'uuid': 'xyz'}]} 'results': [{'uuid': 'xyz'}]}
# mock do_request
with mock.patch.object(nvplib, 'do_request', new=fakedorequest): with mock.patch.object(nvplib, 'do_request', new=fakedorequest):
version = nvplib.get_cluster_version('whatever') version = nvplib.get_cluster_version('whatever')
self.assertEqual(version, '3.0') self.assertEqual(version, '3.0')
@ -1341,11 +1340,17 @@ class TestNvplibClusterVersion(NvplibTestCase):
if 'node' in uri: if 'node' in uri:
return {'result_count': 0} return {'result_count': 0}
# mock do_request
with mock.patch.object(nvplib, 'do_request', new=fakedorequest): with mock.patch.object(nvplib, 'do_request', new=fakedorequest):
version = nvplib.get_cluster_version('whatever') version = nvplib.get_cluster_version('whatever')
self.assertIsNone(version) self.assertIsNone(version)
def test_cluster_in_readonly_mode(self):
with mock.patch.object(self.fake_cluster.api_client,
'request',
side_effect=NvpApiClient.ReadOnlyMode):
self.assertRaises(nvp_exc.MaintenanceInProgress,
nvplib.do_request, cluster=self.fake_cluster)
def _nicira_method(method_name, module_name='nvplib'): def _nicira_method(method_name, module_name='nvplib'):
return '%s.%s.%s' % ('neutron.plugins.nicira', module_name, method_name) return '%s.%s.%s' % ('neutron.plugins.nicira', module_name, method_name)