Skip to content

Commit 1d34760

Browse files
arnaudmorinralonsoh
authored andcommitted
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. Closes-Bug: #1975603 Related-Bug: #1757482 Signed-off-by: Arnaud Morin <[email protected]> Change-Id: I50f07d41428e57e6bed9be16980a6c605b7d130e (cherry picked from commit 8619c10)
1 parent 5684138 commit 1d34760

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

neutron/db/l3_db.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
from neutron.extensions import l3
5555
from neutron.extensions import segment as segment_ext
5656
from neutron.objects import base as base_obj
57+
from neutron.objects import network as network_obj
5758
from neutron.objects import port_forwarding
5859
from neutron.objects import ports as port_obj
5960
from neutron.objects import router as l3_obj
@@ -856,9 +857,24 @@ def _add_interface_by_subnet(self, context, router, subnet_id, owner):
856857
msg = _('Subnet for router interface must have a gateway IP')
857858
raise n_exc.BadRequest(resource='router', msg=msg)
858859
if subnet['project_id'] != context.project_id and not context.is_admin:
859-
msg = (_('Cannot add interface to router because subnet %s is not '
860-
'owned by project making the request') % subnet_id)
861-
raise n_exc.BadRequest(resource='router', msg=msg)
860+
# NOTE(amorin): check if network is RBAC or globaly shared
861+
# globaly shared --> disallow adding interface (see LP-1757482)
862+
# RBAC shared --> allow adding interface (see LP-1975603)
863+
elevated = context.elevated()
864+
865+
with db_api.CONTEXT_READER.using(elevated):
866+
rbac_allowed_projects = network_obj.NetworkRBAC.get_projects(
867+
elevated, object_id=subnet['network_id'],
868+
action='access_as_shared',
869+
target_project=context.project_id)
870+
871+
# Fail if the current project_id is NOT in the allowed
872+
# projects
873+
if context.project_id not in rbac_allowed_projects:
874+
msg = (_('Cannot add interface to router because subnet '
875+
'%s is not owned by project making the request')
876+
% subnet_id)
877+
raise n_exc.BadRequest(resource='router', msg=msg)
862878
self._validate_subnet_address_mode(subnet)
863879
self._check_for_dup_router_subnets(context, router,
864880
subnet['network_id'], [subnet])

neutron/tests/unit/extensions/test_l3.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
from neutron.db.models import l3 as l3_models
5858
from neutron.db import models_v2
5959
from neutron.extensions import l3
60+
from neutron.objects import network as network_obj
6061
from neutron.services.revisions import revision_plugin
6162
from neutron.tests import base
6263
from neutron.tests.unit.api import test_extensions
@@ -1320,6 +1321,26 @@ def test_router_add_interface_by_subnet_other_tenant_subnet_returns_400(
13201321
expected_code=err_code,
13211322
tenant_id=router_tenant_id)
13221323

1324+
def test_router_add_interface_by_subnet_other_tenant_subnet_rbac_shared(
1325+
self,
1326+
):
1327+
router_tenant_id = _uuid()
1328+
with mock.patch.object(network_obj.NetworkRBAC, "get_projects") as g:
1329+
with self.router(
1330+
tenant_id=router_tenant_id, set_context=True
1331+
) as r:
1332+
with self.network(shared=True) as n:
1333+
with self.subnet(network=n) as s:
1334+
g.return_value = [router_tenant_id]
1335+
self._router_interface_action(
1336+
"add",
1337+
r["router"]["id"],
1338+
s["subnet"]["id"],
1339+
None,
1340+
expected_code=exc.HTTPOk.code,
1341+
tenant_id=router_tenant_id,
1342+
)
1343+
13231344
def _test_router_add_interface_by_port_allocation_pool(
13241345
self, out_of_pool=False, router_action_as_admin=False,
13251346
expected_code=exc.HTTPOk.code):

0 commit comments

Comments
 (0)