diff options
author | Arnaud Morin <arnaud.morin@ovhcloud.com> | 2022-05-30 15:40:45 +0200 |
---|---|---|
committer | Rodolfo Alonso Hernandez <ralonsoh@redhat.com> | 2022-11-08 08:51:37 +0000 |
commit | 4b52a8efb1dc2dd6cc336ea2ff1c62aab3d0e3e1 (patch) | |
tree | 3bce83d2bdc79a5f7b7b62044f69f8bcf9cfd32e | |
parent | cdf0400bbe8264e82bb765a904a6541cd9056d3b (diff) | |
download | neutron-4b52a8efb1dc2dd6cc336ea2ff1c62aab3d0e3e1.tar.gz |
Allow shared net to be added on router
This will subnets from shared networks to be added on routers using:
$ openstack router add subnet router_id subnet_id
Without this, neutron user must use a multi-router solution, which is
not convenient at all.
Conflicts:
neutron/db/l3_db.py
Closes-Bug: #1975603
Related-Bug: #1757482
Signed-off-by: Arnaud Morin <arnaud.morin@ovhcloud.com>
Change-Id: I50f07d41428e57e6bed9be16980a6c605b7d130e
(cherry picked from commit 8619c104b886517266f5b7ae7d19816aa5764dc0)
(cherry picked from commit 05569382481fadb05cc69449b19364647a8c4cdb)
-rw-r--r-- | neutron/db/l3_db.py | 22 | ||||
-rw-r--r-- | neutron/tests/unit/extensions/test_l3.py | 21 |
2 files changed, 40 insertions, 3 deletions
diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index 565b422532..fbb74a0101 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -52,6 +52,7 @@ from neutron.db import standardattrdescription_db as st_attr from neutron.extensions import l3 from neutron.extensions import qos_fip from neutron.objects import base as base_obj +from neutron.objects import network as network_obj from neutron.objects import port_forwarding from neutron.objects import ports as port_obj from neutron.objects import router as l3_obj @@ -767,9 +768,24 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase, msg = _('Subnet for router interface must have a gateway IP') raise n_exc.BadRequest(resource='router', msg=msg) if subnet['project_id'] != context.project_id and not context.is_admin: - msg = (_('Cannot add interface to router because subnet %s is not ' - 'owned by project making the request') % subnet_id) - raise n_exc.BadRequest(resource='router', msg=msg) + # NOTE(amorin): check if network is RBAC or globaly shared + # globaly shared --> disallow adding interface (see LP-1757482) + # RBAC shared --> allow adding interface (see LP-1975603) + elevated = context.elevated() + + with db_api.CONTEXT_READER.using(elevated): + rbac_allowed_projects = network_obj.NetworkRBAC.get_projects( + elevated, object_id=subnet['network_id'], + action='access_as_shared', + target_tenant=context.project_id) + + # Fail if the current project_id is NOT in the allowed + # projects + if context.project_id not in rbac_allowed_projects: + msg = (_('Cannot add interface to router because subnet ' + '%s is not owned by project making the request') + % subnet_id) + raise n_exc.BadRequest(resource='router', msg=msg) self._validate_subnet_address_mode(subnet) self._check_for_dup_router_subnets(context, router, subnet['network_id'], [subnet]) diff --git a/neutron/tests/unit/extensions/test_l3.py b/neutron/tests/unit/extensions/test_l3.py index 46423c84c4..5ea4022b9d 100644 --- a/neutron/tests/unit/extensions/test_l3.py +++ b/neutron/tests/unit/extensions/test_l3.py @@ -57,6 +57,7 @@ from neutron.db import l3_hamode_db from neutron.db.models import l3 as l3_models from neutron.db import models_v2 from neutron.extensions import l3 +from neutron.objects import network as network_obj from neutron.services.revisions import revision_plugin from neutron.tests import base from neutron.tests.unit.api import test_extensions @@ -1327,6 +1328,26 @@ class L3NatTestCaseBase(L3NatTestCaseMixin): expected_code=err_code, tenant_id=router_tenant_id) + def test_router_add_interface_by_subnet_other_tenant_subnet_rbac_shared( + self, + ): + router_tenant_id = _uuid() + with mock.patch.object(network_obj.NetworkRBAC, "get_projects") as g: + with self.router( + tenant_id=router_tenant_id, set_context=True + ) as r: + with self.network(shared=True) as n: + with self.subnet(network=n) as s: + g.return_value = [router_tenant_id] + self._router_interface_action( + "add", + r["router"]["id"], + s["subnet"]["id"], + None, + expected_code=exc.HTTPOk.code, + tenant_id=router_tenant_id, + ) + def _test_router_add_interface_by_port_allocation_pool( self, out_of_pool=False, router_action_as_admin=False, expected_code=exc.HTTPOk.code): |