diff --git a/api-ref/source/os-tenant-network.inc b/api-ref/source/os-tenant-network.inc index ceb405800f3..41314fb24cb 100644 --- a/api-ref/source/os-tenant-network.inc +++ b/api-ref/source/os-tenant-network.inc @@ -1,10 +1,8 @@ .. -*- rst -*- -.. NOTE(gmann): These APIs are deprecated so do not update this - file even body, example or parameters are not complete. -=================================================== +==================================================== Project networks (os-tenant-networks) (DEPRECATED) -=================================================== +==================================================== .. warning:: @@ -57,7 +55,8 @@ through the ``policy.json`` file. Normal response codes: 200 -Error response codes: badRequest(400), unauthorized(401), forbidden(403), conflict(409), serviceUnavailable(503) +Error response codes: badRequest(400), unauthorized(401), forbidden(403), +conflict(409), gone(410), serviceUnavailable(503) **Example Create Project Network: JSON request** @@ -121,7 +120,8 @@ can change these permissions through the ``policy.json`` file. Normal response codes: 202 -Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), conflict(409) +Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), +conflict(409), gone(410) Request ------- diff --git a/doc/api_samples/os-tenant-networks/networks-list-res.json b/doc/api_samples/os-tenant-networks/networks-list-res.json index b857e8112af..006663ded1b 100644 --- a/doc/api_samples/os-tenant-networks/networks-list-res.json +++ b/doc/api_samples/os-tenant-networks/networks-list-res.json @@ -1,14 +1,9 @@ { "networks": [ { - "cidr": "10.0.0.0/29", - "id": "616fb98f-46ca-475e-917e-2563e5a8cd19", - "label": "test_0" - }, - { - "cidr": "10.0.0.8/29", - "id": "616fb98f-46ca-475e-917e-2563e5a8cd20", - "label": "test_1" + "cidr": "None", + "id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6", + "label": "private" } ] } diff --git a/nova/api/openstack/compute/rest_api_version_history.rst b/nova/api/openstack/compute/rest_api_version_history.rst index 0f815c8e9be..c47a4b44d4c 100644 --- a/nova/api/openstack/compute/rest_api_version_history.rst +++ b/nova/api/openstack/compute/rest_api_version_history.rst @@ -441,6 +441,12 @@ API endpoints as below:: release. On deployments newer than this, some endpoints of the API will return HTTP 410 (Gone) regadless of the requested microversion. +.. versionchanged:: 21.0.0 + + The ``os-tenant-networks`` API was partially removed in the 21.0.0 (Ussuri) + release. On deployments newer than this, some endpoints of the API will + return HTTP 410 (Gone) regadless of the requested microversion. + 2.37 ---- diff --git a/nova/api/openstack/compute/schemas/tenant_networks.py b/nova/api/openstack/compute/schemas/tenant_networks.py deleted file mode 100644 index f5f4c03ac3a..00000000000 --- a/nova/api/openstack/compute/schemas/tenant_networks.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2015 NEC Corporation. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from nova.api.validation import parameter_types - -create = { - 'type': 'object', - 'properties': { - 'network': { - 'type': 'object', - 'properties': { - 'label': { - 'type': 'string', 'maxLength': 255 - }, - 'ipam': parameter_types.boolean, - 'cidr': parameter_types.cidr, - 'cidr_v6': parameter_types.cidr, - 'vlan_start': parameter_types.positive_integer_with_empty_str, - 'network_size': - parameter_types.positive_integer_with_empty_str, - 'num_networks': parameter_types.positive_integer_with_empty_str - }, - 'required': ['label'], - 'oneOf': [ - {'required': ['cidr']}, - {'required': ['cidr_v6']} - ], - 'additionalProperties': False, - }, - }, - 'required': ['network'], - 'additionalProperties': False, -} diff --git a/nova/api/openstack/compute/tenant_networks.py b/nova/api/openstack/compute/tenant_networks.py index b550c89ec13..f68c2bbcb0a 100644 --- a/nova/api/openstack/compute/tenant_networks.py +++ b/nova/api/openstack/compute/tenant_networks.py @@ -13,24 +13,17 @@ # License for the specific language governing permissions and limitations # under the License. - -import netaddr -import netaddr.core as netexc 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 wsgi -from nova.api import validation import nova.conf from nova import context as nova_context from nova import exception from nova.i18n import _ import nova.network -from nova import objects from nova.policies import tenant_networks as tn_policies from nova import quota @@ -97,86 +90,13 @@ def show(self, req, id): raise exc.HTTPNotFound(explanation=msg) return {'network': network_dict(network)} - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((403, 404, 409)) - @wsgi.response(202) + @wsgi.expected_errors(410) def delete(self, req, id): - context = req.environ['nova.context'] - context.can(tn_policies.BASE_POLICY_NAME) + raise exc.HTTPGone() - try: - self.network_api.disassociate(context, id) - self.network_api.delete(context, id) - except exception.PolicyNotAuthorized as e: - raise exc.HTTPForbidden(explanation=six.text_type(e)) - except exception.NetworkInUse as e: - raise exc.HTTPConflict(explanation=e.format_message()) - except exception.NetworkNotFound: - msg = _("Network not found") - raise exc.HTTPNotFound(explanation=msg) - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((400, 403, 409, 503)) - @validation.schema(schema.create) + @wsgi.expected_errors(410) def create(self, req, body): - context = req.environ["nova.context"] - context.can(tn_policies.BASE_POLICY_NAME) - - network = body["network"] - keys = ["cidr", "cidr_v6", "ipam", "vlan_start", "network_size", - "num_networks"] - kwargs = {k: network.get(k) for k in keys} - - label = network["label"] - - if kwargs["cidr"]: - try: - net = netaddr.IPNetwork(kwargs["cidr"]) - if net.size < 4: - msg = _("Requested network does not contain " - "enough (2+) usable hosts") - raise exc.HTTPBadRequest(explanation=msg) - except netexc.AddrConversionError: - msg = _("Address could not be converted.") - raise exc.HTTPBadRequest(explanation=msg) - - try: - if CONF.enable_network_quota: - objects.Quotas.check_deltas(context, {'networks': 1}, - context.project_id) - except exception.OverQuota: - msg = _("Quota exceeded, too many networks.") - raise exc.HTTPForbidden(explanation=msg) - - kwargs['project_id'] = context.project_id - - try: - networks = self.network_api.create(context, - label=label, **kwargs) - except exception.PolicyNotAuthorized as e: - raise exc.HTTPForbidden(explanation=six.text_type(e)) - except exception.CidrConflict as e: - raise exc.HTTPConflict(explanation=e.format_message()) - except Exception: - msg = _("Create networks failed") - LOG.exception(msg, extra=network) - raise exc.HTTPServiceUnavailable(explanation=msg) - - # NOTE(melwitt): We recheck the quota after creating the object to - # prevent users from allocating more resources than their allowed quota - # in the event of a race. This is configurable because it can be - # expensive if strict quota limits are not required in a deployment. - if CONF.quota.recheck_quota and CONF.enable_network_quota: - try: - objects.Quotas.check_deltas(context, {'networks': 0}, - context.project_id) - except exception.OverQuota: - self.network_api.delete(context, - network_dict(networks[0])['id']) - msg = _("Quota exceeded, too many networks.") - raise exc.HTTPForbidden(explanation=msg) - - return {"network": network_dict(networks[0])} + raise exc.HTTPGone() def _network_count(context, project_id): diff --git a/nova/api/validation/parameter_types.py b/nova/api/validation/parameter_types.py index 7943142e3d9..eecbc621cc6 100644 --- a/nova/api/validation/parameter_types.py +++ b/nova/api/validation/parameter_types.py @@ -250,13 +250,6 @@ def valid_char(char): 'pattern': '^[0-9]*$', 'minimum': 0, 'minLength': 1 } -# This only be used by nova-network specific APIs. It will be removed when -# those API removed. -positive_integer_with_empty_str = { - 'type': ['integer', 'string'], - 'pattern': '^[0-9]*$', 'minimum': 1, -} - hostname = { 'type': 'string', 'minLength': 1, 'maxLength': 255, # NOTE: 'host' is defined in "services" table, and that diff --git a/nova/policies/tenant_networks.py b/nova/policies/tenant_networks.py index 19441c8f3cc..9bd4787bbb2 100644 --- a/nova/policies/tenant_networks.py +++ b/nova/policies/tenant_networks.py @@ -34,22 +34,10 @@ 'method': 'GET', 'path': '/os-tenant-networks' }, - - { - 'method': 'POST', - 'path': '/os-tenant-networks' - }, - { 'method': 'GET', 'path': '/os-tenant-networks/{network_id}' }, - - { - 'method': 'DELETE', - 'path': '/os-tenant-networks/{network_id}' - } - ]), ] diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-list-res.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-list-res.json.tpl index 757084d2f37..9ff40d2bdee 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-list-res.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-list-res.json.tpl @@ -1,14 +1,9 @@ { "networks": [ { - "cidr": "10.0.0.0/29", - "id": "%(id)s", - "label": "test_0" - }, - { - "cidr": "10.0.0.8/29", - "id": "%(id)s", - "label": "test_1" + "cidr": "None", + "id": "%(uuid)s", + "label": "private" } ] } diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-req.json.tpl deleted file mode 100644 index fb1c2d3d062..00000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-req.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "network": { - "label": "public", - "cidr": "172.0.0.0/24", - "vlan_start": 1, - "num_networks": 1, - "network_size": 255 - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-res.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-res.json.tpl deleted file mode 100644 index ff9e2273d30..00000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-tenant-networks/networks-post-res.json.tpl +++ /dev/null @@ -1,7 +0,0 @@ -{ - "network": { - "cidr": "172.0.0.0/24", - "id": "%(id)s", - "label": "public" - } -} diff --git a/nova/tests/functional/api_sample_tests/test_tenant_networks.py b/nova/tests/functional/api_sample_tests/test_tenant_networks.py index 5549f1dac6e..927e2cf604a 100644 --- a/nova/tests/functional/api_sample_tests/test_tenant_networks.py +++ b/nova/tests/functional/api_sample_tests/test_tenant_networks.py @@ -13,52 +13,24 @@ # License for the specific language governing permissions and limitations # under the License. - -from oslo_serialization import jsonutils - import nova.conf -from nova.tests import fixtures as nova_fixtures from nova.tests.functional.api_sample_tests import api_sample_base CONF = nova.conf.CONF -# TODO(stephenfin): Remove the parts of this test that are nova-network only class TenantNetworksJsonTests(api_sample_base.ApiSampleTestBaseV21): - USE_NEUTRON = False # partially nova-net only ADMIN_API = True sample_dir = "os-tenant-networks" - def setUp(self): - super(TenantNetworksJsonTests, self).setUp() - CONF.set_override("enable_network_quota", True) - self.useFixture(nova_fixtures.RegisterNetworkQuota()) - - def fake(*args, **kwargs): - pass - - self.stub_out("nova.quota.QUOTAS.reserve", fake) - self.stub_out("nova.quota.QUOTAS.commit", fake) - self.stub_out("nova.quota.QUOTAS.rollback", fake) - self.stub_out("nova.quota.QuotaEngine.reserve", fake) - self.stub_out("nova.quota.QuotaEngine.commit", fake) - self.stub_out("nova.quota.QuotaEngine.rollback", fake) - - # TODO(stephenfin): Rework this to work with neutron def test_list_networks(self): response = self._do_get('os-tenant-networks') self._verify_response('networks-list-res', {}, response, 200) - # TODO(stephenfin): Remove this API since it's nova-network only def test_create_network(self): - response = self._do_post('os-tenant-networks', "networks-post-req", {}) - self._verify_response('networks-post-res', {}, response, 200) + self.api.api_post('os-tenant-networks', {}, + check_response_status=[410]) - # TODO(stephenfin): Remove this API since it's nova-network only def test_delete_network(self): - response = self._do_post('os-tenant-networks', "networks-post-req", {}) - net = jsonutils.loads(response.content) - response = self._do_delete('os-tenant-networks/%s' % - net["network"]["id"]) - self.assertEqual(202, response.status_code) - self.assertEqual("", response.text) + self.api.api_delete('os-tenant-networks/1', + check_response_status=[410]) 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 3a0a2a352bc..18e07241557 100644 --- a/nova/tests/unit/api/openstack/compute/test_tenant_networks.py +++ b/nova/tests/unit/api/openstack/compute/test_tenant_networks.py @@ -64,15 +64,14 @@ def fake_network_api_get_all(context): class TenantNetworksTestV21(test.NoDBTestCase): ctrlr = networks_v21.TenantNetworkController validation_error = exception.ValidationError - use_neutron = False def setUp(self): + # TODO(stephenfin): We should probably use NeutronFixture here super(TenantNetworksTestV21, self).setUp() # os-tenant-networks only supports Neutron when listing networks or # showing details about a network, create and delete operations # result in a 503 and 500 response, respectively. - self.flags(enable_network_quota=True, - use_neutron=self.use_neutron) + self.flags(enable_network_quota=True) self.useFixture(nova_fixtures.RegisterNetworkQuota()) self.controller = self.ctrlr() self.req = fakes.HTTPRequest.blank('') @@ -83,63 +82,6 @@ def tearDown(self): CONF.set_override("use_neutron_default_nets", self.original_value, group='api') - def _fake_network_api_create(self, context, **kwargs): - self.assertEqual(context.project_id, kwargs['project_id']) - return NETWORKS - - @mock.patch('nova.network.api.API.disassociate') - @mock.patch('nova.network.api.API.delete') - def _test_network_delete_exception(self, delete_ex, disassociate_ex, expex, - delete_mock, disassociate_mock): - ctxt = self.req.environ['nova.context'] - - if delete_mock: - delete_mock.side_effect = delete_ex - if disassociate_ex: - disassociate_mock.side_effect = disassociate_ex - - if self.use_neutron: - expex = webob.exc.HTTPInternalServerError - self.assertRaises(expex, self.controller.delete, self.req, 1) - - if not self.use_neutron: - disassociate_mock.assert_called_once_with(ctxt, 1) - if not disassociate_ex: - delete_mock.assert_called_once_with(ctxt, 1) - - def test_network_delete_exception_network_not_found(self): - ex = exception.NetworkNotFound(network_id=1) - expex = webob.exc.HTTPNotFound - self._test_network_delete_exception(None, ex, expex) - - def test_network_delete_exception_policy_failed(self): - ex = exception.PolicyNotAuthorized(action='dummy') - expex = webob.exc.HTTPForbidden - self._test_network_delete_exception(ex, None, expex) - - def test_network_delete_exception_network_in_use(self): - ex = exception.NetworkInUse(network_id=1) - expex = webob.exc.HTTPConflict - self._test_network_delete_exception(ex, None, expex) - - @mock.patch('nova.network.api.API.delete') - @mock.patch('nova.network.api.API.disassociate') - def test_network_delete(self, disassociate_mock, delete_mock): - ctxt = self.req.environ['nova.context'] - - 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 = delete_method.wsgi_code - else: - status_int = res.status_int - self.assertEqual(202, status_int) - - disassociate_mock.assert_called_once_with(ctxt, 1) - delete_mock.assert_called_once_with(ctxt, 1) - def test_network_show(self): with mock.patch.object(self.controller.network_api, 'get', return_value=NETWORKS[0]): @@ -173,155 +115,6 @@ def test_network_index_with_default_net(self): def test_network_index_without_default_net(self): self._test_network_index(default_net=False) - @mock.patch('nova.objects.Quotas.check_deltas') - @mock.patch('nova.network.api.API.create') - def test_network_create(self, create_mock, check_mock): - create_mock.side_effect = self._fake_network_api_create - - body = copy.deepcopy(NETWORKS[0]) - del body['id'] - body = {'network': body} - res = self.controller.create(self.req, body=body) - - self.assertEqual(NETWORKS[0], res['network']) - - @mock.patch('nova.objects.Quotas.check_deltas') - @mock.patch('nova.network.api.API.delete') - @mock.patch('nova.network.api.API.create') - def test_network_create_quota_error_during_recheck(self, create_mock, - delete_mock, - check_mock): - create_mock.side_effect = self._fake_network_api_create - ctxt = self.req.environ['nova.context'] - - # Simulate a race where the first check passes and the recheck fails. - check_mock.side_effect = [None, exception.OverQuota(overs='networks')] - - body = copy.deepcopy(NETWORKS[0]) - del body['id'] - body = {'network': body} - self.assertRaises(webob.exc.HTTPForbidden, - self.controller.create, self.req, body=body) - - self.assertEqual(2, check_mock.call_count) - call1 = mock.call(ctxt, {'networks': 1}, ctxt.project_id) - call2 = mock.call(ctxt, {'networks': 0}, ctxt.project_id) - check_mock.assert_has_calls([call1, call2]) - - # Verify we removed the network that was added after the first quota - # check passed. - delete_mock.assert_called_once_with(ctxt, NETWORKS[0]['id']) - - @mock.patch('nova.objects.Quotas.check_deltas') - @mock.patch('nova.network.api.API.create') - def test_network_create_no_quota_recheck(self, create_mock, check_mock): - create_mock.side_effect = self._fake_network_api_create - ctxt = self.req.environ['nova.context'] - # Disable recheck_quota. - self.flags(recheck_quota=False, group='quota') - - body = copy.deepcopy(NETWORKS[0]) - del body['id'] - body = {'network': body} - self.controller.create(self.req, body=body) - - # check_deltas should have been called only once. - check_mock.assert_called_once_with(ctxt, {'networks': 1}, - ctxt.project_id) - - @mock.patch('nova.objects.Quotas.check_deltas') - def test_network_create_quota_error(self, check_mock): - ctxt = self.req.environ['nova.context'] - - check_mock.side_effect = exception.OverQuota(overs='networks') - body = {'network': {"cidr": "10.20.105.0/24", - "label": "new net 1"}} - self.assertRaises(webob.exc.HTTPForbidden, - self.controller.create, self.req, body=body) - check_mock.assert_called_once_with(ctxt, {'networks': 1}, - ctxt.project_id) - - @mock.patch('nova.objects.Quotas.check_deltas') - @mock.patch('nova.network.api.API.create') - def _test_network_create_exception(self, ex, expex, create_mock, - check_mock): - ctxt = self.req.environ['nova.context'] - - create_mock.side_effect = ex - body = {'network': {"cidr": "10.20.105.0/24", - "label": "new net 1"}} - if self.use_neutron: - expex = webob.exc.HTTPServiceUnavailable - self.assertRaises(expex, self.controller.create, self.req, body=body) - check_mock.assert_called_once_with(ctxt, {'networks': 1}, - ctxt.project_id) - - def test_network_create_exception_policy_failed(self): - ex = exception.PolicyNotAuthorized(action='dummy') - expex = webob.exc.HTTPForbidden - self._test_network_create_exception(ex, expex) - - def test_network_create_exception_conflictcidr(self): - ex = exception.CidrConflict(cidr='dummy', other='dummy') - expex = webob.exc.HTTPConflict - self._test_network_create_exception(ex, expex) - - def test_network_create_exception_service_unavailable(self): - ex = Exception - expex = webob.exc.HTTPServiceUnavailable - self._test_network_create_exception(ex, expex) - - def test_network_create_empty_body(self): - self.assertRaises(exception.ValidationError, - self.controller.create, self.req, body={}) - - def test_network_create_without_cidr(self): - body = {'network': {"label": "new net 1"}} - self.assertRaises(self.validation_error, - self.controller.create, self.req, body=body) - - def test_network_create_bad_format_cidr(self): - body = {'network': {"cidr": "123", - "label": "new net 1"}} - self.assertRaises(self.validation_error, - self.controller.create, self.req, body=body) - - def test_network_create_empty_network(self): - body = {'network': {}} - self.assertRaises(self.validation_error, - self.controller.create, self.req, body=body) - - def test_network_create_without_label(self): - body = {'network': {"cidr": "10.20.105.0/24"}} - self.assertRaises(self.validation_error, - self.controller.create, self.req, body=body) - - -class TenantNeutronNetworksTestV21(TenantNetworksTestV21): - use_neutron = True - - def test_network_create(self): - self.assertRaises( - webob.exc.HTTPServiceUnavailable, - super(TenantNeutronNetworksTestV21, self).test_network_create) - - def test_network_create_quota_error_during_recheck(self): - self.assertRaises( - webob.exc.HTTPServiceUnavailable, - super(TenantNeutronNetworksTestV21, self) - .test_network_create_quota_error_during_recheck) - - def test_network_create_no_quota_recheck(self): - self.assertRaises( - webob.exc.HTTPServiceUnavailable, - super(TenantNeutronNetworksTestV21, self) - .test_network_create_no_quota_recheck) - - def test_network_delete(self): - self.assertRaises( - webob.exc.HTTPInternalServerError, - super(TenantNeutronNetworksTestV21, self).test_network_delete) - class TenantNetworksEnforcementV21(test.NoDBTestCase): @@ -330,18 +123,6 @@ def setUp(self): self.controller = networks_v21.TenantNetworkController() self.req = fakes.HTTPRequest.blank('') - def test_create_policy_failed(self): - rule_name = 'os_compute_api:os-tenant-networks' - self.policy.set_rules({rule_name: "project:non_fake"}) - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.create, - self.req, body={'network': {'label': 'test', - 'cidr': '10.0.0.0/32'}}) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - def test_index_policy_failed(self): rule_name = 'os_compute_api:os-tenant-networks' self.policy.set_rules({rule_name: "project:non_fake"}) @@ -353,17 +134,6 @@ def test_index_policy_failed(self): "Policy doesn't allow %s to be performed." % rule_name, exc.format_message()) - def test_delete_policy_failed(self): - rule_name = 'os_compute_api:os-tenant-networks' - self.policy.set_rules({rule_name: "project:non_fake"}) - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.delete, - self.req, fakes.FAKE_UUID) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - def test_show_policy_failed(self): rule_name = 'os_compute_api:os-tenant-networks' self.policy.set_rules({rule_name: "project:non_fake"}) @@ -388,7 +158,3 @@ def test_all_apis_return_not_found(self): 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, {}) diff --git a/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml b/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml index b618b2bb248..0ab0be0b7ee 100644 --- a/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml +++ b/releasenotes/notes/remove-nova-network-c02953ba72a1795d.yaml @@ -17,6 +17,8 @@ upgrade: * ``POST /os-networks/{id} (disassociate)`` * ``POST /os-networks/{id} (disassociate_host)`` * ``POST /os-networks/{id} (disassociate_project)`` + * ``POST /os-tenant-networks`` + * ``DELETE /os-tenant-networks`` The following policies have also been removed.