Merge "Fix port can not be created with the sg of other project" into stable/stein

This commit is contained in:
Zuul 2020-08-28 11:12:04 +00:00 committed by Gerrit Code Review
commit 7228eb5fd4
5 changed files with 123 additions and 5 deletions

View File

@ -350,6 +350,9 @@ APIs at the same time.
this is that Compute security group APIs are instances based and this is that Compute security group APIs are instances based and
not port based as Networking. not port based as Networking.
- When creating or updating a port with a specified security group,
the admin tenant can use the security groups of other tenants.
Basic security group operations Basic security group operations
------------------------------- -------------------------------

View File

@ -851,7 +851,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
valid_groups = set( valid_groups = set(
g.id for g in sg_objs g.id for g in sg_objs
if (not tenant_id or g.tenant_id == tenant_id or if (context.is_admin or not tenant_id or
g.tenant_id == tenant_id or
sg_obj.SecurityGroup.is_shared_with_tenant( sg_obj.SecurityGroup.is_shared_with_tenant(
context, g.id, tenant_id)) context, g.id, tenant_id))
) )

View File

@ -441,8 +441,8 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase):
return subnetpool_res return subnetpool_res
def _create_port(self, fmt, net_id, expected_res_status=None, def _create_port(self, fmt, net_id, expected_res_status=None,
arg_list=None, set_context=False, tenant_id=None, arg_list=None, set_context=False, is_admin=False,
**kwargs): tenant_id=None, **kwargs):
tenant_id = tenant_id or self._tenant_id tenant_id = tenant_id or self._tenant_id
data = {'port': {'network_id': net_id, data = {'port': {'network_id': net_id,
'tenant_id': tenant_id}} 'tenant_id': tenant_id}}
@ -466,7 +466,7 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase):
if set_context and tenant_id: if set_context and tenant_id:
# create a specific auth context for this request # create a specific auth context for this request
port_req.environ['neutron.context'] = context.Context( port_req.environ['neutron.context'] = context.Context(
'', tenant_id) '', tenant_id, is_admin=is_admin)
port_res = port_req.get_response(self.api) port_res = port_req.get_response(self.api)
if expected_res_status: if expected_res_status:

View File

@ -293,6 +293,57 @@ class TestPortSecurity(PortSecurityDBTestCase):
self.assertEqual(port['port']['security_groups'], [security_group_id]) self.assertEqual(port['port']['security_groups'], [security_group_id])
self._delete('ports', port['port']['id']) self._delete('ports', port['port']['id'])
def test_create_port_with_admin_use_other_tenant_security_group(self):
if self._skip_security_group:
self.skipTest("Plugin does not support security groups")
res = self._create_network('json', 'net1', True,
arg_list=('port_security_enabled',),
set_context=True,
tenant_id='admin_tenant',
port_security_enabled=False)
net = self.deserialize('json', res)
self._create_subnet('json', net['network']['id'], '10.0.0.0/24')
security_group = self.deserialize(
'json', self._create_security_group(self.fmt, 'asdf', 'asdf',
tenant_id='other_tenant'))
security_group_id = security_group['security_group']['id']
res = self._create_port('json', net['network']['id'],
arg_list=('security_groups',
'port_security_enabled'),
set_context=True,
is_admin=True,
tenant_id='admin_tenant',
port_security_enabled=True,
security_groups=[security_group_id])
port = self.deserialize('json', res)
self.assertTrue(port['port'][psec.PORTSECURITY])
self.assertEqual(port['port']['security_groups'], [security_group_id])
self._delete('ports', port['port']['id'])
def test_create_port_with_no_admin_use_other_tenant_security_group(self):
if self._skip_security_group:
self.skipTest("Plugin does not support security groups")
res = self._create_network('json', 'net1', True,
arg_list=('port_security_enabled',),
set_context=True,
tenant_id='demo_tenant',
port_security_enabled=False)
net = self.deserialize('json', res)
self._create_subnet('json', net['network']['id'], '10.0.0.0/24',
set_context=True, tenant_id='demo_tenant')
security_group = self.deserialize(
'json', self._create_security_group(self.fmt, 'asdf', 'asdf',
tenant_id='other_tenant'))
security_group_id = security_group['security_group']['id']
res = self._create_port('json', net['network']['id'],
arg_list=('security_groups',
'port_security_enabled'),
set_context=True,
tenant_id='demo_tenant',
port_security_enabled=True,
security_groups=[security_group_id])
self.assertEqual(404, res.status_int)
def test_create_port_without_security_group_and_net_sec_false(self): def test_create_port_without_security_group_and_net_sec_false(self):
res = self._create_network('json', 'net1', True, res = self._create_network('json', 'net1', True,
arg_list=('port_security_enabled',), arg_list=('port_security_enabled',),
@ -326,6 +377,54 @@ class TestPortSecurity(PortSecurityDBTestCase):
self.deserialize('json', req.get_response(self.api)) self.deserialize('json', req.get_response(self.api))
self._delete('ports', port['port']['id']) self._delete('ports', port['port']['id'])
def test_update_port_with_admin_use_other_tenant_security_group(self):
if self._skip_security_group:
self.skipTest("Plugin does not support security groups")
with self.network() as net:
with self.subnet(network=net):
res = self._create_port('json', net['network']['id'],
set_context=True, is_admin=True,
tenant_id='admin_tenant',)
port = self.deserialize('json', res)
self.assertTrue(port['port'][psec.PORTSECURITY])
security_group = self.deserialize('json',
self._create_security_group(self.fmt, 'asdf', 'asdf',
tenant_id='other_tenant'))
security_group_id = security_group['security_group']['id']
update_port = {'port':
{'security_groups': [security_group_id]}}
req = self.new_update_request('ports', update_port,
port['port']['id'])
port = self.deserialize('json', req.get_response(self.api))
security_groups = port['port']['security_groups']
self.assertIn(security_group_id, security_groups)
self._delete('ports', port['port']['id'])
def test_update_port_with_no_admin_use_other_tenant_security_group(self):
if self._skip_security_group:
self.skipTest("Plugin does not support security groups")
with self.network(tenant_id='demo_tenant') as net:
with self.subnet(network=net, tenant_id='demo_tenant'):
res = self._create_port('json', net['network']['id'],
set_context=True,
tenant_id='demo_tenant',)
port = self.deserialize('json', res)
self.assertTrue(port['port'][psec.PORTSECURITY])
security_group = self.deserialize('json',
self._create_security_group(self.fmt, 'asdf', 'asdf',
tenant_id='other_tenant'))
security_group_id = security_group['security_group']['id']
update_port = {'port':
{'security_groups': [security_group_id]}}
req = self.new_update_request('ports', update_port,
port['port']['id'])
req.environ['neutron.context'] = context.Context(
'', 'other_tenant')
res = req.get_response(self.api)
self.assertEqual(404, res.status_int)
def test_update_port_remove_port_security_security_group(self): def test_update_port_remove_port_security_security_group(self):
if self._skip_security_group: if self._skip_security_group:
self.skipTest("Plugin does not support security groups") self.skipTest("Plugin does not support security groups")

View File

@ -789,7 +789,7 @@ class TestSecurityGroups(SecurityGroupDBTestCase):
plugin = directory.get_plugin() plugin = directory.get_plugin()
if not hasattr(plugin, '_get_security_groups_on_port'): if not hasattr(plugin, '_get_security_groups_on_port'):
self.skipTest("plugin doesn't use the mixin with this method") self.skipTest("plugin doesn't use the mixin with this method")
neutron_context = context.get_admin_context() neutron_context = context.Context('user', 'tenant')
res = self._create_security_group(self.fmt, 'webservers', 'webservers', res = self._create_security_group(self.fmt, 'webservers', 'webservers',
tenant_id='bad_tenant') tenant_id='bad_tenant')
sg1 = self.deserialize(self.fmt, res) sg1 = self.deserialize(self.fmt, res)
@ -800,6 +800,21 @@ class TestSecurityGroups(SecurityGroupDBTestCase):
'tenant_id': 'tenant'}} 'tenant_id': 'tenant'}}
) )
def test_get_security_group_on_port_with_admin_from_other_tenant(self):
plugin = directory.get_plugin()
if not hasattr(plugin, '_get_security_groups_on_port'):
self.skipTest("plugin doesn't use the mixin with this method")
neutron_context = context.get_admin_context()
res = self._create_security_group(self.fmt, 'webservers', 'webservers',
tenant_id='other_tenant')
sg1 = self.deserialize(self.fmt, res)
sgs = plugin._get_security_groups_on_port(
neutron_context,
{'port': {'security_groups': [sg1['security_group']['id']],
'tenant_id': 'tenant'}})
sg1_id = sg1['security_group']['id']
self.assertEqual(sg1_id, sgs[0])
def test_delete_security_group(self): def test_delete_security_group(self):
name = 'webservers' name = 'webservers'
description = 'my webservers' description = 'my webservers'