summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolfo Alonso Hernandez <ralonsoh@redhat.com>2022-11-14 17:43:27 +0000
committerRodolfo Alonso Hernandez <ralonsoh@redhat.com>2022-11-13 11:45:23 +0100
commit49980e3d120ca1f0cdd761477a96b27415b3aefe (patch)
treeeec331f69082f28648b13d1083fb78252a15a9ab
parent953aba1d5c4288bf6347e652294abf84a4bbbc29 (diff)
downloadneutron-49980e3d120ca1f0cdd761477a96b27415b3aefe.tar.gz
[stable-only] Do not fail making reservation when creating a SG
Do not fail during the creation of a security group when trying to make a quota reservation for the security group rules. This feature was added in [1], in order to prevent the rule quota excess during the security group creation. However, as reported in LP#1992161, this method can be called from the RPC worker. If this RPC worker is spawned alone (not with the API workers), the extensions are not loaded and the security group rule quota resources are not created. That means the quota engine does not have the security group rules as managed resources (in this worker). When a new network (and the first subnet) is created, the DHCP agent (or agents) handling this network will try to create the DHCP port. If, as commented in the LP bug, the default security group is not created, the RPC worker will try to create it. In this case this patch skips the quota check. This patch is for stable releases only. Since Xena, this check is done using a new method called "quota_limit_check" [2]. This method does not fail in the related case. [1]https://review.opendev.org/q/I0a9b91b09d6260ff96fdba2f0a455de53bbc1f00 [2]https://review.opendev.org/q/Id73368576a948f78a043d7cf0be16661a65626a9 Conflicts: neutron/db/securitygroups_db.py Closes-Bug: #1992161 Related-Bug: #1858680 Change-Id: I0f20b17c1b13c3cf56de70588fca4a6956d276df (cherry picked from commit 02bdd0470246dd768227affa2d6a8dd8328d3463) (cherry picked from commit 90865c06afe9780ac3116be9e527da9a75944c96)
-rw-r--r--neutron/db/securitygroups_db.py7
-rw-r--r--neutron/quota/__init__.py9
-rw-r--r--neutron/tests/unit/db/test_securitygroups_db.py12
3 files changed, 22 insertions, 6 deletions
diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py
index fcfd5caccf..559b8e0b0d 100644
--- a/neutron/db/securitygroups_db.py
+++ b/neutron/db/securitygroups_db.py
@@ -121,7 +121,7 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
delta = delta * 2 if default_sg else delta
reservation = quota.QUOTAS.make_reservation(
context, tenant_id, {'security_group_rule': delta},
- self)
+ self, raise_exception=False)
for ethertype in ext_sg.sg_supported_ethertypes:
if default_sg:
@@ -142,8 +142,9 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
sg.rules.append(egress_rule)
sg.obj_reset_changes(['rules'])
- quota.QUOTAS.commit_reservation(context,
- reservation.reservation_id)
+ if reservation:
+ quota.QUOTAS.commit_reservation(context,
+ reservation.reservation_id)
# fetch sg from db to load the sg rules with sg model.
sg = sg_obj.SecurityGroup.get_object(context, id=sg.id)
diff --git a/neutron/quota/__init__.py b/neutron/quota/__init__.py
index a07fd0317c..f736ca697c 100644
--- a/neutron/quota/__init__.py
+++ b/neutron/quota/__init__.py
@@ -205,7 +205,8 @@ class QuotaEngine(object):
return res.count(context, *args, **kwargs)
- def make_reservation(self, context, tenant_id, deltas, plugin):
+ def make_reservation(self, context, tenant_id, deltas, plugin,
+ raise_exception=True):
# Verify that resources are managed by the quota engine
# Ensure no value is less than zero
unders = [key for key, val in deltas.items() if val < 0]
@@ -220,8 +221,10 @@ class QuotaEngine(object):
unknown_resources = requested_resources - managed_resources
if unknown_resources:
- raise exceptions.QuotaResourceUnknown(
- unknown=sorted(unknown_resources))
+ if raise_exception:
+ raise exceptions.QuotaResourceUnknown(
+ unknown=sorted(unknown_resources))
+ return
# FIXME(salv-orlando): There should be no reason for sending all the
# resource in the registry to the quota driver, but as other driver
# APIs request them, this will be sorted out with a different patch.
diff --git a/neutron/tests/unit/db/test_securitygroups_db.py b/neutron/tests/unit/db/test_securitygroups_db.py
index 1bdecdc034..3c5f92b2ee 100644
--- a/neutron/tests/unit/db/test_securitygroups_db.py
+++ b/neutron/tests/unit/db/test_securitygroups_db.py
@@ -90,6 +90,18 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase):
securitygroup.SecurityGroupConflict):
self.mixin.create_security_group(self.ctx, secgroup)
+ def test_create_security_group_no_quota(self):
+ with mock.patch.object(self.mixin, '_registry_notify'):
+ self.mock_quota_make_res.return_value = None
+ self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
+ self.mock_quota_commit_res.assert_not_called()
+
+ self.mock_quota_make_res.return_value = mock.Mock(
+ reservation_id='res_id')
+ self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
+ self.mock_quota_commit_res.assert_called_once_with(self.ctx,
+ 'res_id')
+
def test_delete_security_group_in_use(self):
with mock.patch.object(self.mixin,
'_get_port_security_group_bindings'),\