Merge "Remove support for /os-virtual-interfaces REST API"
This commit is contained in:
@@ -69,7 +69,6 @@ the `API guide <http://developer.openstack.org/api-guide/compute/index.html>`_.
|
||||
.. 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
|
||||
|
||||
@@ -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
|
||||
-------
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"virtual_interfaces": [
|
||||
{
|
||||
"id": "%(id)s",
|
||||
"mac_address": "%(mac_addr)s",
|
||||
"net_id": "%(id)s"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"virtual_interfaces": [
|
||||
{
|
||||
"id": "%(id)s",
|
||||
"mac_address": "%(mac_addr)s",
|
||||
"OS-EXT-VIF-NET:net_id": "%(id)s"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"virtual_interfaces": [
|
||||
{
|
||||
"id": "%(id)s",
|
||||
"mac_address": "%(mac_addr)s"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -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": "",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user