Catch NotImplementedError on Network Associate
When trying to associate/disassociate a network both for project/host
using neutron a 500 error is returned because the "associate" method is
not even defined in neutronv2 api.
The changes are:
* Add missing associate method to neutronv2 api and raise
NotImplementedError
* Catch NotImplementedError on the API to return the proper error
code on network associate/disassociate operations.
* Catch NotImplementedError on os_network when associating a network
Closes-Bug: #1293539
Change-Id: I75b980500f0f171b065b7606baf201ab89848e92
This commit is contained in:
@@ -39,6 +39,10 @@ class NetworkAssociateActionController(wsgi.Controller):
|
|||||||
except exception.NetworkNotFound:
|
except exception.NetworkNotFound:
|
||||||
msg = _("Network not found")
|
msg = _("Network not found")
|
||||||
raise exc.HTTPNotFound(explanation=msg)
|
raise exc.HTTPNotFound(explanation=msg)
|
||||||
|
except NotImplementedError:
|
||||||
|
msg = _('Disassociate host is not implemented by the configured '
|
||||||
|
'Network API')
|
||||||
|
raise exc.HTTPNotImplemented(explanation=msg)
|
||||||
return exc.HTTPAccepted()
|
return exc.HTTPAccepted()
|
||||||
|
|
||||||
@wsgi.action("disassociate_project")
|
@wsgi.action("disassociate_project")
|
||||||
@@ -51,6 +55,11 @@ class NetworkAssociateActionController(wsgi.Controller):
|
|||||||
except exception.NetworkNotFound:
|
except exception.NetworkNotFound:
|
||||||
msg = _("Network not found")
|
msg = _("Network not found")
|
||||||
raise exc.HTTPNotFound(explanation=msg)
|
raise exc.HTTPNotFound(explanation=msg)
|
||||||
|
except NotImplementedError:
|
||||||
|
msg = _('Disassociate project is not implemented by the '
|
||||||
|
'configured Network API')
|
||||||
|
raise exc.HTTPNotImplemented(explanation=msg)
|
||||||
|
|
||||||
return exc.HTTPAccepted()
|
return exc.HTTPAccepted()
|
||||||
|
|
||||||
@wsgi.action("associate_host")
|
@wsgi.action("associate_host")
|
||||||
@@ -64,6 +73,11 @@ class NetworkAssociateActionController(wsgi.Controller):
|
|||||||
except exception.NetworkNotFound:
|
except exception.NetworkNotFound:
|
||||||
msg = _("Network not found")
|
msg = _("Network not found")
|
||||||
raise exc.HTTPNotFound(explanation=msg)
|
raise exc.HTTPNotFound(explanation=msg)
|
||||||
|
except NotImplementedError:
|
||||||
|
msg = _('Associate host is not implemented by the configured '
|
||||||
|
'Network API')
|
||||||
|
raise exc.HTTPNotImplemented(explanation=msg)
|
||||||
|
|
||||||
return exc.HTTPAccepted()
|
return exc.HTTPAccepted()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ class NetworkController(wsgi.Controller):
|
|||||||
except exception.NetworkNotFound:
|
except exception.NetworkNotFound:
|
||||||
msg = _("Network not found")
|
msg = _("Network not found")
|
||||||
raise exc.HTTPNotFound(explanation=msg)
|
raise exc.HTTPNotFound(explanation=msg)
|
||||||
|
except NotImplementedError:
|
||||||
|
msg = _('Disassociate network is not implemented by the '
|
||||||
|
'configured Network API')
|
||||||
|
raise exc.HTTPNotImplemented(explanation=msg)
|
||||||
return exc.HTTPAccepted()
|
return exc.HTTPAccepted()
|
||||||
|
|
||||||
def show(self, req, id):
|
def show(self, req, id):
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ update_instance_info_cache = network_api.update_instance_cache_with_nw_info
|
|||||||
|
|
||||||
class API(base.Base):
|
class API(base.Base):
|
||||||
"""API for interacting with the neutron 2.x API."""
|
"""API for interacting with the neutron 2.x API."""
|
||||||
|
_sentinel = object()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(API, self).__init__()
|
super(API, self).__init__()
|
||||||
@@ -751,6 +752,11 @@ class API(base.Base):
|
|||||||
"""Disassociate a network for client."""
|
"""Disassociate a network for client."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def associate(self, context, network_uuid, host=_sentinel,
|
||||||
|
project=_sentinel):
|
||||||
|
"""Associate a network for client."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
def get_fixed_ip(self, context, id):
|
def get_fixed_ip(self, context, id):
|
||||||
"""Get a fixed ip from the id."""
|
"""Get a fixed ip from the id."""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import nova.context
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.api.openstack import fakes
|
from nova.tests.api.openstack import fakes
|
||||||
|
import nova.utils
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
@@ -202,6 +203,7 @@ class NetworksTest(test.NoDBTestCase):
|
|||||||
self.associate_controller = networks_associate\
|
self.associate_controller = networks_associate\
|
||||||
.NetworkAssociateActionController(self.fake_network_api)
|
.NetworkAssociateActionController(self.fake_network_api)
|
||||||
fakes.stub_out_networking(self.stubs)
|
fakes.stub_out_networking(self.stubs)
|
||||||
|
nova.utils.reset_is_neutron()
|
||||||
fakes.stub_out_rate_limiting(self.stubs)
|
fakes.stub_out_rate_limiting(self.stubs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -347,3 +349,41 @@ class NetworksTest(test.NoDBTestCase):
|
|||||||
res_dict = self.controller.create(req, large_network)
|
res_dict = self.controller.create(req, large_network)
|
||||||
self.assertEqual(res_dict['network']['cidr'],
|
self.assertEqual(res_dict['network']['cidr'],
|
||||||
large_network['network']['cidr'])
|
large_network['network']['cidr'])
|
||||||
|
|
||||||
|
def test_network_neutron_associate_not_implemented(self):
|
||||||
|
uuid = FAKE_NETWORKS[1]['uuid']
|
||||||
|
self.flags(network_api_class='nova.network.neutronv2.api.API')
|
||||||
|
assoc_ctrl = networks_associate.NetworkAssociateActionController()
|
||||||
|
|
||||||
|
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s/action' % uuid)
|
||||||
|
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||||
|
assoc_ctrl._associate_host,
|
||||||
|
req, uuid, {'associate_host': "TestHost"})
|
||||||
|
|
||||||
|
def test_network_neutron_disassociate_project_not_implemented(self):
|
||||||
|
uuid = FAKE_NETWORKS[1]['uuid']
|
||||||
|
self.flags(network_api_class='nova.network.neutronv2.api.API')
|
||||||
|
assoc_ctrl = networks_associate.NetworkAssociateActionController()
|
||||||
|
|
||||||
|
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s/action' % uuid)
|
||||||
|
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||||
|
assoc_ctrl._disassociate_project_only,
|
||||||
|
req, uuid, {'disassociate_project': None})
|
||||||
|
|
||||||
|
def test_network_neutron_disassociate_host_not_implemented(self):
|
||||||
|
uuid = FAKE_NETWORKS[1]['uuid']
|
||||||
|
self.flags(network_api_class='nova.network.neutronv2.api.API')
|
||||||
|
assoc_ctrl = networks_associate.NetworkAssociateActionController()
|
||||||
|
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s/action' % uuid)
|
||||||
|
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||||
|
assoc_ctrl._disassociate_host_only,
|
||||||
|
req, uuid, {'disassociate_host': None})
|
||||||
|
|
||||||
|
def test_network_neutron_disassociate_not_implemented(self):
|
||||||
|
uuid = FAKE_NETWORKS[1]['uuid']
|
||||||
|
self.flags(network_api_class='nova.network.neutronv2.api.API')
|
||||||
|
controller = networks.NetworkController()
|
||||||
|
req = fakes.HTTPRequest.blank('/v2/1234/os-networks/%s/action' % uuid)
|
||||||
|
self.assertRaises(webob.exc.HTTPNotImplemented,
|
||||||
|
controller._disassociate_host_and_project,
|
||||||
|
req, uuid, {'disassociate': None})
|
||||||
|
|||||||
@@ -2091,6 +2091,12 @@ class TestNeutronv2Portbinding(TestNeutronv2Base):
|
|||||||
api.migrate_instance_finish,
|
api.migrate_instance_finish,
|
||||||
self.context, self.instance, migration)
|
self.context, self.instance, migration)
|
||||||
|
|
||||||
|
def test_associate_not_implemented(self):
|
||||||
|
api = neutronapi.API()
|
||||||
|
self.assertRaises(NotImplementedError,
|
||||||
|
api.associate,
|
||||||
|
self.context, 'id')
|
||||||
|
|
||||||
|
|
||||||
class TestNeutronv2ExtraDhcpOpts(TestNeutronv2Base):
|
class TestNeutronv2ExtraDhcpOpts(TestNeutronv2Base):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user