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
This commit is contained in:
parent
d5202b5561
commit
4c93003ede
@ -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-default-rules.inc
|
||||||
.. include:: os-security-group-rules.inc
|
.. include:: os-security-group-rules.inc
|
||||||
.. include:: os-hosts.inc
|
.. include:: os-hosts.inc
|
||||||
.. include:: os-virtual-interfaces.inc
|
|
||||||
|
|
||||||
=============
|
=============
|
||||||
Obsolete APIs
|
Obsolete APIs
|
||||||
@ -81,3 +80,4 @@ Compute API in the past, but no longer exist.
|
|||||||
.. include:: os-certificates.inc
|
.. include:: os-certificates.inc
|
||||||
.. include:: os-cloudpipe.inc
|
.. include:: os-cloudpipe.inc
|
||||||
.. include:: os-fping.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
|
.. 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
|
is deprecated from the Microversion 2.44. This API will fail with
|
||||||
a 404 starting from microversion 2.44. To query the server attached
|
a 404 starting from microversion 2.44. It was removed in the
|
||||||
neutron interface, please use the API
|
18.0.0 Rocky release.
|
||||||
|
|
||||||
|
To query the server attached neutron interface, please use the API
|
||||||
``GET /servers/{server_uuid}/os-interface``.
|
``GET /servers/{server_uuid}/os-interface``.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -32,7 +34,8 @@ the server to perform this operation. Change these permissions through the
|
|||||||
|
|
||||||
Normal response codes: 200
|
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
|
Request
|
||||||
-------
|
-------
|
||||||
|
@ -15,61 +15,13 @@
|
|||||||
|
|
||||||
"""The virtual interfaces extension."""
|
"""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.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):
|
class ServerVirtualInterfaceController(wsgi.Controller):
|
||||||
"""The instance VIF API controller for the OpenStack API.
|
|
||||||
|
|
||||||
This API is deprecated from the Microversion '2.44'.
|
@wsgi.expected_errors((410))
|
||||||
"""
|
|
||||||
|
|
||||||
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))
|
|
||||||
def index(self, req, server_id):
|
def index(self, req, server_id):
|
||||||
"""Returns the list of VIFs for a given instance."""
|
raise exc.HTTPGone()
|
||||||
return self._items(req, server_id,
|
|
||||||
entity_maker=_translate_vif_summary_view)
|
|
||||||
|
@ -83,7 +83,6 @@ from nova.policies import simple_tenant_usage
|
|||||||
from nova.policies import suspend_server
|
from nova.policies import suspend_server
|
||||||
from nova.policies import tenant_networks
|
from nova.policies import tenant_networks
|
||||||
from nova.policies import used_limits
|
from nova.policies import used_limits
|
||||||
from nova.policies import virtual_interfaces
|
|
||||||
from nova.policies import volumes
|
from nova.policies import volumes
|
||||||
from nova.policies import volumes_attachments
|
from nova.policies import volumes_attachments
|
||||||
|
|
||||||
@ -160,7 +159,6 @@ def list_rules():
|
|||||||
suspend_server.list_rules(),
|
suspend_server.list_rules(),
|
||||||
tenant_networks.list_rules(),
|
tenant_networks.list_rules(),
|
||||||
used_limits.list_rules(),
|
used_limits.list_rules(),
|
||||||
virtual_interfaces.list_rules(),
|
|
||||||
volumes.list_rules(),
|
volumes.list_rules(),
|
||||||
volumes_attachments.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
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# 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):
|
class VirtualInterfacesJsonTest(api_samples_test_base.ApiSampleTestBase):
|
||||||
sample_dir = "os-virtual-interfaces"
|
api_major_version = 'v2'
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(VirtualInterfacesJsonTest, self).setUp()
|
|
||||||
self.template = 'vifs-list-resp'
|
|
||||||
if self.api_major_version == 'v2':
|
|
||||||
self.template = 'vifs-list-resp-v2'
|
|
||||||
|
|
||||||
def test_vifs_list(self):
|
def test_vifs_list(self):
|
||||||
uuid = self._post_server()
|
uuid = uuids.instance_1
|
||||||
|
|
||||||
response = self._do_get('servers/%s/os-virtual-interfaces' % uuid)
|
ex = self.assertRaises(api_client.OpenStackApiException,
|
||||||
|
self.api.api_get,
|
||||||
subs = {'mac_addr': '(?:[a-f0-9]{2}:){5}[a-f0-9]{2}'}
|
'/servers/%s/os-virtual-interfaces' % uuid)
|
||||||
self._verify_response(self.template, subs, response, 200)
|
self.assertEqual(410, ex.response.status_code)
|
||||||
|
|
||||||
|
|
||||||
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'})]
|
|
||||||
|
@ -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-shelve:unshelve": "",
|
||||||
"os_compute_api:os-suspend-server:suspend": "",
|
"os_compute_api:os-suspend-server:suspend": "",
|
||||||
"os_compute_api:os-suspend-server:resume": "",
|
"os_compute_api:os-suspend-server:resume": "",
|
||||||
"os_compute_api:os-virtual-interfaces": "",
|
|
||||||
"os_compute_api:os-volumes": "",
|
"os_compute_api:os-volumes": "",
|
||||||
"os_compute_api:os-volumes-attachments:index": "",
|
"os_compute_api:os-volumes-attachments:index": "",
|
||||||
"os_compute_api:os-volumes-attachments:show": "",
|
"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-server-groups:delete",
|
||||||
"os_compute_api:os-shelve:shelve",
|
"os_compute_api:os-shelve:shelve",
|
||||||
"os_compute_api:os-shelve:unshelve",
|
"os_compute_api:os-shelve:unshelve",
|
||||||
"os_compute_api:os-virtual-interfaces",
|
|
||||||
"os_compute_api:os-volumes",
|
"os_compute_api:os-volumes",
|
||||||
"os_compute_api:os-volumes-attachments:index",
|
"os_compute_api:os-volumes-attachments:index",
|
||||||
"os_compute_api:os-volumes-attachments:show",
|
"os_compute_api:os-volumes-attachments:show",
|
||||||
|
@ -8,6 +8,7 @@ upgrade:
|
|||||||
|
|
||||||
* ``GET /os-fping``
|
* ``GET /os-fping``
|
||||||
* ``GET /os-fping/{server_id}``
|
* ``GET /os-fping/{server_id}``
|
||||||
|
* ``GET /servers/{server_id}/os-virtual-interfaces``
|
||||||
|
|
||||||
In addition, the following configuration options have been removed.
|
In addition, the following configuration options have been removed.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user