Fix notify filter when data item is None
When data[k] is None during match check, we are getting annoying TypeError exceptions like: "TypeError: expected string or buffer". This patch adds a check that data[k] is something the regex can do matching. Change-Id: I75c8f602a59a90aeb5a6973f2e9e25708194ad78
This commit is contained in:
parent
fcf114294b
commit
3cdfe15897
@ -15,6 +15,8 @@
|
||||
|
||||
import re
|
||||
|
||||
import six
|
||||
|
||||
|
||||
class NotificationFilter(object):
|
||||
|
||||
@ -31,7 +33,7 @@ class NotificationFilter(object):
|
||||
filter_rule = NotificationFilter(
|
||||
publisher_id='^compute.*',
|
||||
context={'tenant_id': '^5f643cfc-664b-4c69-8000-ce2ed7b08216$',
|
||||
'roles='private'},
|
||||
'roles': 'private'},
|
||||
event_type='^compute\.instance\..*',
|
||||
metadata={'timestamp': 'Aug'},
|
||||
payload={'state': '^active$')
|
||||
@ -58,15 +60,27 @@ class NotificationFilter(object):
|
||||
return dict((k, re.compile(regex_list[k])) for k in regex_list)
|
||||
|
||||
@staticmethod
|
||||
def _check_for_mismatch(data, regex):
|
||||
if isinstance(regex, dict):
|
||||
for k in regex:
|
||||
if (k not in data or not regex[k].match(data[k])):
|
||||
return True
|
||||
elif regex is not None and not regex.match(data):
|
||||
def _check_for_single_mismatch(data, regex):
|
||||
if regex is None:
|
||||
return False
|
||||
if not isinstance(data, six.string_types):
|
||||
return True
|
||||
if not regex.match(data):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def _check_for_mismatch(cls, data, regex):
|
||||
if isinstance(regex, dict):
|
||||
for k in regex:
|
||||
if k not in data:
|
||||
return True
|
||||
if cls._check_for_single_mismatch(data[k], regex[k]):
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
return cls._check_for_single_mismatch(data, regex)
|
||||
|
||||
def match(self, context, publisher_id, event_type, metadata, payload):
|
||||
if (self._check_for_mismatch(publisher_id, self._regex_publisher_id) or
|
||||
self._check_for_mismatch(event_type, self._regex_event_type) or
|
||||
|
@ -163,6 +163,13 @@ class TestDispatcherFilter(test_utils.BaseTestCase):
|
||||
event_type='instance.create.start',
|
||||
context={},
|
||||
match=False)),
|
||||
# this is only for simulation
|
||||
('event_type_not_string',
|
||||
dict(filter_rule=dict(event_type='^instance\.delete'),
|
||||
publisher_id='compute01.manager',
|
||||
event_type=['instance.swim', 'instance.fly'],
|
||||
context={},
|
||||
match=False)),
|
||||
('context_match',
|
||||
dict(filter_rule=dict(context={'user': '^adm'}),
|
||||
publisher_id='compute01.manager',
|
||||
@ -206,6 +213,12 @@ class TestDispatcherFilter(test_utils.BaseTestCase):
|
||||
event_type='instance.create.start',
|
||||
context={},
|
||||
match=False)),
|
||||
('payload_value_none',
|
||||
dict(filter_rule=dict(payload={'virtual_size': '2048'}),
|
||||
publisher_id='compute01.manager',
|
||||
event_type='instance.create.start',
|
||||
context={},
|
||||
match=False)),
|
||||
('mix_match',
|
||||
dict(filter_rule=dict(event_type='^instance\.create',
|
||||
publisher_id='^compute',
|
||||
@ -214,7 +227,6 @@ class TestDispatcherFilter(test_utils.BaseTestCase):
|
||||
event_type='instance.create.start',
|
||||
context={'user': 'admin'},
|
||||
match=True)),
|
||||
|
||||
]
|
||||
|
||||
def test_filters(self):
|
||||
@ -224,7 +236,7 @@ class TestDispatcherFilter(test_utils.BaseTestCase):
|
||||
|
||||
dispatcher = notify_dispatcher.NotificationDispatcher(
|
||||
[endpoint], serializer=None)
|
||||
message = {'payload': {'state': 'active'},
|
||||
message = {'payload': {'state': 'active', 'virtual_size': None},
|
||||
'priority': 'info',
|
||||
'publisher_id': self.publisher_id,
|
||||
'event_type': self.event_type,
|
||||
|
Loading…
Reference in New Issue
Block a user