Skip to content

Commit 061a80d

Browse files
committed
[L3][QoS] Remove router QoS binding when GW is removed
Now when the external gateway of a router is removed, the QoS policy assigned to this router is removed too. A router can only have a QoS policy assigned if a gateway port is attached; if the port is removed, the QoS binding must be removed too. Closes-Bug: #1968269 Change-Id: Iced254259170972a9699aa35ae8062776e11285d (cherry picked from commit 8ad6c3b)
1 parent 0f84be3 commit 061a80d

File tree

3 files changed

+22
-16
lines changed

3 files changed

+22
-16
lines changed

neutron/db/l3_gateway_ip_qos.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def _create_gw_ip_qos_db(self, context, router_id, policy_id):
5858

5959
def _delete_gw_ip_qos_db(self, context, router_id, policy_id):
6060
policy = policy_object.QosPolicy.get_policy_obj(context, policy_id)
61-
policy.detach_router(router_id)
61+
policy.detach_router(router_id, if_exists=True)
6262

6363
def _update_router_gw_info(self, context, router_id, info,
6464
request_body, router=None):
@@ -67,10 +67,13 @@ def _update_router_gw_info(self, context, router_id, info,
6767
self)._update_router_gw_info(
6868
context, router_id, info, request_body, router)
6969

70+
if not self._is_gw_ip_qos_supported:
71+
return router
72+
7073
with db_api.CONTEXT_WRITER.using(context):
71-
if self._is_gw_ip_qos_supported and router.gw_port:
72-
self._update_router_gw_qos_policy(context, router_id,
73-
info, router)
74+
if not router.gw_port:
75+
info = {qos_consts.QOS_POLICY_ID: None}
76+
self._update_router_gw_qos_policy(context, router_id, info, router)
7477

7578
return router
7679

@@ -80,7 +83,7 @@ def _get_router_gateway_policy_binding(self, context, router_id):
8083

8184
def _update_router_gw_qos_policy(self, context, router_id, info, router):
8285
if not info or qos_consts.QOS_POLICY_ID not in info:
83-
# An explicit 'None' for `qos_polcy_id` indicates to clear
86+
# An explicit 'None' for `qos_policy_id` indicates to clear
8487
# the router gateway IP policy. So if info does not have
8588
# the key `qos_polcy_id`, we can not decide what behavior
8689
# to be done, then directly return here.

neutron/objects/qos/policy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,10 @@ def detach_floatingip(self, fip_id):
295295
raise qos_exc.FloatingIPQosBindingNotFound(fip_id=fip_id,
296296
policy_id=self.id)
297297

298-
def detach_router(self, router_id):
298+
def detach_router(self, router_id, if_exists=False):
299299
deleted = binding.QosPolicyRouterGatewayIPBinding.delete_objects(
300300
self.obj_context, router_id=router_id)
301-
if not deleted:
301+
if not deleted and not if_exists:
302302
raise qos_exc.RouterQosBindingNotFound(router_id=router_id,
303303
policy_id=self.id)
304304

neutron/tests/unit/extensions/test_qos_gateway_ip.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from neutron.conf.db import extraroute_db
2828
from neutron.db import l3_gateway_ip_qos
2929
from neutron.extensions import l3
30+
from neutron.objects.qos import binding
3031
from neutron.objects.qos import policy
3132
from neutron.tests.unit.extensions import test_l3
3233

@@ -110,8 +111,7 @@ def test_update_router_gateway_with_qos_policy(self):
110111
res['router']['external_gateway_info'].get(
111112
qos_consts.QOS_POLICY_ID))
112113

113-
def test_clear_router_gateway_and_create_with_old_qos_policy_implicitly(
114-
self):
114+
def test_clear_router_gateway_and_create_again(self):
115115
ctx = context.get_admin_context()
116116
policy_obj = policy.QosPolicy(ctx,
117117
id=uuidutils.generate_uuid(),
@@ -129,22 +129,25 @@ def test_clear_router_gateway_and_create_with_old_qos_policy_implicitly(
129129
policy_obj.id,
130130
res['router']['external_gateway_info'].get(
131131
qos_consts.QOS_POLICY_ID))
132+
gw_binding = binding.QosPolicyRouterGatewayIPBinding.get_object(
133+
ctx, router_id=r['router']['id'])
134+
self.assertEqual(r['router']['id'], gw_binding.router_id)
132135

133-
# Clear router gateway
136+
# Clear router gateway, the QoS policy must be removed.
134137
self._remove_external_gateway_from_router(
135138
r['router']['id'],
136139
public_sub['subnet']['network_id'],
137140
external_gw_info={})
141+
gw_binding = binding.QosPolicyRouterGatewayIPBinding.get_object(
142+
ctx, router_id=r['router']['id'])
143+
self.assertIsNone(gw_binding)
138144

139-
# Create router gateway again, then the qos policy binding will be
140-
# reused here.
145+
# Create router gateway again.
141146
res = self._add_external_gateway_to_router(
142147
r['router']['id'],
143148
public_sub['subnet']['network_id'])
144-
self.assertEqual(
145-
policy_obj.id,
146-
res['router']['external_gateway_info'].get(
147-
qos_consts.QOS_POLICY_ID))
149+
self.assertIsNone(res['router']['external_gateway_info'].get(
150+
qos_consts.QOS_POLICY_ID))
148151

149152
def test_clear_router_gateway_qos_policy(self):
150153
ctx = context.get_admin_context()

0 commit comments

Comments
 (0)