diff --git a/nova/api/openstack/compute/networks.py b/nova/api/openstack/compute/networks.py index d5485d173193..f798d40a0130 100644 --- a/nova/api/openstack/compute/networks.py +++ b/nova/api/openstack/compute/networks.py @@ -17,6 +17,8 @@ import netaddr from webob import exc +from nova.api.openstack.api_version_request \ + import MAX_PROXY_API_SUPPORT_VERSION from nova.api.openstack import common from nova.api.openstack.compute.schemas import networks as schema from nova.api.openstack import extensions @@ -82,6 +84,7 @@ class NetworkController(wsgi.Controller): def __init__(self, network_api=None): self.network_api = network_api or network.API() + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors(()) def index(self, req): context = req.environ['nova.context'] @@ -90,6 +93,7 @@ class NetworkController(wsgi.Controller): result = [network_dict(context, net_ref) for net_ref in networks] return {'networks': result} + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.response(202) @extensions.expected_errors((404, 501)) @wsgi.action("disassociate") @@ -105,6 +109,7 @@ class NetworkController(wsgi.Controller): except NotImplementedError: common.raise_feature_not_supported() + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors(404) def show(self, req, id): context = req.environ['nova.context'] @@ -117,6 +122,7 @@ class NetworkController(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) return {'network': network_dict(context, network)} + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.response(202) @extensions.expected_errors((404, 409)) def delete(self, req, id): @@ -131,6 +137,7 @@ class NetworkController(wsgi.Controller): msg = _("Network not found") raise exc.HTTPNotFound(explanation=msg) + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors((400, 409, 501)) @validation.schema(schema.create) def create(self, req, body): @@ -155,6 +162,7 @@ class NetworkController(wsgi.Controller): raise exc.HTTPConflict(explanation=ex.format_message()) return {"network": network_dict(context, network)} + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.response(202) @extensions.expected_errors((400, 501)) @validation.schema(schema.add_network_to_project) diff --git a/nova/api/openstack/compute/networks_associate.py b/nova/api/openstack/compute/networks_associate.py index 7bd6a3c12358..e96525d91d0f 100644 --- a/nova/api/openstack/compute/networks_associate.py +++ b/nova/api/openstack/compute/networks_associate.py @@ -12,6 +12,8 @@ from webob import exc +from nova.api.openstack.api_version_request \ + import MAX_PROXY_API_SUPPORT_VERSION from nova.api.openstack import common from nova.api.openstack.compute.schemas import networks_associate from nova.api.openstack import extensions @@ -31,6 +33,7 @@ class NetworkAssociateActionController(wsgi.Controller): def __init__(self, network_api=None): self.network_api = network_api or network.API() + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.action("disassociate_host") @wsgi.response(202) @extensions.expected_errors((404, 501)) @@ -45,6 +48,7 @@ class NetworkAssociateActionController(wsgi.Controller): except NotImplementedError: common.raise_feature_not_supported() + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.action("disassociate_project") @wsgi.response(202) @extensions.expected_errors((404, 501)) @@ -59,6 +63,7 @@ class NetworkAssociateActionController(wsgi.Controller): except NotImplementedError: common.raise_feature_not_supported() + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @wsgi.action("associate_host") @wsgi.response(202) @extensions.expected_errors((404, 501)) diff --git a/nova/api/openstack/compute/tenant_networks.py b/nova/api/openstack/compute/tenant_networks.py index 90cc4179091a..e61323abb775 100644 --- a/nova/api/openstack/compute/tenant_networks.py +++ b/nova/api/openstack/compute/tenant_networks.py @@ -20,6 +20,8 @@ from oslo_log import log as logging import six from webob import exc +from nova.api.openstack.api_version_request \ + import MAX_PROXY_API_SUPPORT_VERSION from nova.api.openstack.compute.schemas import tenant_networks as schema from nova.api.openstack import extensions from nova.api.openstack import wsgi @@ -73,6 +75,7 @@ class TenantNetworkController(wsgi.Controller): networks[n['id']] = n['label'] return [{'id': k, 'label': v} for k, v in six.iteritems(networks)] + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors(()) def index(self, req): context = req.environ['nova.context'] @@ -83,6 +86,7 @@ class TenantNetworkController(wsgi.Controller): networks.extend(self._default_networks) return {'networks': [network_dict(n) for n in networks]} + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors(404) def show(self, req, id): context = req.environ['nova.context'] @@ -94,6 +98,7 @@ class TenantNetworkController(wsgi.Controller): raise exc.HTTPNotFound(explanation=msg) return {'network': network_dict(network)} + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors((403, 404, 409)) @wsgi.response(202) def delete(self, req, id): @@ -129,6 +134,7 @@ class TenantNetworkController(wsgi.Controller): if CONF.enable_network_quota and reservation: QUOTAS.commit(context, reservation) + @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) @extensions.expected_errors((400, 403, 409, 503)) @validation.schema(schema.create) def create(self, req, body): diff --git a/nova/tests/unit/api/openstack/compute/test_networks.py b/nova/tests/unit/api/openstack/compute/test_networks.py index 7205844002ef..5f868a72f76a 100644 --- a/nova/tests/unit/api/openstack/compute/test_networks.py +++ b/nova/tests/unit/api/openstack/compute/test_networks.py @@ -372,10 +372,9 @@ class NetworksTestV21(test.NoDBTestCase): def test_network_disassociate(self): uuid = FAKE_NETWORKS[0]['uuid'] - res = self.controller._disassociate_host_and_project( - self.req, uuid, {'disassociate': None}) - self._check_status(res, self.controller._disassociate_host_and_project, - 202) + disassociate = self.controller._disassociate_host_and_project + res = disassociate(self.req, uuid, {'disassociate': None}) + self._check_status(res, disassociate, 202) self.assertIsNone(self.fake_network_api.networks[0]['project_id']) self.assertIsNone(self.fake_network_api.networks[0]['host']) @@ -403,8 +402,9 @@ class NetworksTestV21(test.NoDBTestCase): self.controller.show, self.req, 100) def test_network_delete(self): - res = self.controller.delete(self.req, 1) - self._check_status(res, self.controller.delete, 202) + delete_method = self.controller.delete + res = delete_method(self.req, 1) + self._check_status(res, delete_method, 202) def test_network_delete_not_found(self): self.assertRaises(webob.exc.HTTPNotFound, @@ -416,8 +416,9 @@ class NetworksTestV21(test.NoDBTestCase): def test_network_add(self): uuid = FAKE_NETWORKS[1]['uuid'] - res = self.controller.add(self.req, body={'id': uuid}) - self._check_status(res, self.controller.add, 202) + add = self.controller.add + res = add(self.req, body={'id': uuid}) + self._check_status(res, add, 202) res_dict = self.controller.show(self.admin_req, uuid) self.assertEqual(res_dict['network']['project_id'], @@ -458,8 +459,9 @@ class NetworksTestV21(test.NoDBTestCase): 'extra_arg': 123}) def test_network_add_network_with_none_id(self): - res = self.controller.add(self.req, body={'id': None}) - self._check_status(res, self.controller.add, 202) + add = self.controller.add + res = add(self.req, body={'id': None}) + self._check_status(res, add, 202) def test_network_create(self): res_dict = self.controller.create(self.req, body=self.new_network) @@ -505,36 +507,37 @@ class NetworksAssociateTestV21(test.NoDBTestCase): def test_network_disassociate_host_only(self): uuid = FAKE_NETWORKS[0]['uuid'] - res = self.associate_controller._disassociate_host_only( + disassociate = self.associate_controller._disassociate_host_only + res = disassociate( self.req, uuid, {'disassociate_host': None}) self._check_status(res, - self.associate_controller._disassociate_host_only, + disassociate, 202) self.assertIsNotNone(self.fake_network_api.networks[0]['project_id']) self.assertIsNone(self.fake_network_api.networks[0]['host']) def test_network_disassociate_project_only(self): uuid = FAKE_NETWORKS[0]['uuid'] - res = self.associate_controller._disassociate_project_only( - self.req, uuid, {'disassociate_project': None}) - self._check_status( - res, self.associate_controller._disassociate_project_only, 202) + disassociate = self.associate_controller._disassociate_project_only + res = disassociate(self.req, uuid, {'disassociate_project': None}) + self._check_status(res, disassociate, 202) self.assertIsNone(self.fake_network_api.networks[0]['project_id']) self.assertIsNotNone(self.fake_network_api.networks[0]['host']) def test_network_disassociate_project_network_delete(self): uuid = FAKE_NETWORKS[1]['uuid'] - res = self.associate_controller._disassociate_project_only( + disassociate = self.associate_controller._disassociate_project_only + res = disassociate( self.req, uuid, {'disassociate_project': None}) - self._check_status( - res, self.associate_controller._disassociate_project_only, 202) + self._check_status(res, disassociate, 202) self.assertIsNone(self.fake_network_api.networks[1]['project_id']) - res = self.controller.delete(self.req, 1) + delete = self.controller.delete + res = delete(self.req, 1) # NOTE: On v2.1 code, delete method doesn't return anything and # the status code is decorated on wsgi_code of the method. self.assertIsNone(res) - self.assertEqual(202, self.controller.delete.wsgi_code) + self.assertEqual(202, delete.wsgi_code) def test_network_associate_project_delete_fail(self): uuid = FAKE_NETWORKS[0]['uuid'] @@ -544,9 +547,9 @@ class NetworksAssociateTestV21(test.NoDBTestCase): def test_network_associate_with_host(self): uuid = FAKE_NETWORKS[1]['uuid'] - res = self.associate_controller._associate_host( - self.req, uuid, body={'associate_host': "TestHost"}) - self._check_status(res, self.associate_controller._associate_host, 202) + associate = self.associate_controller._associate_host + res = associate(self.req, uuid, body={'associate_host': "TestHost"}) + self._check_status(res, associate, 202) res_dict = self.controller.show(self.admin_req, uuid) self.assertEqual(res_dict['network']['host'], 'TestHost') @@ -702,3 +705,44 @@ class NetworksAssociateEnforcementV21(test.NoDBTestCase): self.assertEqual( "Policy doesn't allow %s to be performed." % rule_name, exc.format_message()) + + +class NetworksDeprecationTest(test.NoDBTestCase): + + def setUp(self): + super(NetworksDeprecationTest, self).setUp() + self.controller = networks_v21.NetworkController() + self.req = fakes.HTTPRequest.blank('', version='2.36') + + def test_all_api_return_not_found(self): + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.show, self.req, fakes.FAKE_UUID) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.delete, self.req, fakes.FAKE_UUID) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.index, self.req) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller._disassociate_host_and_project, self.req, {}) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.add, self.req, {}) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.create, self.req, {}) + + +class NetworksAssociateDeprecationTest(test.NoDBTestCase): + + def setUp(self): + super(NetworksAssociateDeprecationTest, self).setUp() + self.controller = networks_associate_v21\ + .NetworkAssociateActionController() + self.req = fakes.HTTPRequest.blank('', version='2.36') + + def test_all_api_return_not_found(self): + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller._associate_host, self.req, fakes.FAKE_UUID, {}) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller._disassociate_project_only, self.req, + fakes.FAKE_UUID, {}) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller._disassociate_host_only, self.req, + fakes.FAKE_UUID, {}) diff --git a/nova/tests/unit/api/openstack/compute/test_tenant_networks.py b/nova/tests/unit/api/openstack/compute/test_tenant_networks.py index 0d002697e3c7..2ddc0e1fd826 100644 --- a/nova/tests/unit/api/openstack/compute/test_tenant_networks.py +++ b/nova/tests/unit/api/openstack/compute/test_tenant_networks.py @@ -127,11 +127,12 @@ class TenantNetworksTestV21(test.NoDBTestCase): reserve_mock.return_value = 'rv' - res = self.controller.delete(self.req, 1) + delete_method = self.controller.delete + res = delete_method(self.req, 1) # NOTE: on v2.1, http status code is set as wsgi_code of API # method instead of status_int in a response object. if isinstance(self.controller, networks_v21.TenantNetworkController): - status_int = self.controller.delete.wsgi_code + status_int = delete_method.wsgi_code else: status_int = res.status_int self.assertEqual(202, status_int) @@ -309,3 +310,23 @@ class TenantNetworksEnforcementV21(test.NoDBTestCase): self.assertEqual( "Policy doesn't allow %s to be performed." % rule_name, exc.format_message()) + + +class TenantNetworksDeprecationTest(test.NoDBTestCase): + ctrlr = networks_v21.TenantNetworkController + validation_error = exception.ValidationError + + def setUp(self): + super(TenantNetworksDeprecationTest, self).setUp() + self.controller = networks_v21.TenantNetworkController() + self.req = fakes.HTTPRequest.blank('', version='2.36') + + def test_all_apis_return_not_found(self): + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.index, self.req) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.show, self.req, fakes.FAKE_UUID) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.delete, self.req, fakes.FAKE_UUID) + self.assertRaises(exception.VersionNotFoundForAPIMethod, + self.controller.create, self.req, {})