Fix port can not be created with the sg of other project
This patch adds the verification of whether admin context when verifying the valid security groups of port. Change-Id: I2674bdc448d9a091b9fe8c68f0866fd19141c6be Closes-Bug: #1890539
This commit is contained in:
parent
24590a334f
commit
cc54a1c38e
@ -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
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -895,7 +895,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))
|
||||||
)
|
)
|
||||||
|
@ -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:
|
||||||
|
@ -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")
|
||||||
|
@ -787,7 +787,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)
|
||||||
@ -798,6 +798,22 @@ 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].id)
|
||||||
|
self.assertEqual('other_tenant', sgs[0].project_id)
|
||||||
|
|
||||||
def test_delete_security_group(self):
|
def test_delete_security_group(self):
|
||||||
name = 'webservers'
|
name = 'webservers'
|
||||||
description = 'my webservers'
|
description = 'my webservers'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user