Merge "Don't create default SG in transaction"
This commit is contained in:
commit
970e565efc
@ -83,6 +83,11 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
|
|||||||
|
|
||||||
if not default_sg:
|
if not default_sg:
|
||||||
self._ensure_default_security_group(context, tenant_id)
|
self._ensure_default_security_group(context, tenant_id)
|
||||||
|
else:
|
||||||
|
existing_def_sg_id = self._get_default_sg_id(context, tenant_id)
|
||||||
|
if existing_def_sg_id is not None:
|
||||||
|
# default already exists, return it
|
||||||
|
return self.get_security_group(context, existing_def_sg_id)
|
||||||
|
|
||||||
with db_api.autonested_transaction(context.session):
|
with db_api.autonested_transaction(context.session):
|
||||||
security_group_db = sg_models.SecurityGroup(id=s.get('id') or (
|
security_group_db = sg_models.SecurityGroup(id=s.get('id') or (
|
||||||
@ -661,27 +666,30 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase):
|
|||||||
port[ext_sg.SECURITYGROUPS] = (security_group_ids and
|
port[ext_sg.SECURITYGROUPS] = (security_group_ids and
|
||||||
list(security_group_ids) or [])
|
list(security_group_ids) or [])
|
||||||
|
|
||||||
def _ensure_default_security_group(self, context, tenant_id):
|
def _get_default_sg_id(self, context, tenant_id):
|
||||||
"""Create a default security group if one doesn't exist.
|
|
||||||
|
|
||||||
:returns: the default security group id for given tenant.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
query = self._model_query(context, sg_models.DefaultSecurityGroup)
|
query = self._model_query(context, sg_models.DefaultSecurityGroup)
|
||||||
default_group = query.filter_by(tenant_id=tenant_id).one()
|
default_group = query.filter_by(tenant_id=tenant_id).one()
|
||||||
return default_group['security_group_id']
|
return default_group['security_group_id']
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
security_group = {
|
pass
|
||||||
'security_group':
|
|
||||||
{'name': 'default',
|
def _ensure_default_security_group(self, context, tenant_id):
|
||||||
'tenant_id': tenant_id,
|
"""Create a default security group if one doesn't exist.
|
||||||
'description': _('Default security group')}
|
|
||||||
}
|
:returns: the default security group id for given tenant.
|
||||||
# starting a transaction before create to avoid db retries
|
"""
|
||||||
with context.session.begin(subtransactions=True):
|
existing = self._get_default_sg_id(context, tenant_id)
|
||||||
sg_id = self.create_security_group(
|
if existing is not None:
|
||||||
context, security_group, default_sg=True)['id']
|
return existing
|
||||||
return sg_id
|
security_group = {
|
||||||
|
'security_group':
|
||||||
|
{'name': 'default',
|
||||||
|
'tenant_id': tenant_id,
|
||||||
|
'description': _('Default security group')}
|
||||||
|
}
|
||||||
|
return self.create_security_group(context, security_group,
|
||||||
|
default_sg=True)['id']
|
||||||
|
|
||||||
def _get_security_groups_on_port(self, context, port):
|
def _get_security_groups_on_port(self, context, port):
|
||||||
"""Check that all security groups on port belong to tenant.
|
"""Check that all security groups on port belong to tenant.
|
||||||
|
@ -735,7 +735,6 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
tenant_id = net_data['tenant_id']
|
tenant_id = net_data['tenant_id']
|
||||||
session = context.session
|
session = context.session
|
||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
self._ensure_default_security_group(context, tenant_id)
|
|
||||||
net_db = self.create_network_db(context, network)
|
net_db = self.create_network_db(context, network)
|
||||||
result = self._make_network_dict(net_db, process_extensions=False,
|
result = self._make_network_dict(net_db, process_extensions=False,
|
||||||
context=context)
|
context=context)
|
||||||
@ -771,6 +770,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
@utils.transaction_guard
|
@utils.transaction_guard
|
||||||
@db_api.retry_if_session_inactive()
|
@db_api.retry_if_session_inactive()
|
||||||
def create_network(self, context, network):
|
def create_network(self, context, network):
|
||||||
|
self._ensure_default_security_group(context,
|
||||||
|
network['network']['tenant_id'])
|
||||||
result, mech_context = self._create_network_db(context, network)
|
result, mech_context = self._create_network_db(context, network)
|
||||||
kwargs = {'context': context, 'network': result}
|
kwargs = {'context': context, 'network': result}
|
||||||
registry.notify(resources.NETWORK, events.AFTER_CREATE, self, **kwargs)
|
registry.notify(resources.NETWORK, events.AFTER_CREATE, self, **kwargs)
|
||||||
@ -787,6 +788,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
@utils.transaction_guard
|
@utils.transaction_guard
|
||||||
@db_api.retry_if_session_inactive()
|
@db_api.retry_if_session_inactive()
|
||||||
def create_network_bulk(self, context, networks):
|
def create_network_bulk(self, context, networks):
|
||||||
|
tenants = {n['network']['tenant_id'] for n in networks['networks']}
|
||||||
|
map(lambda t: self._ensure_default_security_group(context, t), tenants)
|
||||||
objects = self._create_bulk_ml2(attributes.NETWORK, context, networks)
|
objects = self._create_bulk_ml2(attributes.NETWORK, context, networks)
|
||||||
return [obj['result'] for obj in objects]
|
return [obj['result'] for obj in objects]
|
||||||
|
|
||||||
@ -1240,6 +1243,9 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
if not attrs.get('status'):
|
if not attrs.get('status'):
|
||||||
attrs['status'] = const.PORT_STATUS_DOWN
|
attrs['status'] = const.PORT_STATUS_DOWN
|
||||||
|
|
||||||
|
# NOTE(kevinbenton): triggered outside of transaction since it
|
||||||
|
# emits 'AFTER' events if it creates.
|
||||||
|
self._ensure_default_security_group(context, attrs['tenant_id'])
|
||||||
session = context.session
|
session = context.session
|
||||||
with session.begin(subtransactions=True):
|
with session.begin(subtransactions=True):
|
||||||
dhcp_opts = attrs.get(edo_ext.EXTRADHCPOPTS, [])
|
dhcp_opts = attrs.get(edo_ext.EXTRADHCPOPTS, [])
|
||||||
|
@ -20,6 +20,9 @@ import mock
|
|||||||
from neutron_lib import constants as const
|
from neutron_lib import constants as const
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
|
|
||||||
|
from neutron.callbacks import events
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron.callbacks import resources
|
||||||
from neutron import context
|
from neutron import context
|
||||||
from neutron.extensions import securitygroup as ext_sg
|
from neutron.extensions import securitygroup as ext_sg
|
||||||
from neutron.tests import tools
|
from neutron.tests import tools
|
||||||
@ -148,6 +151,20 @@ class TestMl2SecurityGroups(Ml2SecurityGroupsTestCase,
|
|||||||
# the or_ function should only have one argument
|
# the or_ function should only have one argument
|
||||||
or_mock.assert_called_once_with(mock.ANY)
|
or_mock.assert_called_once_with(mock.ANY)
|
||||||
|
|
||||||
|
def test_security_groups_created_outside_transaction(self):
|
||||||
|
def record_after_state(r, e, t, context, *args, **kwargs):
|
||||||
|
self.was_active = context.session.is_active
|
||||||
|
|
||||||
|
registry.subscribe(record_after_state, resources.SECURITY_GROUP,
|
||||||
|
events.AFTER_CREATE)
|
||||||
|
with self.subnet() as s:
|
||||||
|
self.assertFalse(self.was_active)
|
||||||
|
self._delete(
|
||||||
|
'security-groups',
|
||||||
|
self._list('security-groups')['security_groups'][0]['id'])
|
||||||
|
with self.port(subnet=s):
|
||||||
|
self.assertFalse(self.was_active)
|
||||||
|
|
||||||
|
|
||||||
class TestMl2SGServerRpcCallBack(
|
class TestMl2SGServerRpcCallBack(
|
||||||
Ml2SecurityGroupsTestCase,
|
Ml2SecurityGroupsTestCase,
|
||||||
|
Loading…
Reference in New Issue
Block a user