Merge "nova-net: Remove 'networks' quota"
This commit is contained in:
commit
5b2e906bb4
|
@ -34,7 +34,7 @@ EXTENDED_QUOTAS = ['server_groups', 'server_group_members']
|
||||||
|
|
||||||
# NOTE(gmann): Network related quotas are filter out in
|
# NOTE(gmann): Network related quotas are filter out in
|
||||||
# microversion 2.50. Bug#1701211.
|
# microversion 2.50. Bug#1701211.
|
||||||
FILTERED_QUOTAS_2_50 = ["fixed_ips", "floating_ips", "networks",
|
FILTERED_QUOTAS_2_50 = ["fixed_ips", "floating_ips",
|
||||||
"security_group_rules", "security_groups"]
|
"security_group_rules", "security_groups"]
|
||||||
|
|
||||||
# Microversion 2.57 removes personality (injected) files from the API.
|
# Microversion 2.57 removes personality (injected) files from the API.
|
||||||
|
|
|
@ -37,7 +37,7 @@ from nova import quota
|
||||||
CONF = nova.conf.CONF
|
CONF = nova.conf.CONF
|
||||||
QUOTAS = quota.QUOTAS
|
QUOTAS = quota.QUOTAS
|
||||||
|
|
||||||
FILTERED_QUOTAS_2_36 = ["fixed_ips", "floating_ips", "networks",
|
FILTERED_QUOTAS_2_36 = ["fixed_ips", "floating_ips",
|
||||||
"security_group_rules", "security_groups"]
|
"security_group_rules", "security_groups"]
|
||||||
|
|
||||||
FILTERED_QUOTAS_2_57 = list(FILTERED_QUOTAS_2_36)
|
FILTERED_QUOTAS_2_57 = list(FILTERED_QUOTAS_2_36)
|
||||||
|
@ -194,13 +194,11 @@ class QuotaSetsController(wsgi.Controller):
|
||||||
|
|
||||||
quota_set = body['quota_set']
|
quota_set = body['quota_set']
|
||||||
|
|
||||||
# NOTE(alex_xu): The CONF.enable_network_quota was deprecated
|
# NOTE(stephenfin): network quotas were only used by nova-network and
|
||||||
# due to it is only used by nova-network, and nova-network will be
|
# therefore should be explicitly rejected
|
||||||
# deprecated also. So when CONF.enable_newtork_quota is removed,
|
if 'networks' in quota_set:
|
||||||
# the networks quota will disappeare also.
|
|
||||||
if not CONF.enable_network_quota and 'networks' in quota_set:
|
|
||||||
raise webob.exc.HTTPBadRequest(
|
raise webob.exc.HTTPBadRequest(
|
||||||
explanation=_('The networks quota is disabled'))
|
explanation=_('The networks quota has been removed'))
|
||||||
|
|
||||||
force_update = strutils.bool_from_string(quota_set.get('force',
|
force_update = strutils.bool_from_string(quota_set.get('force',
|
||||||
'False'))
|
'False'))
|
||||||
|
|
|
@ -41,6 +41,8 @@ quota_resources = {
|
||||||
'injected_file_path_bytes': common_quota,
|
'injected_file_path_bytes': common_quota,
|
||||||
'server_groups': common_quota,
|
'server_groups': common_quota,
|
||||||
'server_group_members': common_quota,
|
'server_group_members': common_quota,
|
||||||
|
# NOTE(stephenfin): This will always be rejected since it was nova-network
|
||||||
|
# only, but we need to allow users to submit it at a minimum
|
||||||
'networks': common_quota
|
'networks': common_quota
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,21 +97,3 @@ class TenantNetworkController(wsgi.Controller):
|
||||||
@wsgi.expected_errors(410)
|
@wsgi.expected_errors(410)
|
||||||
def create(self, req, body):
|
def create(self, req, body):
|
||||||
raise exc.HTTPGone()
|
raise exc.HTTPGone()
|
||||||
|
|
||||||
|
|
||||||
def _network_count(context, project_id):
|
|
||||||
# NOTE(melwitt): This assumes a single cell.
|
|
||||||
ctx = nova_context.RequestContext(user_id=None, project_id=project_id)
|
|
||||||
ctx = ctx.elevated()
|
|
||||||
networks = nova.network.api.API().get_all(ctx)
|
|
||||||
return {'project': {'networks': len(networks)}}
|
|
||||||
|
|
||||||
|
|
||||||
def _register_network_quota():
|
|
||||||
if CONF.enable_network_quota:
|
|
||||||
QUOTAS.register_resource(quota.CountableResource('networks',
|
|
||||||
_network_count,
|
|
||||||
'quota_networks'))
|
|
||||||
|
|
||||||
|
|
||||||
_register_network_quota()
|
|
||||||
|
|
|
@ -1378,40 +1378,6 @@ Related options:
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
quota_opts = [
|
|
||||||
cfg.BoolOpt('enable_network_quota',
|
|
||||||
deprecated_for_removal=True,
|
|
||||||
deprecated_since='14.0.0',
|
|
||||||
deprecated_reason="""
|
|
||||||
CRUD operations on tenant networks are only available when using nova-network
|
|
||||||
and nova-network is itself deprecated.""",
|
|
||||||
default=False,
|
|
||||||
help="""
|
|
||||||
This option is used to enable or disable quota checking for tenant networks.
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* quota_networks
|
|
||||||
"""),
|
|
||||||
cfg.IntOpt('quota_networks',
|
|
||||||
deprecated_for_removal=True,
|
|
||||||
deprecated_since='14.0.0',
|
|
||||||
deprecated_reason="""
|
|
||||||
CRUD operations on tenant networks are only available when using nova-network
|
|
||||||
and nova-network is itself deprecated.""",
|
|
||||||
default=3,
|
|
||||||
min=0,
|
|
||||||
help="""
|
|
||||||
This option controls the number of private networks that can be created per
|
|
||||||
project (or per tenant).
|
|
||||||
|
|
||||||
Related options:
|
|
||||||
|
|
||||||
* enable_network_quota
|
|
||||||
"""),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
service_opts = [
|
service_opts = [
|
||||||
cfg.StrOpt('network_manager',
|
cfg.StrOpt('network_manager',
|
||||||
choices=[
|
choices=[
|
||||||
|
@ -1431,7 +1397,7 @@ nova-network is deprecated, as are any related configuration options.
|
||||||
|
|
||||||
ALL_DEFAULT_OPTS = (linux_net_opts + network_opts + ldap_dns_opts +
|
ALL_DEFAULT_OPTS = (linux_net_opts + network_opts + ldap_dns_opts +
|
||||||
rpcapi_opts + driver_opts + floating_ip_opts +
|
rpcapi_opts + driver_opts + floating_ip_opts +
|
||||||
ipv6_opts + quota_opts + service_opts)
|
ipv6_opts + service_opts)
|
||||||
|
|
||||||
|
|
||||||
def register_opts(conf):
|
def register_opts(conf):
|
||||||
|
|
|
@ -546,7 +546,7 @@ class DbQuotaDriver(object):
|
||||||
# together.
|
# together.
|
||||||
|
|
||||||
# per project quota limits (quotas that have no concept of
|
# per project quota limits (quotas that have no concept of
|
||||||
# user-scoping: fixed_ips, networks, floating_ips)
|
# user-scoping: fixed_ips, floating_ips)
|
||||||
project_quotas = objects.Quotas.get_all_by_project(context, project_id)
|
project_quotas = objects.Quotas.get_all_by_project(context, project_id)
|
||||||
# per user quotas, project quota limits (for quotas that have
|
# per user quotas, project quota limits (for quotas that have
|
||||||
# user-scoping, limits for the project)
|
# user-scoping, limits for the project)
|
||||||
|
@ -790,12 +790,6 @@ class BaseResource(object):
|
||||||
@property
|
@property
|
||||||
def default(self):
|
def default(self):
|
||||||
"""Return the default value of the quota."""
|
"""Return the default value of the quota."""
|
||||||
|
|
||||||
# NOTE(mikal): special case for quota_networks, which is an API
|
|
||||||
# flag and not a quota flag
|
|
||||||
if self.flag == 'quota_networks':
|
|
||||||
return CONF[self.flag]
|
|
||||||
|
|
||||||
return CONF.quota[self.flag] if self.flag else -1
|
return CONF.quota[self.flag] if self.flag else -1
|
||||||
|
|
||||||
|
|
||||||
|
@ -889,11 +883,6 @@ class QuotaEngine(object):
|
||||||
self.__driver = importutils.import_object(CONF.quota.driver)
|
self.__driver = importutils.import_object(CONF.quota.driver)
|
||||||
return self.__driver
|
return self.__driver
|
||||||
|
|
||||||
def register_resource(self, resource):
|
|
||||||
"""Register a resource."""
|
|
||||||
|
|
||||||
self._resources[resource.name] = resource
|
|
||||||
|
|
||||||
def get_defaults(self, context):
|
def get_defaults(self, context):
|
||||||
"""Retrieve the default quotas.
|
"""Retrieve the default quotas.
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ from requests import adapters
|
||||||
from sqlalchemy import exc as sqla_exc
|
from sqlalchemy import exc as sqla_exc
|
||||||
from wsgi_intercept import interceptor
|
from wsgi_intercept import interceptor
|
||||||
|
|
||||||
from nova.api.openstack.compute import tenant_networks
|
|
||||||
from nova.api.openstack import wsgi_app
|
from nova.api.openstack import wsgi_app
|
||||||
from nova.api import wsgi
|
from nova.api import wsgi
|
||||||
from nova.compute import multi_cell_list
|
from nova.compute import multi_cell_list
|
||||||
|
@ -1231,18 +1230,6 @@ class AllServicesCurrent(fixtures.Fixture):
|
||||||
return service_obj.SERVICE_VERSION
|
return service_obj.SERVICE_VERSION
|
||||||
|
|
||||||
|
|
||||||
class RegisterNetworkQuota(fixtures.Fixture):
|
|
||||||
def setUp(self):
|
|
||||||
super(RegisterNetworkQuota, self).setUp()
|
|
||||||
# Quota resource registration modifies the global QUOTAS engine, so
|
|
||||||
# this fixture registers and unregisters network quota for a test.
|
|
||||||
tenant_networks._register_network_quota()
|
|
||||||
self.addCleanup(self.cleanup)
|
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
nova_quota.QUOTAS._resources.pop('networks', None)
|
|
||||||
|
|
||||||
|
|
||||||
class _FakeNeutronClient(object):
|
class _FakeNeutronClient(object):
|
||||||
"""Class representing a Neutron client which wraps a NeutronFixture.
|
"""Class representing a Neutron client which wraps a NeutronFixture.
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ from nova.db import api as db
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import quota
|
from nova import quota
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests import fixtures as nova_fixtures
|
|
||||||
from nova.tests.unit.api.openstack import fakes
|
from nova.tests.unit.api.openstack import fakes
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,18 +283,6 @@ class QuotaSetsTestV21(BaseQuotaSetsTest):
|
||||||
mock_destroy_all_by_project.assert_called_once_with(
|
mock_destroy_all_by_project.assert_called_once_with(
|
||||||
req.environ['nova.context'], 1234)
|
req.environ['nova.context'], 1234)
|
||||||
|
|
||||||
def test_update_network_quota_disabled(self):
|
|
||||||
self.flags(enable_network_quota=False)
|
|
||||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
|
|
||||||
self._get_http_request(),
|
|
||||||
1234, body={'quota_set': {'networks': 1}})
|
|
||||||
|
|
||||||
def test_update_network_quota_enabled(self):
|
|
||||||
self.flags(enable_network_quota=True)
|
|
||||||
self.useFixture(nova_fixtures.RegisterNetworkQuota())
|
|
||||||
self.controller.update(self._get_http_request(),
|
|
||||||
1234, body={'quota_set': {'networks': 1}})
|
|
||||||
|
|
||||||
def test_duplicate_quota_filter(self):
|
def test_duplicate_quota_filter(self):
|
||||||
query_string = 'user_id=1&user_id=2'
|
query_string = 'user_id=1&user_id=2'
|
||||||
req = fakes.HTTPRequest.blank('', query_string=query_string)
|
req = fakes.HTTPRequest.blank('', query_string=query_string)
|
||||||
|
@ -585,10 +572,8 @@ class QuotaSetsTestV236(test.NoDBTestCase):
|
||||||
self.stub_out('nova.api.openstack.identity.verify_project_id',
|
self.stub_out('nova.api.openstack.identity.verify_project_id',
|
||||||
lambda ctx, project_id: True)
|
lambda ctx, project_id: True)
|
||||||
|
|
||||||
self.flags(enable_network_quota=True)
|
|
||||||
self.useFixture(nova_fixtures.RegisterNetworkQuota())
|
|
||||||
self.old_req = fakes.HTTPRequest.blank('', version='2.1')
|
self.old_req = fakes.HTTPRequest.blank('', version='2.1')
|
||||||
self.filtered_quotas = ['fixed_ips', 'floating_ips', 'networks',
|
self.filtered_quotas = ['fixed_ips', 'floating_ips',
|
||||||
'security_group_rules', 'security_groups']
|
'security_group_rules', 'security_groups']
|
||||||
self.quotas = {
|
self.quotas = {
|
||||||
'cores': {'limit': 20},
|
'cores': {'limit': 20},
|
||||||
|
@ -600,7 +585,6 @@ class QuotaSetsTestV236(test.NoDBTestCase):
|
||||||
'instances': {'limit': 10},
|
'instances': {'limit': 10},
|
||||||
'key_pairs': {'limit': 100},
|
'key_pairs': {'limit': 100},
|
||||||
'metadata_items': {'limit': 128},
|
'metadata_items': {'limit': 128},
|
||||||
'networks': {'limit': 3},
|
|
||||||
'ram': {'limit': 51200},
|
'ram': {'limit': 51200},
|
||||||
'security_group_rules': {'limit': 20},
|
'security_group_rules': {'limit': 20},
|
||||||
'security_groups': {'limit': 10},
|
'security_groups': {'limit': 10},
|
||||||
|
@ -617,7 +601,6 @@ class QuotaSetsTestV236(test.NoDBTestCase):
|
||||||
'instances': 10,
|
'instances': 10,
|
||||||
'key_pairs': 100,
|
'key_pairs': 100,
|
||||||
'metadata_items': 128,
|
'metadata_items': 128,
|
||||||
'networks': 3,
|
|
||||||
'ram': 51200,
|
'ram': 51200,
|
||||||
'security_group_rules': 20,
|
'security_group_rules': 20,
|
||||||
'security_groups': 10,
|
'security_groups': 10,
|
||||||
|
|
|
@ -22,7 +22,6 @@ from nova.api.openstack.compute import tenant_networks \
|
||||||
as networks_v21
|
as networks_v21
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests import fixtures as nova_fixtures
|
|
||||||
from nova.tests.unit.api.openstack import fakes
|
from nova.tests.unit.api.openstack import fakes
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
@ -71,8 +70,6 @@ class TenantNetworksTestV21(test.NoDBTestCase):
|
||||||
# os-tenant-networks only supports Neutron when listing networks or
|
# os-tenant-networks only supports Neutron when listing networks or
|
||||||
# showing details about a network, create and delete operations
|
# showing details about a network, create and delete operations
|
||||||
# result in a 503 and 500 response, respectively.
|
# result in a 503 and 500 response, respectively.
|
||||||
self.flags(enable_network_quota=True)
|
|
||||||
self.useFixture(nova_fixtures.RegisterNetworkQuota())
|
|
||||||
self.controller = self.ctrlr()
|
self.controller = self.ctrlr()
|
||||||
self.req = fakes.HTTPRequest.blank('')
|
self.req = fakes.HTTPRequest.blank('')
|
||||||
self.original_value = CONF.api.use_neutron_default_nets
|
self.original_value = CONF.api.use_neutron_default_nets
|
||||||
|
|
|
@ -248,13 +248,13 @@ class _TestQuotasObject(object):
|
||||||
mock_get_all.return_value = {'project_id': 'fake-project',
|
mock_get_all.return_value = {'project_id': 'fake-project',
|
||||||
'fixed_ips': 20, 'floating_ips': 5}
|
'fixed_ips': 20, 'floating_ips': 5}
|
||||||
mock_get_all_main.return_value = {'project_id': 'fake-project',
|
mock_get_all_main.return_value = {'project_id': 'fake-project',
|
||||||
'fixed_ips': 10, 'networks': 5}
|
'fixed_ips': 10}
|
||||||
quotas_dict = quotas_obj.Quotas.get_all_by_project(self.context,
|
quotas_dict = quotas_obj.Quotas.get_all_by_project(self.context,
|
||||||
'fake-project')
|
'fake-project')
|
||||||
mock_get_all.assert_called_once_with(self.context, 'fake-project')
|
mock_get_all.assert_called_once_with(self.context, 'fake-project')
|
||||||
mock_get_all_main.assert_called_once_with(self.context, 'fake-project')
|
mock_get_all_main.assert_called_once_with(self.context, 'fake-project')
|
||||||
expected = {'project_id': 'fake-project', 'fixed_ips': 20,
|
expected = {'project_id': 'fake-project', 'fixed_ips': 20,
|
||||||
'floating_ips': 5, 'networks': 5}
|
'floating_ips': 5}
|
||||||
self.assertEqual(expected, quotas_dict)
|
self.assertEqual(expected, quotas_dict)
|
||||||
|
|
||||||
@mock.patch('nova.objects.Quotas._get_all_from_db_by_project_and_user')
|
@mock.patch('nova.objects.Quotas._get_all_from_db_by_project_and_user')
|
||||||
|
|
|
@ -405,13 +405,6 @@ class QuotaEngineTestCase(test.TestCase):
|
||||||
quota_obj = quota.QuotaEngine(quota_driver=FakeDriver)
|
quota_obj = quota.QuotaEngine(quota_driver=FakeDriver)
|
||||||
self.assertEqual(quota_obj._driver, FakeDriver)
|
self.assertEqual(quota_obj._driver, FakeDriver)
|
||||||
|
|
||||||
def test_register_resource(self):
|
|
||||||
quota_obj = quota.QuotaEngine()
|
|
||||||
resource = quota.AbsoluteResource('test_resource')
|
|
||||||
quota_obj.register_resource(resource)
|
|
||||||
|
|
||||||
self.assertEqual(quota_obj._resources, dict(test_resource=resource))
|
|
||||||
|
|
||||||
def _get_quota_engine(self, driver, resources=None):
|
def _get_quota_engine(self, driver, resources=None):
|
||||||
resources = resources or [
|
resources = resources or [
|
||||||
quota.AbsoluteResource('test_resource4'),
|
quota.AbsoluteResource('test_resource4'),
|
||||||
|
|
|
@ -25,3 +25,21 @@ upgrade:
|
||||||
* ``os_compute_api:os-security-group-default-rules``
|
* ``os_compute_api:os-security-group-default-rules``
|
||||||
* ``os_compute_api:os-networks``
|
* ``os_compute_api:os-networks``
|
||||||
* ``os_compute_api:os-networks-associate``
|
* ``os_compute_api:os-networks-associate``
|
||||||
|
- |
|
||||||
|
The ``networks`` quota, which was only enabled if the
|
||||||
|
``enabled_network_quota`` config option was enabled and only useful with
|
||||||
|
*nova-network*, is removed. It will not longer be present in the responses
|
||||||
|
for the APIs while attempts to update the quota will be rejected.
|
||||||
|
|
||||||
|
* ``GET /os-quota-sets``
|
||||||
|
* ``GET /os-quota-sets/{project_id}``
|
||||||
|
* ``GET /os-quota-sets/{project_id}/defaults``
|
||||||
|
* ``GET /os-quota-sets/{project_id}/detail``
|
||||||
|
* ``PUT /os-quota-sets/{project_id}``
|
||||||
|
* ``GET /os-quota-class-sets/{id}``
|
||||||
|
* ``PUT /os-quota-class-sets/{id}``
|
||||||
|
|
||||||
|
The following related config options have been removed.
|
||||||
|
|
||||||
|
* ``enable_network_quota``
|
||||||
|
* ``quota_networks``
|
||||||
|
|
Loading…
Reference in New Issue