Skip to content

Commit 5054a16

Browse files
authored
Merge pull request #12 from stackhpc/upstream/yoga-2022-11-14
Synchronise yoga with upstream
2 parents 8f73356 + 4465987 commit 5054a16

File tree

4 files changed

+63
-5
lines changed

4 files changed

+63
-5
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/plugins/ml2/plugin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,9 @@ def _port_provisioned(self, rtype, event, trigger, payload=None):
355355
# a host ID and the dhcp agent notifies that its wiring is done
356356
LOG.debug('Port %s cannot update to ACTIVE because it '
357357
'is not bound.', port_id)
358-
if count == MAX_PROVISIONING_TRIES:
358+
owner = port.device_owner
359+
if (count == MAX_PROVISIONING_TRIES or not
360+
owner.startswith(const.DEVICE_OWNER_COMPUTE_PREFIX)):
359361
return
360362

361363
# Wait 0.5 seconds before checking again if the port is bound.

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):

neutron/tests/unit/plugins/ml2/test_plugin.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,9 @@ def test__port_provisioned_port_retry_port_binding_unbound(
11261126
ml2_plugin.MAX_PROVISIONING_TRIES = 2
11271127
plugin = directory.get_plugin()
11281128
port_id = 'fake_port_id'
1129-
port = mock.Mock(id=port_id, admin_state_up=True)
1129+
device_owner = constants.DEVICE_OWNER_COMPUTE_PREFIX + 'nova'
1130+
port = mock.Mock(id=port_id, admin_state_up=True,
1131+
device_owner=device_owner)
11301132
mock_get_port.return_value = port
11311133
with mock.patch.object(plugin, 'update_port_status') as mock_pstatus:
11321134
pb1 = mock.MagicMock(vif_type=portbindings.VIF_TYPE_UNBOUND)
@@ -1139,6 +1141,23 @@ def test__port_provisioned_port_retry_port_binding_unbound(
11391141
mock_pstatus.assert_called_once_with(self.context, port_id,
11401142
constants.PORT_STATUS_ACTIVE)
11411143

1144+
@mock.patch('neutron.plugins.ml2.plugin.db.get_port')
1145+
@mock.patch.object(p_utils, 'get_port_binding_by_status_and_host')
1146+
def test__port_provisioned_port_retry_port_binding_unbound_no_vm_port(
1147+
self, mock_get_pb, mock_get_port):
1148+
plugin = directory.get_plugin()
1149+
port_id = 'fake_port_id'
1150+
port = mock.Mock(id=port_id, admin_state_up=True,
1151+
device_owner='other_value')
1152+
mock_get_port.return_value = port
1153+
with mock.patch.object(plugin, 'update_port_status') as mock_pstatus:
1154+
pb1 = mock.MagicMock(vif_type=portbindings.VIF_TYPE_UNBOUND)
1155+
mock_get_pb.return_value = pb1
1156+
plugin._port_provisioned('port', 'evt', 'trigger',
1157+
payload=events.DBEventPayload(
1158+
self.context, resource_id=port_id))
1159+
mock_pstatus.assert_not_called()
1160+
11421161
def test_port_after_create_outside_transaction(self):
11431162
self.tx_open = True
11441163

0 commit comments

Comments
 (0)