Pay attention to Nova disabled quotas defined in a config file
Since Nova doesn't currently provide an API call to indicate whether its quotas are disabled, we could use a parameter named 'enable_quotas' within 'OPENSTACK_HYPERVISOR_FEATURES' setting for this purpose. This allows to avoid errors while trying to update quotas which are disabled on service side. Also make disabled_quotas collection to be a set instead of a list - this removes duplicate fields that appear due to some possible quota overlaps between Nova and Neutron. Also, since we dropped out python2.6 support fancy set literals and dict comprehensions can be used. Co-Authored-By: Paul Karikh <pkarikh@mirantis.com> Closes-Bug: #1286099 Change-Id: I10923f147e4c323aba8bbcc130d2016ad6725e86
This commit is contained in:
parent
9e4e8e00d5
commit
baca29144b
@ -781,6 +781,7 @@ Default::
|
||||
'can_set_mount_point': False,
|
||||
'can_set_password': False,
|
||||
'requires_keypair': False,
|
||||
'enable_quotas': True
|
||||
}
|
||||
|
||||
A dictionary containing settings which can be used to identify the
|
||||
@ -797,6 +798,9 @@ an administrator password when launching or rebuilding an instance.
|
||||
Setting ``requires_keypair`` to ``True`` will require users to select
|
||||
a key pair when launching an instance.
|
||||
|
||||
Setting ``enable_quotas`` to ``False`` will make Horizon treat all Nova
|
||||
quotas as disabled, thus it won't try to modify them. By default, quotas are
|
||||
enabled.
|
||||
|
||||
``OPENSTACK_IMAGE_BACKEND``
|
||||
---------------------------
|
||||
|
@ -811,7 +811,8 @@ def tenant_quota_get(request, tenant_id):
|
||||
|
||||
|
||||
def tenant_quota_update(request, tenant_id, **kwargs):
|
||||
novaclient(request).quotas.update(tenant_id, **kwargs)
|
||||
if kwargs:
|
||||
novaclient(request).quotas.update(tenant_id, **kwargs)
|
||||
|
||||
|
||||
def default_quota_get(request, tenant_id):
|
||||
@ -1083,3 +1084,8 @@ def can_set_mount_point():
|
||||
def requires_keypair():
|
||||
features = getattr(settings, 'OPENSTACK_HYPERVISOR_FEATURES', {})
|
||||
return features.get('requires_keypair', False)
|
||||
|
||||
|
||||
def can_set_quotas():
|
||||
features = getattr(settings, 'OPENSTACK_HYPERVISOR_FEATURES', {})
|
||||
return features.get('enable_quotas', True)
|
||||
|
@ -312,9 +312,10 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
'tenant_quota_usages',),
|
||||
api.cinder: ('tenant_quota_update',),
|
||||
api.nova: ('tenant_quota_update',)})
|
||||
def test_add_project_post(self, neutron=False):
|
||||
def test_add_project_post(self):
|
||||
project = self.tenants.first()
|
||||
quota = self.quotas.first()
|
||||
disabled_quotas = self.disabled_quotas.first()
|
||||
default_role = self.roles.first()
|
||||
default_domain = self._get_default_domain()
|
||||
domain_id = default_domain.id
|
||||
@ -325,9 +326,6 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
# init
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.disabled_quotas.first())
|
||||
if neutron:
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.disabled_quotas.first())
|
||||
quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota)
|
||||
|
||||
api.keystone.get_default_role(IsA(http.HttpRequest)) \
|
||||
@ -364,8 +362,10 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
group=group_id,
|
||||
project=self.tenant.id)
|
||||
|
||||
nova_updated_quota = dict([(key, quota_data[key]) for key in
|
||||
quotas.NOVA_QUOTA_FIELDS])
|
||||
nova_updated_quota = {key: quota_data[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(disabled_quotas)
|
||||
api.nova.tenant_quota_update(IsA(http.HttpRequest),
|
||||
project.id,
|
||||
**nova_updated_quota)
|
||||
@ -406,7 +406,7 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
api.neutron.tenant_quota_update(IsA(http.HttpRequest),
|
||||
self.tenant.id,
|
||||
**neutron_updated_quota)
|
||||
self.test_add_project_post(neutron=True)
|
||||
self.test_add_project_post()
|
||||
|
||||
@test.create_stubs({api.keystone: ('user_list',
|
||||
'role_list',
|
||||
@ -531,6 +531,7 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
def test_add_project_quota_update_error(self):
|
||||
project = self.tenants.first()
|
||||
quota = self.quotas.first()
|
||||
disabled_quotas = self.disabled_quotas.first()
|
||||
default_role = self.roles.first()
|
||||
default_domain = self._get_default_domain()
|
||||
domain_id = default_domain.id
|
||||
@ -579,8 +580,10 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
group=group_id,
|
||||
project=self.tenant.id)
|
||||
|
||||
nova_updated_quota = dict([(key, quota_data[key]) for key in
|
||||
quotas.NOVA_QUOTA_FIELDS])
|
||||
nova_updated_quota = {key: quota_data[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(disabled_quotas)
|
||||
api.nova.tenant_quota_update(IsA(http.HttpRequest),
|
||||
project.id,
|
||||
**nova_updated_quota) \
|
||||
@ -617,6 +620,7 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
def test_add_project_user_update_error(self):
|
||||
project = self.tenants.first()
|
||||
quota = self.quotas.first()
|
||||
disabled_quotas = self.disabled_quotas.first()
|
||||
default_role = self.roles.first()
|
||||
default_domain = self._get_default_domain()
|
||||
domain_id = default_domain.id
|
||||
@ -660,8 +664,10 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
break
|
||||
break
|
||||
|
||||
nova_updated_quota = dict([(key, quota_data[key]) for key in
|
||||
quotas.NOVA_QUOTA_FIELDS])
|
||||
nova_updated_quota = {key: quota_data[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(disabled_quotas)
|
||||
api.nova.tenant_quota_update(IsA(http.HttpRequest),
|
||||
project.id,
|
||||
**nova_updated_quota)
|
||||
@ -961,11 +967,12 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
quotas: ('get_tenant_quota_data',
|
||||
'get_disabled_quotas',
|
||||
'tenant_quota_usages',)})
|
||||
def test_update_project_save(self, neutron=False):
|
||||
def test_update_project_save(self):
|
||||
keystone_api_version = api.keystone.VERSIONS.active
|
||||
|
||||
project = self.tenants.first()
|
||||
quota = self.quotas.first()
|
||||
disabled_quotas = self.disabled_quotas.first()
|
||||
default_role = self.roles.first()
|
||||
domain_id = project.domain_id
|
||||
users = self._get_all_users(domain_id)
|
||||
@ -983,9 +990,6 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
.AndReturn(self.domain)
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.disabled_quotas.first())
|
||||
if neutron:
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.disabled_quotas.first())
|
||||
quotas.get_tenant_quota_data(IsA(http.HttpRequest),
|
||||
tenant_id=self.tenant.id) \
|
||||
.AndReturn(quota)
|
||||
@ -1047,8 +1051,10 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
quotas.tenant_quota_usages(IsA(http.HttpRequest), tenant_id=project.id) \
|
||||
.AndReturn(quota_usages)
|
||||
|
||||
nova_updated_quota = dict([(key, updated_quota[key]) for key in
|
||||
quotas.NOVA_QUOTA_FIELDS])
|
||||
nova_updated_quota = {key: updated_quota[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(disabled_quotas)
|
||||
api.nova.tenant_quota_update(IsA(http.HttpRequest),
|
||||
project.id,
|
||||
**nova_updated_quota)
|
||||
@ -1093,7 +1099,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
api.neutron.tenant_quota_update(IsA(http.HttpRequest),
|
||||
self.tenant.id,
|
||||
**neutron_updated_quota)
|
||||
self.test_update_project_save(neutron=True)
|
||||
self.test_update_project_save()
|
||||
|
||||
@test.create_stubs({api.keystone: ('tenant_get',)})
|
||||
def test_update_project_get_error(self):
|
||||
@ -1256,6 +1262,7 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
|
||||
project = self.tenants.first()
|
||||
quota = self.quotas.first()
|
||||
disabled_quotas = self.disabled_quotas.first()
|
||||
default_role = self.roles.first()
|
||||
domain_id = project.domain_id
|
||||
users = self._get_all_users(domain_id)
|
||||
@ -1335,8 +1342,10 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
quotas.tenant_quota_usages(IsA(http.HttpRequest), tenant_id=project.id) \
|
||||
.AndReturn(quota_usages)
|
||||
|
||||
nova_updated_quota = dict([(key, updated_quota[key]) for key in
|
||||
quotas.NOVA_QUOTA_FIELDS])
|
||||
nova_updated_quota = {key: updated_quota[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(disabled_quotas)
|
||||
api.nova.tenant_quota_update(IsA(http.HttpRequest),
|
||||
project.id,
|
||||
**nova_updated_quota) \
|
||||
@ -1458,6 +1467,8 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
|
||||
api.keystone.user_list(IsA(http.HttpRequest),
|
||||
domain=domain_id).AndReturn(users)
|
||||
quotas.get_disabled_quotas(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.disabled_quotas.first())
|
||||
|
||||
self._check_role_list(keystone_api_version, role_assignments, groups,
|
||||
proj_users, roles, workflow_data)
|
||||
|
@ -385,9 +385,9 @@ class UpdateProjectGroups(workflows.UpdateMembersStep):
|
||||
|
||||
class CommonQuotaWorkflow(workflows.Workflow):
|
||||
def _update_project_quota(self, request, data, project_id):
|
||||
# Update the project quota.
|
||||
nova_data = dict(
|
||||
[(key, data[key]) for key in quotas.NOVA_QUOTA_FIELDS])
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
nova_data = {key: data[key] for key in
|
||||
set(quotas.NOVA_QUOTA_FIELDS) - disabled_quotas}
|
||||
nova.tenant_quota_update(request, project_id, **nova_data)
|
||||
|
||||
if cinder.is_volume_service_enabled(request):
|
||||
@ -400,7 +400,6 @@ class CommonQuotaWorkflow(workflows.Workflow):
|
||||
if api.base.is_service_enabled(request, 'network') and \
|
||||
api.neutron.is_quotas_extension_supported(request):
|
||||
neutron_data = {}
|
||||
disabled_quotas = quotas.get_disabled_quotas(request)
|
||||
for key in quotas.NEUTRON_QUOTA_FIELDS:
|
||||
if key not in disabled_quotas:
|
||||
neutron_data[key] = data[key]
|
||||
|
@ -251,6 +251,7 @@ OPENSTACK_HYPERVISOR_FEATURES = {
|
||||
'can_set_mount_point': False,
|
||||
'can_set_password': False,
|
||||
'requires_keypair': False,
|
||||
'enable_quotas': True
|
||||
}
|
||||
|
||||
# The OPENSTACK_CINDER_FEATURES settings can be used to enable optional
|
||||
|
@ -403,8 +403,8 @@ def data(TEST):
|
||||
TEST.quotas.add(base.QuotaSet(quota))
|
||||
|
||||
# nova quotas disabled when neutron is enabled
|
||||
disabled_quotas_nova = ['floating_ips', 'fixed_ips',
|
||||
'security_groups', 'security_group_rules']
|
||||
disabled_quotas_nova = {'floating_ips', 'fixed_ips',
|
||||
'security_groups', 'security_group_rules'}
|
||||
TEST.disabled_quotas.add(disabled_quotas_nova)
|
||||
|
||||
# Quota Usages
|
||||
|
@ -20,6 +20,7 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django import http
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from mox3.mox import IsA # noqa
|
||||
|
||||
@ -32,17 +33,26 @@ from openstack_dashboard.usage import quotas
|
||||
|
||||
class QuotaTests(test.APITestCase):
|
||||
|
||||
def get_usages(self, with_volume=True):
|
||||
usages = {'injected_file_content_bytes': {'quota': 1},
|
||||
'metadata_items': {'quota': 1},
|
||||
'injected_files': {'quota': 1},
|
||||
'security_groups': {'quota': 10},
|
||||
'security_group_rules': {'quota': 20},
|
||||
'fixed_ips': {'quota': 10},
|
||||
'ram': {'available': 8976, 'used': 1024, 'quota': 10000},
|
||||
'floating_ips': {'available': 0, 'used': 2, 'quota': 1},
|
||||
'instances': {'available': 8, 'used': 2, 'quota': 10},
|
||||
'cores': {'available': 8, 'used': 2, 'quota': 10}}
|
||||
def get_usages(self, with_volume=True, nova_quotas_enabled=True):
|
||||
if nova_quotas_enabled:
|
||||
usages = {'injected_file_content_bytes': {'quota': 1},
|
||||
'metadata_items': {'quota': 1},
|
||||
'injected_files': {'quota': 1},
|
||||
'security_groups': {'quota': 10},
|
||||
'security_group_rules': {'quota': 20},
|
||||
'fixed_ips': {'quota': 10},
|
||||
'ram': {'available': 8976, 'used': 1024, 'quota': 10000},
|
||||
'floating_ips': {'available': 0, 'used': 2, 'quota': 1},
|
||||
'instances': {'available': 8, 'used': 2, 'quota': 10},
|
||||
'cores': {'available': 8, 'used': 2, 'quota': 10}}
|
||||
else:
|
||||
inf = float('inf')
|
||||
usages = {'security_groups': {'available': inf, 'quota': inf},
|
||||
'ram': {'available': inf, 'used': 1024, 'quota': inf},
|
||||
'floating_ips': {
|
||||
'available': inf, 'used': 2, 'quota': inf},
|
||||
'instances': {'available': inf, 'used': 2, 'quota': inf},
|
||||
'cores': {'available': inf, 'used': 2, 'quota': inf}}
|
||||
if with_volume:
|
||||
usages.update({'volumes': {'available': 0, 'used': 4, 'quota': 1},
|
||||
'snapshots': {'available': 0, 'used': 3,
|
||||
@ -51,6 +61,13 @@ class QuotaTests(test.APITestCase):
|
||||
'quota': 1000}})
|
||||
return usages
|
||||
|
||||
def assertAvailableQuotasEqual(self, expected_usages, actual_usages):
|
||||
expected_available = {key: value['available'] for key, value in
|
||||
expected_usages.items() if 'available' in value}
|
||||
actual_available = {key: value['available'] for key, value in
|
||||
actual_usages.items() if 'available' in value}
|
||||
self.assertEqual(expected_available, actual_available)
|
||||
|
||||
@test.create_stubs({api.nova: ('server_list',
|
||||
'flavor_list',
|
||||
'tenant_quota_get',),
|
||||
@ -60,13 +77,13 @@ class QuotaTests(test.APITestCase):
|
||||
cinder: ('volume_list', 'volume_snapshot_list',
|
||||
'tenant_quota_get',
|
||||
'is_volume_service_enabled')})
|
||||
def test_tenant_quota_usages(self):
|
||||
def _test_tenant_quota_usages(self, nova_quotas_enabled=True,
|
||||
with_volume=True):
|
||||
servers = [s for s in self.servers.list()
|
||||
if s.tenant_id == self.request.user.tenant_id]
|
||||
|
||||
cinder.is_volume_service_enabled(
|
||||
IsA(http.HttpRequest)
|
||||
).AndReturn(True)
|
||||
cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(
|
||||
with_volume)
|
||||
api.base.is_service_enabled(IsA(http.HttpRequest),
|
||||
'network').AndReturn(False)
|
||||
api.nova.flavor_list(IsA(http.HttpRequest)) \
|
||||
@ -81,21 +98,49 @@ class QuotaTests(test.APITestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts,
|
||||
all_tenants=True) \
|
||||
.AndReturn([servers, False])
|
||||
opts = {'all_tenants': 1, 'project_id': self.request.user.tenant_id}
|
||||
cinder.volume_list(IsA(http.HttpRequest), opts) \
|
||||
.AndReturn(self.volumes.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \
|
||||
.AndReturn(self.cinder_volume_snapshots.list())
|
||||
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
||||
.AndReturn(self.cinder_quotas.first())
|
||||
if with_volume:
|
||||
opts = {'all_tenants': 1,
|
||||
'project_id': self.request.user.tenant_id}
|
||||
cinder.volume_list(IsA(http.HttpRequest), opts) \
|
||||
.AndReturn(self.volumes.list())
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest), opts) \
|
||||
.AndReturn(self.cinder_volume_snapshots.list())
|
||||
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
|
||||
.AndReturn(self.cinder_quotas.first())
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
quota_usages = quotas.tenant_quota_usages(self.request)
|
||||
expected_output = self.get_usages()
|
||||
expected_output = self.get_usages(
|
||||
nova_quotas_enabled=nova_quotas_enabled, with_volume=with_volume)
|
||||
|
||||
# Compare internal structure of usages to expected.
|
||||
self.assertItemsEqual(expected_output, quota_usages.usages)
|
||||
# Compare available resources
|
||||
self.assertAvailableQuotasEqual(expected_output, quota_usages.usages)
|
||||
|
||||
def test_tenant_quota_usages(self):
|
||||
self._test_tenant_quota_usages()
|
||||
|
||||
@override_settings(OPENSTACK_HYPERVISOR_FEATURES={'enable_quotas': False})
|
||||
def test_tenant_quota_usages_wo_nova_quotas(self):
|
||||
self._test_tenant_quota_usages(nova_quotas_enabled=False,
|
||||
with_volume=False)
|
||||
|
||||
@override_settings(OPENSTACK_HYPERVISOR_FEATURES={'enable_quotas': False})
|
||||
@test.create_stubs({api.base: ('is_service_enabled',),
|
||||
cinder: ('is_volume_service_enabled',)})
|
||||
def test_get_all_disabled_quotas(self):
|
||||
cinder.is_volume_service_enabled(IsA(http.HttpRequest)).AndReturn(
|
||||
False)
|
||||
api.base.is_service_enabled(IsA(http.HttpRequest),
|
||||
'network').AndReturn(False)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
result_quotas = quotas.get_disabled_quotas(self.request)
|
||||
expected_quotas = list(quotas.CINDER_QUOTA_FIELDS) + \
|
||||
list(quotas.NEUTRON_QUOTA_FIELDS) + list(quotas.NOVA_QUOTA_FIELDS)
|
||||
self.assertItemsEqual(result_quotas, expected_quotas)
|
||||
|
||||
@test.create_stubs({api.nova: ('server_list',
|
||||
'flavor_list',
|
||||
|
@ -129,7 +129,8 @@ class QuotaUsage(dict):
|
||||
|
||||
def update_available(self, name):
|
||||
"""Updates the "available" metric for the given quota."""
|
||||
available = self.usages[name]['quota'] - self.usages[name]['used']
|
||||
quota = self.usages.get(name, {}).get('quota', float('inf'))
|
||||
available = quota - self.usages[name]['used']
|
||||
if available < 0:
|
||||
available = 0
|
||||
self.usages[name]['available'] = available
|
||||
@ -148,7 +149,7 @@ def _get_quota_data(request, method_name, disabled_quotas=None,
|
||||
try:
|
||||
quotasets.append(getattr(cinder, method_name)(request, tenant_id))
|
||||
except cinder.cinder_exception.ClientException:
|
||||
disabled_quotas.extend(CINDER_QUOTA_FIELDS)
|
||||
disabled_quotas.update(CINDER_QUOTA_FIELDS)
|
||||
msg = _("Unable to retrieve volume limit information.")
|
||||
exceptions.handle(request, msg)
|
||||
for quota in itertools.chain(*quotasets):
|
||||
@ -228,29 +229,33 @@ def get_tenant_quota_data(request, disabled_quotas=None, tenant_id=None):
|
||||
|
||||
|
||||
def get_disabled_quotas(request):
|
||||
disabled_quotas = []
|
||||
disabled_quotas = set([])
|
||||
|
||||
# Nova
|
||||
if not nova.can_set_quotas():
|
||||
disabled_quotas.update(NOVA_QUOTA_FIELDS)
|
||||
|
||||
# Cinder
|
||||
if not cinder.is_volume_service_enabled(request):
|
||||
disabled_quotas.extend(CINDER_QUOTA_FIELDS)
|
||||
disabled_quotas.update(CINDER_QUOTA_FIELDS)
|
||||
|
||||
# Neutron
|
||||
if not base.is_service_enabled(request, 'network'):
|
||||
disabled_quotas.extend(NEUTRON_QUOTA_FIELDS)
|
||||
disabled_quotas.update(NEUTRON_QUOTA_FIELDS)
|
||||
else:
|
||||
# Remove the nova network quotas
|
||||
disabled_quotas.extend(['floating_ips', 'fixed_ips'])
|
||||
disabled_quotas.update(['floating_ips', 'fixed_ips'])
|
||||
|
||||
if neutron.is_extension_supported(request, 'security-group'):
|
||||
# If Neutron security group is supported, disable Nova quotas
|
||||
disabled_quotas.extend(['security_groups', 'security_group_rules'])
|
||||
disabled_quotas.update(['security_groups', 'security_group_rules'])
|
||||
else:
|
||||
# If Nova security group is used, disable Neutron quotas
|
||||
disabled_quotas.extend(['security_group', 'security_group_rule'])
|
||||
disabled_quotas.update(['security_group', 'security_group_rule'])
|
||||
|
||||
try:
|
||||
if not neutron.is_quotas_extension_supported(request):
|
||||
disabled_quotas.extend(NEUTRON_QUOTA_FIELDS)
|
||||
disabled_quotas.update(NEUTRON_QUOTA_FIELDS)
|
||||
except Exception:
|
||||
LOG.exception("There was an error checking if the Neutron "
|
||||
"quotas extension is enabled.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user