From 9dd06e9c4424c7201cb65420f73309c545349055 Mon Sep 17 00:00:00 2001 From: yangjianfeng Date: Sat, 14 May 2022 17:06:21 +0800 Subject: [PATCH] Forbid create ndp proxy on same router with same ip address Create multiple ndp proxies with same ip address within one router is invalid. The related database constraint was missed in previous patchsets. The patch add some codes fixed this error. Additionally, Fixed two typo errors. Related-Bug: #1877301 Change-Id: Iab24ad78a3d4d9b0ee584cf0986328c9ae2bd16a --- .../alembic_migrations/versions/EXPAND_HEAD | 2 +- .../21ff98fabab1_add_ndp_proxy_constraint.py | 37 +++++++++++++++++++ neutron/db/models/ndp_proxy.py | 6 +++ neutron/services/ndp_proxy/exceptions.py | 4 +- .../unit/extensions/test_l3_ndp_proxy.py | 11 +++++- ...cate-ndp-proxy-entry-28040bc2afb3c1c7.yaml | 6 +++ 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 neutron/db/migration/alembic_migrations/versions/zed/expand/21ff98fabab1_add_ndp_proxy_constraint.py create mode 100644 releasenotes/notes/forbid-duplicate-ndp-proxy-entry-28040bc2afb3c1c7.yaml diff --git a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD index ae416390415..3bd1cc3f361 100644 --- a/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD +++ b/neutron/db/migration/alembic_migrations/versions/EXPAND_HEAD @@ -1 +1 @@ -659cbedf30a1 +21ff98fabab1 diff --git a/neutron/db/migration/alembic_migrations/versions/zed/expand/21ff98fabab1_add_ndp_proxy_constraint.py b/neutron/db/migration/alembic_migrations/versions/zed/expand/21ff98fabab1_add_ndp_proxy_constraint.py new file mode 100644 index 00000000000..b4e5be72bc4 --- /dev/null +++ b/neutron/db/migration/alembic_migrations/versions/zed/expand/21ff98fabab1_add_ndp_proxy_constraint.py @@ -0,0 +1,37 @@ +# Copyright 2022 OpenStack Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from alembic import op + + +"""add ndp proxy constraint + +Revision ID: 21ff98fabab1 +Revises: 659cbedf30a1 +Create Date: 2022-05-22 14:16:24.550155 + +""" + +# revision identifiers, used by Alembic. +revision = '21ff98fabab1' +down_revision = '659cbedf30a1' + + +def upgrade(): + op.create_unique_constraint( + 'uniq_ndp_proxy0router_id0ip_address', + 'ndp_proxies', + ['router_id', 'ip_address'] + ) diff --git a/neutron/db/models/ndp_proxy.py b/neutron/db/models/ndp_proxy.py index 2cdf025f71a..7653018a90c 100644 --- a/neutron/db/models/ndp_proxy.py +++ b/neutron/db/models/ndp_proxy.py @@ -28,6 +28,12 @@ class NDPProxy(standard_attr.HasStandardAttributes, model_base.HasProject): __tablename__ = 'ndp_proxies' + __table_args__ = ( + sa.UniqueConstraint( + 'router_id', 'ip_address', + name='uniq_ndp_proxy0router_id0ip_address'), + model_base.BASEV2.__table_args__ + ) name = sa.Column(sa.String(db_const.NAME_FIELD_SIZE)) router_id = sa.Column(sa.String(db_const.UUID_FIELD_SIZE), diff --git a/neutron/services/ndp_proxy/exceptions.py b/neutron/services/ndp_proxy/exceptions.py index 15e5b7e8708..f967783b290 100644 --- a/neutron/services/ndp_proxy/exceptions.py +++ b/neutron/services/ndp_proxy/exceptions.py @@ -37,7 +37,7 @@ class AddressScopeConflict(n_exc.Conflict): class RouterGatewayNotValid(n_exc.Conflict): - message = _("Can not enable ndp proxy no " + message = _("Can not enable ndp proxy on " "router %(router_id)s, %(reason)s.") @@ -62,4 +62,4 @@ class RouterIPv6GatewayInUse(n_exc.Conflict): class NDPProxyNotFound(n_exc.NotFound): - message = _("NDP proxy %(id)s could not be found.") + message = _("Ndp proxy %(id)s could not be found.") diff --git a/neutron/tests/unit/extensions/test_l3_ndp_proxy.py b/neutron/tests/unit/extensions/test_l3_ndp_proxy.py index 6f83c602d33..7f8dd960c95 100644 --- a/neutron/tests/unit/extensions/test_l3_ndp_proxy.py +++ b/neutron/tests/unit/extensions/test_l3_ndp_proxy.py @@ -247,7 +247,7 @@ class L3NDPProxyTestCase(test_address_scope.AddressScopeTestCase, def test_enable_ndp_proxy_without_external_gateway(self): with self.router() as router: router_id = router['router']['id'] - err_msg = ("Can not enable ndp proxy no router %s, The router has " + err_msg = ("Can not enable ndp proxy on router %s, The router has " "no external gateway or the external gateway port has " "no IPv6 address.") % router_id self._update_router(router_id, {'enable_ndp_proxy': True}, @@ -260,7 +260,7 @@ class L3NDPProxyTestCase(test_address_scope.AddressScopeTestCase, self._update_router( router_id, {'external_gateway_info': {'network_id': self.ext_net_id}}) - err_msg = ("Can not enable ndp proxy no router %s, The router's " + err_msg = ("Can not enable ndp proxy on router %s, The router's " "external gateway will be unset.") % router_id self._update_router( router_id, @@ -516,3 +516,10 @@ class L3NDPProxyTestCase(test_address_scope.AddressScopeTestCase, self.assertTrue(router_dict['router']['enable_ndp_proxy']) self._create_ndp_proxy( router_id, port_id) + + def test_create_ndp_proxy_with_duplicated(self): + with self.port(self.private_subnet) as port1: + self._create_ndp_proxy(self.router1_id, port1['port']['id']) + self._create_ndp_proxy( + self.router1_id, port1['port']['id'], + expected_code=exc.HTTPConflict.code) diff --git a/releasenotes/notes/forbid-duplicate-ndp-proxy-entry-28040bc2afb3c1c7.yaml b/releasenotes/notes/forbid-duplicate-ndp-proxy-entry-28040bc2afb3c1c7.yaml new file mode 100644 index 00000000000..a3ff5dde941 --- /dev/null +++ b/releasenotes/notes/forbid-duplicate-ndp-proxy-entry-28040bc2afb3c1c7.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Forbid the creation of a duplicate NDP proxy entry on the same router, + since the IP address of a router is unique and an IPv6 address only needs + one NDP proxy.