From 4c93003ede55e1f60ac95549007b03bf8a5a0be8 Mon Sep 17 00:00:00 2001 From: jichen Date: Wed, 16 May 2018 11:15:03 +0800 Subject: [PATCH] Remove support for /os-virtual-interfaces REST API This drops support for the os-virtual-interfaces compute REST API which has been deprecated since Newton: I1a8a44530be29292561e90d6f7bd7ed512a88ee3 Now it returns 410 response. Unit tests are removed and the functional API sample test is just asserting the 410 response now. The API sample docs are left intact since the API reference still builds from those and can be considered more or less branchless, so people looking at the API reference can apply it to older deployments of nova before os-virtual-interfaces was removed. Depends-On: https://review.openstack.org/571556/ Part of blueprint remove-nova-network Change-Id: Id7f94a643e5d7b8a842c0f4a5c9f796d6566b365 --- api-ref/source/index.rst | 2 +- api-ref/source/os-virtual-interfaces.inc | 9 +- .../openstack/compute/virtual_interfaces.py | 54 +----- nova/policies/__init__.py | 2 - nova/policies/virtual_interfaces.py | 41 ---- .../v2.12/vifs-list-resp.json.tpl | 9 - .../vifs-list-resp-v2.json.tpl | 9 - .../vifs-list-resp.json.tpl | 8 - .../test_virtual_interfaces.py | 33 ++-- .../compute/test_virtual_interfaces.py | 177 ------------------ nova/tests/unit/fake_policy.py | 1 - nova/tests/unit/test_policy.py | 1 - ...network-api-removals-931ad60364f6f2a8.yaml | 1 + 13 files changed, 22 insertions(+), 325 deletions(-) delete mode 100644 nova/policies/virtual_interfaces.py delete mode 100644 nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/v2.12/vifs-list-resp.json.tpl delete mode 100644 nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp-v2.json.tpl delete mode 100644 nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp.json.tpl delete mode 100644 nova/tests/unit/api/openstack/compute/test_virtual_interfaces.py diff --git a/api-ref/source/index.rst b/api-ref/source/index.rst index f7679f7cabaf..bab9aa083c42 100644 --- a/api-ref/source/index.rst +++ b/api-ref/source/index.rst @@ -69,7 +69,6 @@ the `API guide `_. .. include:: os-security-group-default-rules.inc .. include:: os-security-group-rules.inc .. include:: os-hosts.inc -.. include:: os-virtual-interfaces.inc ============= Obsolete APIs @@ -81,3 +80,4 @@ Compute API in the past, but no longer exist. .. include:: os-certificates.inc .. include:: os-cloudpipe.inc .. include:: os-fping.inc +.. include:: os-virtual-interfaces.inc diff --git a/api-ref/source/os-virtual-interfaces.inc b/api-ref/source/os-virtual-interfaces.inc index 3390bdf1adb9..df0277dea8d6 100644 --- a/api-ref/source/os-virtual-interfaces.inc +++ b/api-ref/source/os-virtual-interfaces.inc @@ -8,8 +8,10 @@ Lists virtual interfaces for a server. .. warning:: Since this API is only implemented for the nova-network, the API is deprecated from the Microversion 2.44. This API will fail with - a 404 starting from microversion 2.44. To query the server attached - neutron interface, please use the API + a 404 starting from microversion 2.44. It was removed in the + 18.0.0 Rocky release. + + To query the server attached neutron interface, please use the API ``GET /servers/{server_uuid}/os-interface``. .. note:: @@ -32,7 +34,8 @@ the server to perform this operation. Change these permissions through the Normal response codes: 200 -Error response codes: badRequest(400), unauthorized(401), forbidden(403), itemNotFound(404) +Error response codes: badRequest(400), unauthorized(401), forbidden(403), +itemNotFound(404), gone(410) Request ------- diff --git a/nova/api/openstack/compute/virtual_interfaces.py b/nova/api/openstack/compute/virtual_interfaces.py index 46724c9c4aaf..d2fb94ad094d 100644 --- a/nova/api/openstack/compute/virtual_interfaces.py +++ b/nova/api/openstack/compute/virtual_interfaces.py @@ -15,61 +15,13 @@ """The virtual interfaces extension.""" -import webob +from webob import exc -from nova.api.openstack import api_version_request -from nova.api.openstack import common from nova.api.openstack import wsgi -from nova import compute -from nova.i18n import _ -from nova import network -from nova.policies import virtual_interfaces as vif_policies - - -def _translate_vif_summary_view(req, vif): - """Maps keys for VIF summary view.""" - d = {} - d['id'] = vif.uuid - d['mac_address'] = vif.address - if api_version_request.is_supported(req, min_version='2.12'): - d['net_id'] = vif.net_uuid - # NOTE(gmann): This is for v2.1 compatible mode where response should be - # same as v2 one. - if req.is_legacy_v2(): - d['OS-EXT-VIF-NET:net_id'] = vif.net_uuid - return d class ServerVirtualInterfaceController(wsgi.Controller): - """The instance VIF API controller for the OpenStack API. - This API is deprecated from the Microversion '2.44'. - """ - - def __init__(self): - self.compute_api = compute.API() - self.network_api = network.API() - super(ServerVirtualInterfaceController, self).__init__() - - def _items(self, req, server_id, entity_maker): - """Returns a list of VIFs, transformed through entity_maker.""" - context = req.environ['nova.context'] - context.can(vif_policies.BASE_POLICY_NAME) - instance = common.get_instance(self.compute_api, context, server_id) - - try: - vifs = self.network_api.get_vifs_by_instance(context, instance) - except NotImplementedError: - msg = _('Listing virtual interfaces is not supported by this ' - 'cloud.') - raise webob.exc.HTTPBadRequest(explanation=msg) - limited_list = common.limited(vifs, req) - res = [entity_maker(req, vif) for vif in limited_list] - return {'virtual_interfaces': res} - - @wsgi.Controller.api_version("2.1", "2.43") - @wsgi.expected_errors((400, 404)) + @wsgi.expected_errors((410)) def index(self, req, server_id): - """Returns the list of VIFs for a given instance.""" - return self._items(req, server_id, - entity_maker=_translate_vif_summary_view) + raise exc.HTTPGone() diff --git a/nova/policies/__init__.py b/nova/policies/__init__.py index 01ba14606ee0..80e5c64fb8e2 100644 --- a/nova/policies/__init__.py +++ b/nova/policies/__init__.py @@ -83,7 +83,6 @@ from nova.policies import simple_tenant_usage from nova.policies import suspend_server from nova.policies import tenant_networks from nova.policies import used_limits -from nova.policies import virtual_interfaces from nova.policies import volumes from nova.policies import volumes_attachments @@ -160,7 +159,6 @@ def list_rules(): suspend_server.list_rules(), tenant_networks.list_rules(), used_limits.list_rules(), - virtual_interfaces.list_rules(), volumes.list_rules(), volumes_attachments.list_rules() ) diff --git a/nova/policies/virtual_interfaces.py b/nova/policies/virtual_interfaces.py deleted file mode 100644 index f5fe117ea752..000000000000 --- a/nova/policies/virtual_interfaces.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2016 Cloudbase Solutions Srl -# 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 oslo_policy import policy - -from nova.policies import base - - -BASE_POLICY_NAME = 'os_compute_api:os-virtual-interfaces' - - -virtual_interfaces_policies = [ - policy.DocumentedRuleDefault( - BASE_POLICY_NAME, - base.RULE_ADMIN_OR_OWNER, - """List virtual interfaces. - -This works only with the nova-network service, which is now deprecated""", - [ - { - 'method': 'GET', - 'path': '/servers/{server_id}/os-virtual-interfaces' - } - ]), -] - - -def list_rules(): - return virtual_interfaces_policies diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/v2.12/vifs-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/v2.12/vifs-list-resp.json.tpl deleted file mode 100644 index 86c839f215b1..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/v2.12/vifs-list-resp.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "virtual_interfaces": [ - { - "id": "%(id)s", - "mac_address": "%(mac_addr)s", - "net_id": "%(id)s" - } - ] -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp-v2.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp-v2.json.tpl deleted file mode 100644 index 684b93448d27..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp-v2.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "virtual_interfaces": [ - { - "id": "%(id)s", - "mac_address": "%(mac_addr)s", - "OS-EXT-VIF-NET:net_id": "%(id)s" - } - ] -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp.json.tpl deleted file mode 100644 index af0b7e05a795..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-virtual-interfaces/vifs-list-resp.json.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{ - "virtual_interfaces": [ - { - "id": "%(id)s", - "mac_address": "%(mac_addr)s" - } - ] -} \ No newline at end of file diff --git a/nova/tests/functional/api_sample_tests/test_virtual_interfaces.py b/nova/tests/functional/api_sample_tests/test_virtual_interfaces.py index 8091d8c9feaa..9684db270480 100644 --- a/nova/tests/functional/api_sample_tests/test_virtual_interfaces.py +++ b/nova/tests/functional/api_sample_tests/test_virtual_interfaces.py @@ -13,30 +13,19 @@ # License for the specific language governing permissions and limitations # under the License. -from nova.tests.functional.api_sample_tests import test_servers + +from nova.tests.functional.api import client as api_client +from nova.tests.functional import api_samples_test_base +from nova.tests import uuidsentinel as uuids -class VirtualInterfacesJsonTest(test_servers.ServersSampleBase): - sample_dir = "os-virtual-interfaces" - - def setUp(self): - super(VirtualInterfacesJsonTest, self).setUp() - self.template = 'vifs-list-resp' - if self.api_major_version == 'v2': - self.template = 'vifs-list-resp-v2' +class VirtualInterfacesJsonTest(api_samples_test_base.ApiSampleTestBase): + api_major_version = 'v2' def test_vifs_list(self): - uuid = self._post_server() + uuid = uuids.instance_1 - response = self._do_get('servers/%s/os-virtual-interfaces' % uuid) - - subs = {'mac_addr': '(?:[a-f0-9]{2}:){5}[a-f0-9]{2}'} - self._verify_response(self.template, subs, response, 200) - - -class VirtualInterfacesJsonV212Test(VirtualInterfacesJsonTest): - microversion = '2.12' - # NOTE(gmann): microversion tests do not need to run for v2 API - # so defining scenarios only for v2.12 which will run the original tests - # by appending '(v2_12)' in test_id. - scenarios = [('v2_12', {'api_major_version': 'v2.1'})] + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, + '/servers/%s/os-virtual-interfaces' % uuid) + self.assertEqual(410, ex.response.status_code) diff --git a/nova/tests/unit/api/openstack/compute/test_virtual_interfaces.py b/nova/tests/unit/api/openstack/compute/test_virtual_interfaces.py deleted file mode 100644 index a79e7caa547b..000000000000 --- a/nova/tests/unit/api/openstack/compute/test_virtual_interfaces.py +++ /dev/null @@ -1,177 +0,0 @@ -# Copyright (C) 2011 Midokura KK -# 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. - -import mock - -import webob - -from nova.api.openstack import api_version_request -from nova.api.openstack.compute import virtual_interfaces as vi21 -from nova import compute -from nova.compute import api as compute_api -from nova import context -from nova import exception -from nova import network -from nova.objects import virtual_interface as vif_obj -from nova import test -from nova.tests.unit.api.openstack import fakes -from nova.tests import uuidsentinel as uuids - - -FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - - -def compute_api_get(context, instance_id, expected_attrs=None): - return dict(uuid=FAKE_UUID, id=instance_id, instance_type_id=1, host='bob') - - -def _generate_fake_vifs(context): - vif = vif_obj.VirtualInterface(context=context) - vif.address = '00-00-00-00-00-00' - vif.network_id = 123 - vif.net_uuid = '22222222-2222-2222-2222-22222222222222222' - vif.uuid = uuids.vif1_uuid - fake_vifs = [vif] - vif = vif_obj.VirtualInterface(context=context) - vif.address = '11-11-11-11-11-11' - vif.network_id = 456 - vif.net_uuid = '33333333-3333-3333-3333-33333333333333333' - vif.uuid = uuids.vif2_uuid - fake_vifs.append(vif) - return fake_vifs - - -def get_vifs_by_instance(context, instance_id): - return _generate_fake_vifs(context) - - -class FakeRequest(object): - def __init__(self, context): - self.environ = {'nova.context': context} - - -class ServerVirtualInterfaceTestV21(test.NoDBTestCase): - wsgi_api_version = '2.1' - expected_response = { - 'virtual_interfaces': [ - {'id': uuids.vif1_uuid, - 'mac_address': '00-00-00-00-00-00'}, - {'id': uuids.vif2_uuid, - 'mac_address': '11-11-11-11-11-11'}]} - - def setUp(self): - super(ServerVirtualInterfaceTestV21, self).setUp() - # These APIs aren't implemented by the neutronv2 API code in Nova so - # the tests need to specifically run against nova-network unless - # otherwise setup to run with Neutron and expect failure. - self.flags(use_neutron=False) - self.compute_api_get_patcher = mock.patch.object( - compute.api.API, "get", - side_effect=compute_api_get) - self.get_vifs_by_instance_patcher = mock.patch.object( - network.api.API, "get_vifs_by_instance", - side_effect=get_vifs_by_instance) - self.compute_api_get_patcher.start() - self.get_vifs_by_instance_patcher.start() - self.addCleanup(self.compute_api_get_patcher.stop) - self.addCleanup(self.get_vifs_by_instance_patcher.stop) - self._set_controller() - - def _set_controller(self): - self.controller = vi21.ServerVirtualInterfaceController() - - def test_get_virtual_interfaces_list(self): - req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version) - res_dict = self.controller.index(req, 'fake_uuid') - self.assertEqual(self.expected_response, res_dict) - - def test_get_virtual_interfaces_list_offset_and_limit(self): - path = '/v2/fake/os-virtual-interfaces?offset=1&limit=1' - req = fakes.HTTPRequest.blank(path, version=self.wsgi_api_version) - res_dict = self.controller.index(req, 'fake_uuid') - name = 'virtual_interfaces' - limited_response = {name: [self.expected_response[name][1]]} - self.assertEqual(limited_response, res_dict) - - @mock.patch.object(compute_api.API, 'get', - side_effect=exception.InstanceNotFound( - instance_id='instance-0000')) - def test_vif_instance_not_found(self, mock_get): - fake_context = context.RequestContext('fake', 'fake') - fake_req = FakeRequest(fake_context) - fake_req.api_version_request = api_version_request.APIVersionRequest( - self.wsgi_api_version) - self.assertRaises( - webob.exc.HTTPNotFound, - self.controller.index, - fake_req, 'fake_uuid') - mock_get.assert_called_once_with(fake_context, - 'fake_uuid', - expected_attrs=None) - - def test_list_vifs_neutron_notimplemented(self): - """Tests that a 400 is returned when using neutron as the backend""" - # unset the get_vifs_by_instance stub from setUp - self.get_vifs_by_instance_patcher.stop() - self.flags(use_neutron=True) - # reset the controller to use the neutron network API - self._set_controller() - req = fakes.HTTPRequest.blank('', version=self.wsgi_api_version) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.index, req, FAKE_UUID) - self.get_vifs_by_instance_patcher.start() - - -class ServerVirtualInterfaceTestV212(ServerVirtualInterfaceTestV21): - wsgi_api_version = '2.12' - - expected_response = { - 'virtual_interfaces': [ - {'id': uuids.vif1_uuid, - 'mac_address': '00-00-00-00-00-00', - 'net_id': '22222222-2222-2222-2222-22222222222222222'}, - {'id': uuids.vif2_uuid, - 'mac_address': '11-11-11-11-11-11', - 'net_id': '33333333-3333-3333-3333-33333333333333333'}]} - - -class ServerVirtualInterfaceEnforcementV21(test.NoDBTestCase): - - def setUp(self): - super(ServerVirtualInterfaceEnforcementV21, self).setUp() - self.controller = vi21.ServerVirtualInterfaceController() - self.req = fakes.HTTPRequest.blank('') - - def test_index_virtual_interfaces_policy_failed(self): - rule_name = "os_compute_api:os-virtual-interfaces" - self.policy.set_rules({rule_name: "project:non_fake"}) - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.index, self.req, fakes.FAKE_UUID) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - - -class ServerVirtualInterfaceDeprecationTest(test.NoDBTestCase): - - def setUp(self): - super(ServerVirtualInterfaceDeprecationTest, self).setUp() - self.controller = vi21.ServerVirtualInterfaceController() - self.req = fakes.HTTPRequest.blank('', version='2.44') - - def test_index_not_found(self): - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.index, self.req, FAKE_UUID) diff --git a/nova/tests/unit/fake_policy.py b/nova/tests/unit/fake_policy.py index c639fee20759..b43fb0f3a324 100644 --- a/nova/tests/unit/fake_policy.py +++ b/nova/tests/unit/fake_policy.py @@ -97,7 +97,6 @@ policy_data = """ "os_compute_api:os-shelve:unshelve": "", "os_compute_api:os-suspend-server:suspend": "", "os_compute_api:os-suspend-server:resume": "", - "os_compute_api:os-virtual-interfaces": "", "os_compute_api:os-volumes": "", "os_compute_api:os-volumes-attachments:index": "", "os_compute_api:os-volumes-attachments:show": "", diff --git a/nova/tests/unit/test_policy.py b/nova/tests/unit/test_policy.py index d5dad45d3cdb..cbe1a2591170 100644 --- a/nova/tests/unit/test_policy.py +++ b/nova/tests/unit/test_policy.py @@ -433,7 +433,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase): "os_compute_api:os-server-groups:delete", "os_compute_api:os-shelve:shelve", "os_compute_api:os-shelve:unshelve", -"os_compute_api:os-virtual-interfaces", "os_compute_api:os-volumes", "os_compute_api:os-volumes-attachments:index", "os_compute_api:os-volumes-attachments:show", diff --git a/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml index 76c1706ba545..36480d849dc1 100644 --- a/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml +++ b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml @@ -8,6 +8,7 @@ upgrade: * ``GET /os-fping`` * ``GET /os-fping/{server_id}`` + * ``GET /servers/{server_id}/os-virtual-interfaces`` In addition, the following configuration options have been removed.