summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Morin <arnaud.morin@ovhcloud.com>2022-05-30 15:40:45 +0200
committerRodolfo Alonso Hernandez <ralonsoh@redhat.com>2022-11-08 08:51:37 +0000
commit4b52a8efb1dc2dd6cc336ea2ff1c62aab3d0e3e1 (patch)
tree3bce83d2bdc79a5f7b7b62044f69f8bcf9cfd32e
parentcdf0400bbe8264e82bb765a904a6541cd9056d3b (diff)
downloadneutron-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.py22
-rw-r--r--neutron/tests/unit/extensions/test_l3.py21
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):