Merge "Enable signature verification for events"

This commit is contained in:
Jenkins 2015-12-03 08:16:53 +00:00 committed by Gerrit Code Review
commit dcada9c8d8
4 changed files with 73 additions and 34 deletions

View File

@ -109,20 +109,25 @@ class DatabaseDispatcher(dispatcher.MeterDispatcherBase,
event_list = [] event_list = []
for ev in events: for ev in events:
try: if publisher_utils.verify_signature(
event_list.append( ev, self.conf.publisher.telemetry_secret):
models.Event( try:
message_id=ev['message_id'], event_list.append(
event_type=ev['event_type'], models.Event(
generated=timeutils.normalize_time( message_id=ev['message_id'],
timeutils.parse_isotime(ev['generated'])), event_type=ev['event_type'],
traits=[models.Trait( generated=timeutils.normalize_time(
name, dtype, timeutils.parse_isotime(ev['generated'])),
models.Trait.convert_value(dtype, value)) traits=[models.Trait(
for name, dtype, value in ev['traits']], name, dtype,
raw=ev.get('raw', {})) models.Trait.convert_value(dtype, value))
) for name, dtype, value in ev['traits']],
except Exception: raw=ev.get('raw', {}))
LOG.exception(_LE("Error processing event and it will be " )
"dropped: %s"), ev) except Exception:
LOG.exception(_LE("Error processing event and it will be "
"dropped: %s"), ev)
else:
LOG.warning(_LW(
'event signature invalid, discarding event: %s'), ev)
self.event_conn.record_events(event_list) self.event_conn.record_events(event_list)

View File

@ -19,7 +19,7 @@ from oslo_log import log
import requests import requests
from ceilometer import dispatcher from ceilometer import dispatcher
from ceilometer.i18n import _, _LE from ceilometer.i18n import _, _LE, _LW
from ceilometer.publisher import utils as publisher_utils from ceilometer.publisher import utils as publisher_utils
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@ -132,13 +132,19 @@ class HttpDispatcher(dispatcher.MeterDispatcherBase,
events = [events] events = [events]
for event in events: for event in events:
res = None if publisher_utils.verify_signature(
try: event, self.conf.publisher.telemetry_secret):
res = requests.post(self.event_target, data=event, res = None
headers=self.headers, timeout=self.timeout) try:
res.raise_for_status() res = requests.post(self.event_target, data=event,
except Exception: headers=self.headers,
error_code = res.status_code if res else 'unknown' timeout=self.timeout)
LOG.exception(_LE('Status Code: %{code}s. Failed to dispatch ' res.raise_for_status()
'event: %{event}s'), except Exception:
{'code': error_code, 'event': event}) error_code = res.status_code if res else 'unknown'
LOG.exception(_LE('Status Code: %{code}s. Failed to'
'dispatch event: %{event}s'),
{'code': error_code, 'event': event})
else:
LOG.warning(_LW(
'event signature invalid, discarding event: %s'), event)

View File

@ -36,11 +36,35 @@ class TestDispatcherDB(base.BaseTestCase):
def test_event_conn(self): def test_event_conn(self):
event = event_models.Event(uuid.uuid4(), 'test', event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40), datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {}).serialize() [], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch.object(self.dispatcher.event_conn, with mock.patch.object(self.dispatcher.event_conn,
'record_events') as record_events: 'record_events') as record_events:
self.dispatcher.record_events(event) self.dispatcher.record_events(event)
self.assertTrue(record_events.called) self.assertEqual(1, len(record_events.call_args_list[0][0][0]))
@mock.patch('ceilometer.publisher.utils.verify_signature')
def test_event_with_bad_signature(self, mocked_verify):
event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {}).serialize()
def _fake_verify(ev, secret):
if ev.get('message_signature') == 'bad_signature':
return False
return True
mocked_verify.side_effect = _fake_verify
with mock.patch.object(self.dispatcher.event_conn,
'record_events') as record_events:
event['message_signature'] = 'bad_signature'
self.dispatcher.record_events(event)
self.assertEqual([], record_events.call_args_list[0][0][0])
del event['message_signature']
event['message_signature'] = utils.compute_signature(
event, self.CONF.publisher.telemetry_secret)
self.dispatcher.record_events(event)
self.assertEqual(1, len(record_events.call_args_list[1][0][0]))
def test_valid_message(self): def test_valid_message(self):
msg = {'counter_name': 'test', msg = {'counter_name': 'test',

View File

@ -136,7 +136,9 @@ class TestEventDispatcherHttp(base.BaseTestCase):
event = event_models.Event(uuid.uuid4(), 'test', event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40), datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {}).serialize() [], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch.object(requests, 'post') as post: with mock.patch.object(requests, 'post') as post:
dispatcher.record_events(event) dispatcher.record_events(event)
@ -149,8 +151,9 @@ class TestEventDispatcherHttp(base.BaseTestCase):
event = event_models.Event(uuid.uuid4(), 'test', event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40), datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {}).serialize() [], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch('ceilometer.dispatcher.http.LOG', with mock.patch('ceilometer.dispatcher.http.LOG',
mock.MagicMock()) as LOG: mock.MagicMock()) as LOG:
dispatcher.record_events(event) dispatcher.record_events(event)
@ -162,8 +165,9 @@ class TestEventDispatcherHttp(base.BaseTestCase):
event = event_models.Event(uuid.uuid4(), 'test', event = event_models.Event(uuid.uuid4(), 'test',
datetime.datetime(2012, 7, 2, 13, 53, 40), datetime.datetime(2012, 7, 2, 13, 53, 40),
[], {}).serialize() [], {})
event = utils.message_from_event(event,
self.CONF.publisher.telemetry_secret)
with mock.patch.object(requests, 'post') as post: with mock.patch.object(requests, 'post') as post:
dispatcher.record_events(event) dispatcher.record_events(event)