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:
Leandro I. Costantino 2014-03-17 09:09:04 -03:00
parent 9de2e7382e
commit f349b7c806
5 changed files with 70 additions and 0 deletions

View File

@ -39,6 +39,10 @@ class NetworkAssociateActionController(wsgi.Controller):
except exception.NetworkNotFound:
msg = _("Network not found")
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()
@wsgi.action("disassociate_project")
@ -51,6 +55,11 @@ class NetworkAssociateActionController(wsgi.Controller):
except exception.NetworkNotFound:
msg = _("Network not found")
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()
@wsgi.action("associate_host")
@ -64,6 +73,11 @@ class NetworkAssociateActionController(wsgi.Controller):
except exception.NetworkNotFound:
msg = _("Network not found")
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()

View File

@ -77,6 +77,10 @@ class NetworkController(wsgi.Controller):
except exception.NetworkNotFound:
msg = _("Network not found")
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()
def show(self, req, id):

View File

@ -94,6 +94,7 @@ update_instance_info_cache = network_api.update_instance_cache_with_nw_info
class API(base.Base):
"""API for interacting with the neutron 2.x API."""
_sentinel = object()
def __init__(self):
super(API, self).__init__()
@ -751,6 +752,11 @@ class API(base.Base):
"""Disassociate a network for client."""
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):
"""Get a fixed ip from the id."""
raise NotImplementedError()

View File

@ -28,6 +28,7 @@ import nova.context
from nova import exception
from nova import test
from nova.tests.api.openstack import fakes
import nova.utils
CONF = cfg.CONF
@ -202,6 +203,7 @@ class NetworksTest(test.NoDBTestCase):
self.associate_controller = networks_associate\
.NetworkAssociateActionController(self.fake_network_api)
fakes.stub_out_networking(self.stubs)
nova.utils.reset_is_neutron()
fakes.stub_out_rate_limiting(self.stubs)
@staticmethod
@ -347,3 +349,41 @@ class NetworksTest(test.NoDBTestCase):
res_dict = self.controller.create(req, large_network)
self.assertEqual(res_dict['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})

View File

@ -2091,6 +2091,12 @@ class TestNeutronv2Portbinding(TestNeutronv2Base):
api.migrate_instance_finish,
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):
def setUp(self):