use callback payloads for SECURITY_GROUP_RULE
This patch switches over to callback payloads for SECURITY_GROUP_RULE events. Change-Id: Id80dc6790226cc81cb6535dc1bcaba58e991fdcb
This commit is contained in:
parent
1e2088abbe
commit
941be42a61
|
@ -394,17 +394,24 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
|
||||||
context, rule_dict, validate=False)
|
context, rule_dict, validate=False)
|
||||||
ret.append(res_rule_dict)
|
ret.append(res_rule_dict)
|
||||||
for rdict in ret:
|
for rdict in ret:
|
||||||
registry.notify(
|
registry.publish(resources.SECURITY_GROUP_RULE,
|
||||||
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, self,
|
events.AFTER_CREATE,
|
||||||
context=context, security_group_rule=rdict)
|
self,
|
||||||
|
payload=events.DBEventPayload(
|
||||||
|
context,
|
||||||
|
resource_id=rdict['id'],
|
||||||
|
states=(rdict,)))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@db_api.retry_if_session_inactive()
|
@db_api.retry_if_session_inactive()
|
||||||
def create_security_group_rule(self, context, security_group_rule):
|
def create_security_group_rule(self, context, security_group_rule):
|
||||||
res = self._create_security_group_rule(context, security_group_rule)
|
res = self._create_security_group_rule(context, security_group_rule)
|
||||||
registry.notify(
|
registry.publish(resources.SECURITY_GROUP_RULE, events.AFTER_CREATE,
|
||||||
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, self,
|
self, payload=events.DBEventPayload(
|
||||||
context=context, security_group_rule=res)
|
context,
|
||||||
|
resource_id=res['id'],
|
||||||
|
states=(res,)))
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _create_security_group_rule(self, context, security_group_rule,
|
def _create_security_group_rule(self, context, security_group_rule,
|
||||||
|
@ -444,13 +451,14 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
|
||||||
if port_range_max is not None:
|
if port_range_max is not None:
|
||||||
args['port_range_max'] = port_range_max
|
args['port_range_max'] = port_range_max
|
||||||
|
|
||||||
kwargs = {
|
self._registry_notify(
|
||||||
'context': context,
|
resources.SECURITY_GROUP_RULE,
|
||||||
'security_group_rule': args
|
events.BEFORE_CREATE,
|
||||||
}
|
exc_cls=ext_sg.SecurityGroupConflict,
|
||||||
self._registry_notify(resources.SECURITY_GROUP_RULE,
|
payload=events.DBEventPayload(
|
||||||
events.BEFORE_CREATE,
|
context, resource_id=args['id'],
|
||||||
exc_cls=ext_sg.SecurityGroupConflict, **kwargs)
|
states=(args,)))
|
||||||
|
|
||||||
with db_api.CONTEXT_WRITER.using(context):
|
with db_api.CONTEXT_WRITER.using(context):
|
||||||
if validate:
|
if validate:
|
||||||
self._check_for_duplicate_rules(context, sg_id,
|
self._check_for_duplicate_rules(context, sg_id,
|
||||||
|
@ -463,11 +471,14 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
|
||||||
sg_rule = sg_obj.SecurityGroupRule.get_object(context,
|
sg_rule = sg_obj.SecurityGroupRule.get_object(context,
|
||||||
id=sg_rule.id)
|
id=sg_rule.id)
|
||||||
res_rule_dict = self._make_security_group_rule_dict(sg_rule.db_obj)
|
res_rule_dict = self._make_security_group_rule_dict(sg_rule.db_obj)
|
||||||
kwargs['security_group_rule'] = res_rule_dict
|
|
||||||
self._registry_notify(
|
self._registry_notify(
|
||||||
resources.SECURITY_GROUP_RULE,
|
resources.SECURITY_GROUP_RULE,
|
||||||
events.PRECOMMIT_CREATE,
|
events.PRECOMMIT_CREATE,
|
||||||
exc_cls=ext_sg.SecurityGroupConflict, **kwargs)
|
exc_cls=ext_sg.SecurityGroupConflict,
|
||||||
|
payload=events.DBEventPayload(
|
||||||
|
context, resource_id=res_rule_dict['id'],
|
||||||
|
states=(res_rule_dict,)))
|
||||||
|
|
||||||
return res_rule_dict
|
return res_rule_dict
|
||||||
|
|
||||||
def _get_ip_proto_number(self, protocol):
|
def _get_ip_proto_number(self, protocol):
|
||||||
|
@ -833,26 +844,32 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase,
|
||||||
|
|
||||||
@db_api.retry_if_session_inactive()
|
@db_api.retry_if_session_inactive()
|
||||||
def delete_security_group_rule(self, context, id):
|
def delete_security_group_rule(self, context, id):
|
||||||
kwargs = {
|
|
||||||
'context': context,
|
|
||||||
'security_group_rule_id': id
|
|
||||||
}
|
|
||||||
self._registry_notify(resources.SECURITY_GROUP_RULE,
|
self._registry_notify(resources.SECURITY_GROUP_RULE,
|
||||||
events.BEFORE_DELETE, id=id,
|
events.BEFORE_DELETE,
|
||||||
exc_cls=ext_sg.SecurityGroupRuleInUse, **kwargs)
|
exc_cls=ext_sg.SecurityGroupRuleInUse,
|
||||||
|
payload=events.DBEventPayload(
|
||||||
|
context, resource_id=id,))
|
||||||
|
|
||||||
with db_api.CONTEXT_WRITER.using(context):
|
with db_api.CONTEXT_WRITER.using(context):
|
||||||
sgr = self._get_security_group_rule(context, id)
|
sgr = self._get_security_group_rule(context, id)
|
||||||
kwargs['security_group_id'] = sgr['security_group_id']
|
self._registry_notify(
|
||||||
self._registry_notify(resources.SECURITY_GROUP_RULE,
|
resources.SECURITY_GROUP_RULE,
|
||||||
events.PRECOMMIT_DELETE,
|
events.PRECOMMIT_DELETE,
|
||||||
exc_cls=ext_sg.SecurityGroupRuleInUse, id=id,
|
exc_cls=ext_sg.SecurityGroupRuleInUse,
|
||||||
**kwargs)
|
payload=events.DBEventPayload(
|
||||||
|
context,
|
||||||
|
resource_id=id,
|
||||||
|
metadata={'security_group_id': sgr['security_group_id']}))
|
||||||
sgr.delete()
|
sgr.delete()
|
||||||
|
|
||||||
registry.notify(
|
registry.publish(
|
||||||
resources.SECURITY_GROUP_RULE, events.AFTER_DELETE, self,
|
resources.SECURITY_GROUP_RULE,
|
||||||
**kwargs)
|
events.AFTER_DELETE,
|
||||||
|
self,
|
||||||
|
payload=events.DBEventPayload(
|
||||||
|
context,
|
||||||
|
resource_id=id,
|
||||||
|
metadata={'security_group_id': sgr['security_group_id']}))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@resource_extend.extends([port_def.COLLECTION_NAME])
|
@resource_extend.extends([port_def.COLLECTION_NAME])
|
||||||
|
|
|
@ -379,26 +379,30 @@ class OVNMechanismDriver(api.MechanismDriver):
|
||||||
ovn_revision_numbers_db.bump_revision(
|
ovn_revision_numbers_db.bump_revision(
|
||||||
kwargs['context'], security_group, ovn_const.TYPE_SECURITY_GROUPS)
|
kwargs['context'], security_group, ovn_const.TYPE_SECURITY_GROUPS)
|
||||||
|
|
||||||
def _create_sg_rule_precommit(self, resource, event, trigger, **kwargs):
|
def _create_sg_rule_precommit(self, resource, event, trigger,
|
||||||
sg_rule = kwargs.get('security_group_rule')
|
payload):
|
||||||
context = kwargs.get('context')
|
sg_rule = payload.latest_state
|
||||||
|
context = payload.context
|
||||||
ovn_revision_numbers_db.create_initial_revision(
|
ovn_revision_numbers_db.create_initial_revision(
|
||||||
context, sg_rule['id'], ovn_const.TYPE_SECURITY_GROUP_RULES,
|
context, sg_rule['id'], ovn_const.TYPE_SECURITY_GROUP_RULES,
|
||||||
std_attr_id=sg_rule['standard_attr_id'])
|
std_attr_id=sg_rule['standard_attr_id'])
|
||||||
|
|
||||||
def _process_sg_rule_notification(
|
def _process_sg_rule_notification(
|
||||||
self, resource, event, trigger, **kwargs):
|
self, resource, event, trigger, payload):
|
||||||
|
context = payload.context
|
||||||
|
security_group_rule = payload.latest_state
|
||||||
|
security_group_rule_id = payload.resource_id
|
||||||
if event == events.AFTER_CREATE:
|
if event == events.AFTER_CREATE:
|
||||||
self._ovn_client.create_security_group_rule(
|
self._ovn_client.create_security_group_rule(
|
||||||
kwargs['context'], kwargs.get('security_group_rule'))
|
context, security_group_rule)
|
||||||
elif event == events.BEFORE_DELETE:
|
elif event == events.BEFORE_DELETE:
|
||||||
sg_rule = self._plugin.get_security_group_rule(
|
sg_rule = self._plugin.get_security_group_rule(
|
||||||
kwargs['context'], kwargs.get('security_group_rule_id'))
|
context, security_group_rule_id)
|
||||||
if sg_rule.get('remote_ip_prefix') is not None:
|
if sg_rule.get('remote_ip_prefix') is not None:
|
||||||
if self._sg_has_rules_with_same_normalized_cidr(sg_rule):
|
if self._sg_has_rules_with_same_normalized_cidr(sg_rule):
|
||||||
return
|
return
|
||||||
self._ovn_client.delete_security_group_rule(
|
self._ovn_client.delete_security_group_rule(
|
||||||
kwargs['context'],
|
context,
|
||||||
sg_rule)
|
sg_rule)
|
||||||
|
|
||||||
def _sg_has_rules_with_same_normalized_cidr(self, sg_rule):
|
def _sg_has_rules_with_same_normalized_cidr(self, sg_rule):
|
||||||
|
|
|
@ -37,7 +37,9 @@ LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class _ObjectChangeHandler(object):
|
class _ObjectChangeHandler(object):
|
||||||
_PAYLOAD_RESOURCES = (resources.NETWORK, resources.ADDRESS_GROUP,)
|
_PAYLOAD_RESOURCES = (resources.NETWORK,
|
||||||
|
resources.ADDRESS_GROUP,
|
||||||
|
resources.SECURITY_GROUP_RULE,)
|
||||||
|
|
||||||
def __init__(self, resource, object_class, resource_push_api):
|
def __init__(self, resource, object_class, resource_push_api):
|
||||||
self._resource = resource
|
self._resource = resource
|
||||||
|
|
|
@ -124,8 +124,8 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase):
|
||||||
with mock.patch.object(self.mixin, '_validate_security_group_rule'),\
|
with mock.patch.object(self.mixin, '_validate_security_group_rule'),\
|
||||||
mock.patch.object(self.mixin,
|
mock.patch.object(self.mixin,
|
||||||
'_check_for_duplicate_rules'),\
|
'_check_for_duplicate_rules'),\
|
||||||
mock.patch.object(registry, "notify") as mock_notify:
|
mock.patch.object(registry, "publish") as mock_publish:
|
||||||
mock_notify.side_effect = exceptions.CallbackFailure(Exception())
|
mock_publish.side_effect = exceptions.CallbackFailure(Exception())
|
||||||
with testtools.ExpectedException(
|
with testtools.ExpectedException(
|
||||||
securitygroup.SecurityGroupConflict):
|
securitygroup.SecurityGroupConflict):
|
||||||
self.mixin.create_security_group_rule(
|
self.mixin.create_security_group_rule(
|
||||||
|
@ -201,8 +201,8 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase):
|
||||||
context, 'fake', [rule_dict])
|
context, 'fake', [rule_dict])
|
||||||
|
|
||||||
def test_delete_security_group_rule_in_use(self):
|
def test_delete_security_group_rule_in_use(self):
|
||||||
with mock.patch.object(registry, "notify") as mock_notify:
|
with mock.patch.object(registry, "publish") as mock_publish:
|
||||||
mock_notify.side_effect = exceptions.CallbackFailure(Exception())
|
mock_publish.side_effect = exceptions.CallbackFailure(Exception())
|
||||||
with testtools.ExpectedException(
|
with testtools.ExpectedException(
|
||||||
securitygroup.SecurityGroupRuleInUse):
|
securitygroup.SecurityGroupRuleInUse):
|
||||||
self.mixin.delete_security_group_rule(self.ctx, mock.ANY)
|
self.mixin.delete_security_group_rule(self.ctx, mock.ANY)
|
||||||
|
@ -415,34 +415,54 @@ class SecurityGroupDbMixinTestCase(testlib_api.SqlTestCase):
|
||||||
sg_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
|
sg_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
|
||||||
fake_rule = FAKE_SECGROUP_RULE
|
fake_rule = FAKE_SECGROUP_RULE
|
||||||
fake_rule['security_group_rule']['security_group_id'] = sg_dict['id']
|
fake_rule['security_group_rule']['security_group_id'] = sg_dict['id']
|
||||||
with mock.patch.object(registry, "notify") as mock_notify, \
|
with mock.patch.object(registry, "publish") as mock_publish, \
|
||||||
mock.patch.object(self.mixin, '_get_security_group'):
|
mock.patch.object(self.mixin, '_get_security_group'):
|
||||||
mock_notify.assert_has_calls([mock.call('security_group_rule',
|
sg_rule = self.mixin.create_security_group_rule(self.ctx,
|
||||||
'precommit_create', mock.ANY, context=mock.ANY,
|
fake_rule)
|
||||||
security_group_rule=self.mixin.create_security_group_rule(
|
mock_publish.assert_has_calls([mock.call(
|
||||||
self.ctx, fake_rule))])
|
'security_group_rule',
|
||||||
|
'precommit_create', mock.ANY, payload=mock.ANY)])
|
||||||
|
|
||||||
|
payload = mock_publish.mock_calls[1][2]['payload']
|
||||||
|
self.assertEqual(sg_rule['id'], payload.resource_id)
|
||||||
|
self.assertEqual(sg_rule, payload.latest_state)
|
||||||
|
|
||||||
def test_sg_rule_before_precommit_and_after_delete_event(self):
|
def test_sg_rule_before_precommit_and_after_delete_event(self):
|
||||||
sg_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
|
sg_dict = self.mixin.create_security_group(self.ctx, FAKE_SECGROUP)
|
||||||
fake_rule = FAKE_SECGROUP_RULE
|
fake_rule = FAKE_SECGROUP_RULE
|
||||||
fake_rule['security_group_rule']['security_group_id'] = sg_dict['id']
|
fake_rule['security_group_rule']['security_group_id'] = sg_dict['id']
|
||||||
with mock.patch.object(registry, "notify") as mock_notify, \
|
with mock.patch.object(registry, "publish") as mock_publish, \
|
||||||
mock.patch.object(self.mixin, '_get_security_group'):
|
mock.patch.object(self.mixin, '_get_security_group'):
|
||||||
sg_rule_dict = self.mixin.create_security_group_rule(self.ctx,
|
sg_rule_dict = self.mixin.create_security_group_rule(self.ctx,
|
||||||
fake_rule)
|
fake_rule)
|
||||||
self.mixin.delete_security_group_rule(self.ctx,
|
self.mixin.delete_security_group_rule(self.ctx,
|
||||||
sg_rule_dict['id'])
|
sg_rule_dict['id'])
|
||||||
mock_notify.assert_has_calls([mock.call('security_group_rule',
|
mock_publish.assert_has_calls([mock.call('security_group_rule',
|
||||||
'before_delete', mock.ANY, context=mock.ANY,
|
'before_delete',
|
||||||
security_group_rule_id=sg_rule_dict['id'])])
|
mock.ANY,
|
||||||
mock_notify.assert_has_calls([mock.call('security_group_rule',
|
payload=mock.ANY)])
|
||||||
'precommit_delete', mock.ANY, context=mock.ANY,
|
mock_publish.assert_has_calls([mock.call('security_group_rule',
|
||||||
security_group_id=sg_dict['id'],
|
'precommit_delete',
|
||||||
security_group_rule_id=sg_rule_dict['id'])])
|
mock.ANY,
|
||||||
mock_notify.assert_has_calls([mock.call('security_group_rule',
|
payload=mock.ANY)])
|
||||||
'after_delete', mock.ANY, context=mock.ANY,
|
mock_publish.assert_has_calls([mock.call('security_group_rule',
|
||||||
security_group_rule_id=sg_rule_dict['id'],
|
'after_delete',
|
||||||
security_group_id=sg_dict['id'])])
|
mock.ANY,
|
||||||
|
payload=mock.ANY)])
|
||||||
|
|
||||||
|
payload = mock_publish.mock_calls[1][2]['payload']
|
||||||
|
self.assertEqual(mock.ANY, payload.context)
|
||||||
|
self.assertEqual(sg_rule_dict, payload.latest_state)
|
||||||
|
self.assertEqual(sg_rule_dict['id'], payload.resource_id)
|
||||||
|
|
||||||
|
payload = mock_publish.mock_calls[2][2]['payload']
|
||||||
|
self.assertEqual(mock.ANY, payload.context)
|
||||||
|
self.assertEqual(sg_rule_dict, payload.latest_state)
|
||||||
|
self.assertEqual(sg_rule_dict['id'], payload.resource_id)
|
||||||
|
|
||||||
|
payload = mock_publish.mock_calls[3][2]['payload']
|
||||||
|
self.assertEqual(mock.ANY, payload.context)
|
||||||
|
self.assertEqual(sg_rule_dict['id'], payload.resource_id)
|
||||||
|
|
||||||
def test_get_ip_proto_name_and_num(self):
|
def test_get_ip_proto_name_and_num(self):
|
||||||
protocols = [constants.PROTO_NAME_UDP, str(constants.PROTO_NUM_TCP),
|
protocols = [constants.PROTO_NAME_UDP, str(constants.PROTO_NUM_TCP),
|
||||||
|
|
|
@ -258,7 +258,8 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
|
||||||
rule = {'security_group_id': 'sg_id'}
|
rule = {'security_group_id': 'sg_id'}
|
||||||
self.mech_driver._process_sg_rule_notification(
|
self.mech_driver._process_sg_rule_notification(
|
||||||
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, {},
|
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, {},
|
||||||
security_group_rule=rule, context=self.context)
|
payload=events.DBEventPayload(
|
||||||
|
self.context, states=(rule,)))
|
||||||
has_same_rules.assert_not_called()
|
has_same_rules.assert_not_called()
|
||||||
ovn_acl_up.assert_called_once_with(
|
ovn_acl_up.assert_called_once_with(
|
||||||
mock.ANY, mock.ANY, mock.ANY,
|
mock.ANY, mock.ANY, mock.ANY,
|
||||||
|
@ -278,7 +279,8 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
|
||||||
'remote_ip_prefix': '1.0.0.0/24'}
|
'remote_ip_prefix': '1.0.0.0/24'}
|
||||||
self.mech_driver._process_sg_rule_notification(
|
self.mech_driver._process_sg_rule_notification(
|
||||||
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, {},
|
resources.SECURITY_GROUP_RULE, events.AFTER_CREATE, {},
|
||||||
security_group_rule=rule, context=self.context)
|
payload=events.DBEventPayload(
|
||||||
|
self.context, states=(rule,)))
|
||||||
has_same_rules.assert_not_called()
|
has_same_rules.assert_not_called()
|
||||||
ovn_acl_up.assert_called_once_with(
|
ovn_acl_up.assert_called_once_with(
|
||||||
mock.ANY, mock.ANY, mock.ANY,
|
mock.ANY, mock.ANY, mock.ANY,
|
||||||
|
@ -296,7 +298,8 @@ class TestOVNMechanismDriver(TestOVNMechanismDriverBase):
|
||||||
return_value=rule):
|
return_value=rule):
|
||||||
self.mech_driver._process_sg_rule_notification(
|
self.mech_driver._process_sg_rule_notification(
|
||||||
resources.SECURITY_GROUP_RULE, events.BEFORE_DELETE, {},
|
resources.SECURITY_GROUP_RULE, events.BEFORE_DELETE, {},
|
||||||
security_group_rule=rule, context=self.context)
|
payload=events.DBEventPayload(
|
||||||
|
self.context, states=(rule,)))
|
||||||
ovn_acl_up.assert_called_once_with(
|
ovn_acl_up.assert_called_once_with(
|
||||||
mock.ANY, mock.ANY, mock.ANY,
|
mock.ANY, mock.ANY, mock.ANY,
|
||||||
'sg_id', rule, is_add_acl=False, stateless_supported=False)
|
'sg_id', rule, is_add_acl=False, stateless_supported=False)
|
||||||
|
|
Loading…
Reference in New Issue