Ensure default security group before port update
The default security group can be deleted and updating a port will recreate it. However, we should do this in the BEFORE_UPDATE event handler rather than waiting for it to happen inside of the port update transaction which violates the transaction semantics of the security group callbacks. Closes-Bug: #1718282 Change-Id: I1ce8b558b0a831adcebead512d97554173423955
This commit is contained in:
parent
863fb129f9
commit
017185496c
|
@ -740,11 +740,15 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
|
|||
if default_group:
|
||||
return default_group.security_group_id
|
||||
|
||||
@registry.receives(resources.PORT, [events.BEFORE_CREATE])
|
||||
@registry.receives(resources.PORT, [events.BEFORE_CREATE,
|
||||
events.BEFORE_UPDATE])
|
||||
@registry.receives(resources.NETWORK, [events.BEFORE_CREATE])
|
||||
def _ensure_default_security_group_handler(self, resource, event, trigger,
|
||||
context, **kwargs):
|
||||
tenant_id = kwargs[resource]['tenant_id']
|
||||
if event == events.BEFORE_UPDATE:
|
||||
tenant_id = kwargs['original_' + resource]['tenant_id']
|
||||
else:
|
||||
tenant_id = kwargs[resource]['tenant_id']
|
||||
self._ensure_default_security_group(context, tenant_id)
|
||||
|
||||
def _ensure_default_security_group(self, context, tenant_id):
|
||||
|
|
|
@ -464,6 +464,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
# It would be addressed during EventPayload conversion.
|
||||
registry.notify(resources.PORT, events.BEFORE_UPDATE, self,
|
||||
context=plugin_context, port=orig_context.current,
|
||||
original_port=orig_context.current,
|
||||
orig_binding=orig_binding, new_binding=new_binding)
|
||||
|
||||
# After we've attempted to bind the port, we begin a
|
||||
|
@ -1284,8 +1285,10 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
attrs = port[port_def.RESOURCE_NAME]
|
||||
need_port_update_notify = False
|
||||
bound_mech_contexts = []
|
||||
original_port = self.get_port(context, id)
|
||||
registry.notify(resources.PORT, events.BEFORE_UPDATE, self,
|
||||
context=context, port=attrs)
|
||||
context=context, port=attrs,
|
||||
original_port=original_port)
|
||||
with db_api.context_manager.writer.using(context):
|
||||
port_db = self._get_port(context, id)
|
||||
binding = port_db.port_binding
|
||||
|
@ -1726,6 +1729,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
'status': status
|
||||
}
|
||||
registry.notify(resources.PORT, events.BEFORE_UPDATE, self,
|
||||
original_port=port,
|
||||
context=context, port=attr)
|
||||
with db_api.context_manager.writer.using(context):
|
||||
context.session.add(port) # bring port into writer session
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from tempest.lib import decorators
|
||||
|
||||
from neutron.tests.tempest.api import base_security_groups as base
|
||||
|
||||
|
||||
class SecGroupAdminTest(base.BaseSecGroupTest):
|
||||
required_extensions = ['security-group']
|
||||
credentials = ['primary', 'admin']
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(SecGroupAdminTest, cls).setup_clients()
|
||||
cls.admin_client = cls.os_admin.network_client
|
||||
cls.identity_admin_client = cls.os_admin.projects_client
|
||||
|
||||
@decorators.idempotent_id('44f1e1c4-af10-4aa0-972f-87c1c8fa25cc')
|
||||
def test_security_group_recreated_on_port_update(self):
|
||||
network = self.create_network()
|
||||
self.create_subnet(network)
|
||||
port = self.create_port(network, security_groups=[])
|
||||
for sg in self.client.list_security_groups()['security_groups']:
|
||||
if sg['name'] == 'default':
|
||||
self.admin_client.delete_security_group(sg['id'])
|
||||
self.update_port(port, name='update')
|
||||
names = [
|
||||
sg['name']
|
||||
for sg in self.client.list_security_groups()['security_groups']
|
||||
]
|
||||
self.assertIn('default', names)
|
|
@ -1094,7 +1094,8 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
|
|||
# one to change the host_id, the second to commit a binding
|
||||
self.assertEqual(2, len(b_update_events))
|
||||
self.assertEqual({'context': ctx,
|
||||
'port': {'binding:host_id': 'newhost'}},
|
||||
'port': {'binding:host_id': 'newhost'},
|
||||
'original_port': mock.ANY},
|
||||
b_update_events[0])
|
||||
self.assertIn('orig_binding', b_update_events[1])
|
||||
self.assertIn('new_binding', b_update_events[1])
|
||||
|
|
Loading…
Reference in New Issue