Drop OPENSTACK_NOVA_EXTENSIONS_BLACKLIST finally
Part of the removal of OPENSTACK_NOVA_EXTENSIONS_BLACKLIST (3/3) Clean up nova extensions related code in the API layer. Change-Id: I9730095365342cac1023f4112bae4b3a28cdeaf7
This commit is contained in:
parent
3c6286a9e9
commit
672c43c43e
@ -2312,41 +2312,6 @@ Note that when disabling the query to neutron it takes some time until
|
|||||||
associated floating IPs are visible in the project instance table and
|
associated floating IPs are visible in the project instance table and
|
||||||
users may reload the table to check them.
|
users may reload the table to check them.
|
||||||
|
|
||||||
OPENSTACK_NOVA_EXTENSIONS_BLACKLIST
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.0(Liberty)
|
|
||||||
|
|
||||||
.. deprecated:: 17.2.0(Ussuri)
|
|
||||||
|
|
||||||
Default: ``[]``
|
|
||||||
|
|
||||||
Ignore all listed Nova extensions, and behave as if they were unsupported.
|
|
||||||
Can be used to selectively disable certain costly extensions for performance
|
|
||||||
reasons.
|
|
||||||
|
|
||||||
Along with the deprecation, the current plan on individual effective values
|
|
||||||
in this setting is as follows.
|
|
||||||
|
|
||||||
The support of ``SimpleTenantUsage`` will be replaced by a new setting which
|
|
||||||
controls whether ``SimpleTenantUsage`` nova API feature is used or not
|
|
||||||
(not implemented yet as of Victoria; planned in Wallaby release).
|
|
||||||
This setting will not be droped until the new setting is implemented.
|
|
||||||
|
|
||||||
The support of the following values will be simply dropped
|
|
||||||
as nova provides all features in the recent API versions.
|
|
||||||
|
|
||||||
* ``AdminActions``
|
|
||||||
* ``Aggregates``
|
|
||||||
* ``BlockDeviceMappingV2Boot``
|
|
||||||
* ``ConfigDrive``
|
|
||||||
* ``DiskConfig``
|
|
||||||
* ``Keypairs``
|
|
||||||
* ``SchedulerHints``
|
|
||||||
* ``ServerGroups``
|
|
||||||
* ``Services``
|
|
||||||
* ``Shelve``
|
|
||||||
|
|
||||||
OPENSTACK_USE_SIMPLE_TENANT_USAGE
|
OPENSTACK_USE_SIMPLE_TENANT_USAGE
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ import collections
|
|||||||
import logging
|
import logging
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from novaclient import api_versions
|
from novaclient import api_versions
|
||||||
@ -46,114 +45,6 @@ INSTANCE_ACTIVE_STATE = 'ACTIVE'
|
|||||||
VOLUME_STATE_AVAILABLE = "available"
|
VOLUME_STATE_AVAILABLE = "available"
|
||||||
DEFAULT_QUOTA_NAME = 'default'
|
DEFAULT_QUOTA_NAME = 'default'
|
||||||
|
|
||||||
# python-novaclient 16.0.0 removed the list_extensions module and the
|
|
||||||
# GET /extensions API is deprecated since Newton. Furthermore, the ability
|
|
||||||
# to enable/disable compute API extensions was also removed in Newton.
|
|
||||||
# Therefore we hard-code the list of extensions here until the
|
|
||||||
# OPENSTACK_NOVA_EXTENSIONS_BLACKLIST setting is no longer used.
|
|
||||||
EXTENSIONS = (
|
|
||||||
'AccessIPs',
|
|
||||||
'AdminActions',
|
|
||||||
'AdminPassword',
|
|
||||||
'Agents',
|
|
||||||
'Aggregates',
|
|
||||||
'AssistedVolumeSnapshots',
|
|
||||||
'AttachInterfaces',
|
|
||||||
'AvailabilityZone',
|
|
||||||
'BareMetalExtStatus',
|
|
||||||
'BareMetalNodes',
|
|
||||||
'BlockDeviceMapping',
|
|
||||||
'BlockDeviceMappingV2Boot',
|
|
||||||
'CellCapacities',
|
|
||||||
'Cells',
|
|
||||||
'Certificates',
|
|
||||||
'Cloudpipe',
|
|
||||||
'CloudpipeUpdate',
|
|
||||||
'ConfigDrive',
|
|
||||||
'ConsoleAuthTokens',
|
|
||||||
'ConsoleOutput',
|
|
||||||
'Consoles',
|
|
||||||
'CreateBackup',
|
|
||||||
'Createserverext',
|
|
||||||
'DeferredDelete',
|
|
||||||
'DiskConfig',
|
|
||||||
'Evacuate',
|
|
||||||
'ExtendedAvailabilityZone',
|
|
||||||
'ExtendedEvacuateFindHost',
|
|
||||||
'ExtendedFloatingIps',
|
|
||||||
'ExtendedHypervisors',
|
|
||||||
'ExtendedIps',
|
|
||||||
'ExtendedIpsMac',
|
|
||||||
'ExtendedNetworks',
|
|
||||||
'ExtendedQuotas',
|
|
||||||
'ExtendedRescueWithImage',
|
|
||||||
'ExtendedServerAttributes',
|
|
||||||
'ExtendedServices',
|
|
||||||
'ExtendedServicesDelete',
|
|
||||||
'ExtendedStatus',
|
|
||||||
'ExtendedStatus',
|
|
||||||
'ExtendedVolumes',
|
|
||||||
'FixedIPs',
|
|
||||||
'FlavorAccess',
|
|
||||||
'FlavorDisabled',
|
|
||||||
'FlavorExtraData',
|
|
||||||
'FlavorExtraSpecs',
|
|
||||||
'FlavorManage',
|
|
||||||
'FlavorRxtx',
|
|
||||||
'FlavorSwap',
|
|
||||||
'FloatingIpDns',
|
|
||||||
'FloatingIpPools',
|
|
||||||
'FloatingIps',
|
|
||||||
'FloatingIpsBulk',
|
|
||||||
'Fping',
|
|
||||||
'HideServerAddresses',
|
|
||||||
'Hosts',
|
|
||||||
'HypervisorStatus',
|
|
||||||
'Hypervisors',
|
|
||||||
'ImageSize',
|
|
||||||
'InstanceActions',
|
|
||||||
'Keypairs',
|
|
||||||
'LockServer',
|
|
||||||
'MigrateServer',
|
|
||||||
'Migrations',
|
|
||||||
'Multinic',
|
|
||||||
'MultipleCreate',
|
|
||||||
'NetworkAssociationSupport',
|
|
||||||
'Networks',
|
|
||||||
'OSInstanceUsageAuditLog',
|
|
||||||
'OSTenantNetworks',
|
|
||||||
'PauseServer',
|
|
||||||
'Personality',
|
|
||||||
'PreserveEphemeralOnRebuild',
|
|
||||||
'QuotaClasses',
|
|
||||||
'Quotas',
|
|
||||||
'Rescue',
|
|
||||||
'SchedulerHints',
|
|
||||||
'SecurityGroupDefaultRules',
|
|
||||||
'SecurityGroups',
|
|
||||||
'ServerDiagnostics',
|
|
||||||
'ServerExternalEvents',
|
|
||||||
'ServerGroupQuotas',
|
|
||||||
'ServerGroups',
|
|
||||||
'ServerListMultiStatus',
|
|
||||||
'ServerPassword',
|
|
||||||
'ServerSortKeys',
|
|
||||||
'ServerStartStop',
|
|
||||||
'ServerUsage',
|
|
||||||
'Services',
|
|
||||||
'Shelve',
|
|
||||||
'SimpleTenantUsage',
|
|
||||||
'SuspendServer',
|
|
||||||
'UsedLimits',
|
|
||||||
'UsedLimitsForAdmin',
|
|
||||||
'UserData',
|
|
||||||
'UserQuotas',
|
|
||||||
'VirtualInterfaces',
|
|
||||||
'VolumeAttachmentUpdate',
|
|
||||||
'Volumes'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
get_microversion = _nova.get_microversion
|
get_microversion = _nova.get_microversion
|
||||||
server_get = _nova.server_get
|
server_get = _nova.server_get
|
||||||
Server = _nova.Server
|
Server = _nova.Server
|
||||||
@ -1124,27 +1015,6 @@ def interface_detach(request, server, port_id):
|
|||||||
return _nova.novaclient(request).servers.interface_detach(server, port_id)
|
return _nova.novaclient(request).servers.interface_detach(server, port_id)
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
|
||||||
@memoized.memoized
|
|
||||||
def list_extensions(request):
|
|
||||||
"""List all nova extension names, except the ones in the blacklist."""
|
|
||||||
blacklist = set(settings.OPENSTACK_NOVA_EXTENSIONS_BLACKLIST)
|
|
||||||
return tuple(
|
|
||||||
extension for extension in EXTENSIONS if extension not in blacklist
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
|
||||||
@memoized.memoized
|
|
||||||
def extension_supported(extension_name, request):
|
|
||||||
"""Determine if nova supports a given extension name.
|
|
||||||
|
|
||||||
Example values for the extension_name include AdminActions, ConsoleOutput,
|
|
||||||
etc.
|
|
||||||
"""
|
|
||||||
return extension_name in list_extensions(request)
|
|
||||||
|
|
||||||
|
|
||||||
@profiler.trace
|
@profiler.trace
|
||||||
def can_set_server_password():
|
def can_set_server_password():
|
||||||
return utils.get_dict_config('OPENSTACK_HYPERVISOR_FEATURES',
|
return utils.get_dict_config('OPENSTACK_HYPERVISOR_FEATURES',
|
||||||
|
@ -120,11 +120,9 @@ class Services(generic.View):
|
|||||||
def get(self, request):
|
def get(self, request):
|
||||||
"""Get a list of nova services.
|
"""Get a list of nova services.
|
||||||
|
|
||||||
Will return HTTP 501 status code if the service_list extension is
|
Will return HTTP 501 status code if the compute service is enabled.
|
||||||
not supported.
|
|
||||||
"""
|
"""
|
||||||
if (api.base.is_service_enabled(request, 'compute') and
|
if api.base.is_service_enabled(request, 'compute'):
|
||||||
api.nova.extension_supported('Services', request)):
|
|
||||||
result = api.nova.service_list(request)
|
result = api.nova.service_list(request)
|
||||||
return {'items': [u.to_dict() for u in result]}
|
return {'items': [u.to_dict() for u in result]}
|
||||||
raise rest_utils.AjaxError(501, '')
|
raise rest_utils.AjaxError(501, '')
|
||||||
@ -347,7 +345,7 @@ class Servers(generic.View):
|
|||||||
:param name: The new server name.
|
:param name: The new server name.
|
||||||
:param source_id: The ID of the image to use.
|
:param source_id: The ID of the image to use.
|
||||||
:param flavor_id: The ID of the flavor to use.
|
:param flavor_id: The ID of the flavor to use.
|
||||||
:param key_name: (optional extension) name of previously created
|
:param key_name: (optional) name of previously created
|
||||||
keypair to inject into the instance.
|
keypair to inject into the instance.
|
||||||
:param user_data: user data to pass to be exposed by the metadata
|
:param user_data: user data to pass to be exposed by the metadata
|
||||||
server this can be a file type object as well or a
|
server this can be a file type object as well or a
|
||||||
@ -501,25 +499,6 @@ class ServerMetadata(generic.View):
|
|||||||
api.nova.server_metadata_delete(request, server_id, removed)
|
api.nova.server_metadata_delete(request, server_id, removed)
|
||||||
|
|
||||||
|
|
||||||
@urls.register
|
|
||||||
class Extensions(generic.View):
|
|
||||||
"""API for nova extensions."""
|
|
||||||
url_regex = r'nova/extensions/$'
|
|
||||||
|
|
||||||
@rest_utils.ajax()
|
|
||||||
def get(self, request):
|
|
||||||
"""Get a list of extensions.
|
|
||||||
|
|
||||||
The listing result is an object with property "items". Each item is
|
|
||||||
an object with property "name".
|
|
||||||
|
|
||||||
Example GET:
|
|
||||||
http://localhost/api/nova/extensions
|
|
||||||
"""
|
|
||||||
result = api.nova.list_extensions(request)
|
|
||||||
return {'items': [{'name': e} for e in result]}
|
|
||||||
|
|
||||||
|
|
||||||
@urls.register
|
@urls.register
|
||||||
class Flavors(generic.View):
|
class Flavors(generic.View):
|
||||||
"""API for nova flavors."""
|
"""API for nova flavors."""
|
||||||
|
@ -461,8 +461,6 @@ OPENSTACK_NEUTRON_NETWORK = {
|
|||||||
# a performance issue in the project instance table in large deployments.
|
# a performance issue in the project instance table in large deployments.
|
||||||
OPENSTACK_INSTANCE_RETRIEVE_IP_ADDRESSES = True
|
OPENSTACK_INSTANCE_RETRIEVE_IP_ADDRESSES = True
|
||||||
|
|
||||||
OPENSTACK_NOVA_EXTENSIONS_BLACKLIST = []
|
|
||||||
|
|
||||||
# This setting controls whether SimpleTenantUsage nova API is used in the usage
|
# This setting controls whether SimpleTenantUsage nova API is used in the usage
|
||||||
# overview. According to feedbacks to the horizon team, the usage of
|
# overview. According to feedbacks to the horizon team, the usage of
|
||||||
# SimpleTenantUsage can cause performance issues in the nova API in larger
|
# SimpleTenantUsage can cause performance issues in the nova API in larger
|
||||||
|
@ -483,19 +483,6 @@ class NovaRestTestCase(test.TestCase):
|
|||||||
request, '1', ['c', 'd']
|
request, '1', ['c', 'd']
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
|
||||||
# Extensions
|
|
||||||
#
|
|
||||||
@test.create_mocks({api.nova: ['list_extensions']})
|
|
||||||
def test_extension_list(self):
|
|
||||||
request = self.mock_rest_request()
|
|
||||||
self.mock_list_extensions.return_value = ['foo', 'bar']
|
|
||||||
response = nova.Extensions().get(request)
|
|
||||||
self.assertStatusCode(response, 200)
|
|
||||||
self.assertEqual({"items": [{"name": "foo"}, {"name": "bar"}]},
|
|
||||||
response.json)
|
|
||||||
self.mock_list_extensions.assert_called_once_with(request)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Flavors
|
# Flavors
|
||||||
#
|
#
|
||||||
@ -892,8 +879,7 @@ class NovaRestTestCase(test.TestCase):
|
|||||||
#
|
#
|
||||||
|
|
||||||
@test.create_mocks({api.base: ['is_service_enabled'],
|
@test.create_mocks({api.base: ['is_service_enabled'],
|
||||||
api.nova: ['service_list',
|
api.nova: ['service_list']})
|
||||||
'extension_supported']})
|
|
||||||
def test_services_get(self):
|
def test_services_get(self):
|
||||||
request = self.mock_rest_request(GET={})
|
request = self.mock_rest_request(GET={})
|
||||||
self.mock_service_list.return_value = [
|
self.mock_service_list.return_value = [
|
||||||
@ -901,7 +887,6 @@ class NovaRestTestCase(test.TestCase):
|
|||||||
mock.Mock(**{'to_dict.return_value': {'id': '2'}})
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}})
|
||||||
]
|
]
|
||||||
self.mock_is_service_enabled.return_value = True
|
self.mock_is_service_enabled.return_value = True
|
||||||
self.mock_extension_supported.return_value = True
|
|
||||||
|
|
||||||
response = nova.Services().get(request)
|
response = nova.Services().get(request)
|
||||||
|
|
||||||
@ -911,8 +896,6 @@ class NovaRestTestCase(test.TestCase):
|
|||||||
self.mock_service_list.assert_called_once_with(request)
|
self.mock_service_list.assert_called_once_with(request)
|
||||||
self.mock_is_service_enabled.assert_called_once_with(request,
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
||||||
'compute')
|
'compute')
|
||||||
self.mock_extension_supported.assert_called_once_with(
|
|
||||||
'Services', request)
|
|
||||||
|
|
||||||
@mock.patch.object(api.base, 'is_service_enabled')
|
@mock.patch.object(api.base, 'is_service_enabled')
|
||||||
def test_services_get_disabled(self, mock_is_service_enabled):
|
def test_services_get_disabled(self, mock_is_service_enabled):
|
||||||
|
@ -70,15 +70,6 @@ class ComputeApiTests(test.APIMockTestCase):
|
|||||||
# To handle upgrade_api
|
# To handle upgrade_api
|
||||||
mock_novaclient.api_version = api_versions.APIVersion(version)
|
mock_novaclient.api_version = api_versions.APIVersion(version)
|
||||||
|
|
||||||
@override_settings(OPENSTACK_NOVA_EXTENSIONS_BLACKLIST=['ConsoleOutput'])
|
|
||||||
def test_extension_supported(self):
|
|
||||||
self.assertTrue(api.nova.extension_supported(
|
|
||||||
'Evacuate', mock.sentinel.request))
|
|
||||||
self.assertFalse(api.nova.extension_supported(
|
|
||||||
'ConsoleOutput', mock.sentinel.request))
|
|
||||||
self.assertFalse(api.nova.extension_supported(
|
|
||||||
'DoesNotExist', mock.sentinel.request))
|
|
||||||
|
|
||||||
@mock.patch.object(api._nova, 'novaclient')
|
@mock.patch.object(api._nova, 'novaclient')
|
||||||
def test_server_reboot(self, mock_novaclient):
|
def test_server_reboot(self, mock_novaclient):
|
||||||
server = self.servers.first()
|
server = self.servers.first()
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
``OPENSTACK_NOVA_EXTENSIONS_BLACKLIST`` setting is now dropped.
|
||||||
|
If you specify ``SimpleTenantUsage`` in this setting, consider setting
|
||||||
|
``OPENSTACK_USE_SIMPLE_TENANT_USAGE`` to ``False`` instead.
|
||||||
|
For other effective values in this setting, no replacement is
|
||||||
|
provided as nova provides all features in recent versions of nova API.
|
||||||
|
Note that you can enable/disable table actions via policy rules.
|
Loading…
x
Reference in New Issue
Block a user