Deprecated networks related proxy APIs
This patch deprecates all the proxy APIs for networks. All those APIs
will return 404 in new Microversions.
The deprecated API endpoints are:
'/os-networks'
'/os-networks/add'
'/os-networks/{id}/action'
This patch doesn't bump the max API version, due to the patch separation.
The max API version will bump in the last patch.
Partially implements blueprint deprecate-api-proxies
Change-Id: Icfedbe7e4ff0a1b575ac4449ba11cf2383810866
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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, {})
|
||||
|
||||
@@ -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, {})
|
||||
|
||||
Reference in New Issue
Block a user