diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index 787ef9abf77..2a131c65325 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -1097,7 +1097,7 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase, the floating IP should be associated to. """ internal_port = self._core_plugin.get_port(context, fip['port_id']) - if not internal_port['tenant_id'] == tenant_id: + if internal_port['tenant_id'] != tenant_id and not context.is_admin: port_id = fip['port_id'] msg = (_('Cannot process floating IP association with ' 'Port %s, since that port is owned by a ' diff --git a/neutron/tests/unit/extensions/test_l3.py b/neutron/tests/unit/extensions/test_l3.py index a7dcb85bad9..ca04309df5e 100644 --- a/neutron/tests/unit/extensions/test_l3.py +++ b/neutron/tests/unit/extensions/test_l3.py @@ -2562,6 +2562,16 @@ class L3NatTestCaseBase(L3NatTestCaseMixin): fip2_r2_res = associate_and_assert(fip2, p2) self.assertEqual(fip2_r2_res, r2['router']['id']) + def test_floatingip_update_different_port_owner_as_admin(self): + with self.subnet() as private_sub: + with self.floatingip_no_assoc(private_sub) as fip: + with self.port(subnet=private_sub, tenant_id='other') as p: + body = self._update('floatingips', fip['floatingip']['id'], + {'floatingip': + {'port_id': p['port']['id']}}) + self.assertEqual(p['port']['id'], + body['floatingip']['port_id']) + def test_floatingip_port_delete(self): with self.subnet() as private_sub: with self.floatingip_no_assoc(private_sub) as fip: