summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Keen <joe.keen@hp.com>2017-02-16 14:56:11 -0700
committerDobroslaw Zybort <dobroslaw.zybort@ts.fujitsu.com>2019-01-17 11:58:45 +0100
commit1d680f173988dd02f86a72330d3ed2f3710ac7d3 (patch)
treebadd0c5beb0f360028711c44fca4e58662ea4524
parentcedb42da75a1e0695320fb8c403c073b01d0bd12 (diff)
Make default notifiers pluggable
Erasing distinction between plugins that are an inherent part of the notification engine and plugins that can be specified via the config file. Fixing broken tests. Story: 2003801 Task: 26532 Change-Id: I360cc2ad0782f209606706bf1869570fdae2260d
Notes
Notes (review): Code-Review+1: Dobroslaw Zybort <dobroslaw.zybort@ts.fujitsu.com> Code-Review+2: Doug Szumski <doug@stackhpc.com> Workflow+1: Witold Bedyk <witold.bedyk@suse.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 17 Jan 2019 13:31:27 +0000 Reviewed-on: https://review.openstack.org/435136 Project: openstack/monasca-notification Branch: refs/heads/master
-rw-r--r--monasca_notification/conf/__init__.py15
-rw-r--r--monasca_notification/conf/notifiers.py9
-rw-r--r--monasca_notification/types/notifiers.py11
-rw-r--r--tests/resources/notification.yaml3
-rw-r--r--tests/test_notification_processor.py2
-rw-r--r--tests/test_notifiers.py159
6 files changed, 123 insertions, 76 deletions
diff --git a/monasca_notification/conf/__init__.py b/monasca_notification/conf/__init__.py
index 9dc80aa..5dc861d 100644
--- a/monasca_notification/conf/__init__.py
+++ b/monasca_notification/conf/__init__.py
@@ -80,21 +80,6 @@ def load_from_yaml(yaml_config, conf=None):
80 notifiers_cfg = {t.lower(): v for t, v in notifiers_cfg.items()} 80 notifiers_cfg = {t.lower(): v for t, v in notifiers_cfg.items()}
81 enabled_plugins = notifiers_cfg.pop('plugins', []) 81 enabled_plugins = notifiers_cfg.pop('plugins', [])
82 82
83 # We still can have these 3 (email, pagerduty, webhook)
84 # that are considered as builtin, hence should be always enabled
85 conf_to_plugin = {
86 'email': 'monasca_notification.plugins.'
87 'email_notifier:EmailNotifier',
88 'pagerduty': 'monasca_notification.plugins.'
89 'pagerduty_notifier:PagerdutyNotifier',
90 'webhook': 'monasca_notification.plugins.'
91 'webhook_notifier:WebhookNotifier'
92 }
93 for ctp_key, ctp_clazz in conf_to_plugin.items():
94 if ctp_key in notifiers_cfg and ctp_key not in enabled_plugins:
95 LOG.debug('%s enabled as builtin plugin', ctp_key)
96 enabled_plugins.append(ctp_clazz)
97
98 _plain_override(g='notification_types', enabled=enabled_plugins) 83 _plain_override(g='notification_types', enabled=enabled_plugins)
99 if not enabled_plugins: 84 if not enabled_plugins:
100 return 85 return
diff --git a/monasca_notification/conf/notifiers.py b/monasca_notification/conf/notifiers.py
index 6f2787a..c37cf89 100644
--- a/monasca_notification/conf/notifiers.py
+++ b/monasca_notification/conf/notifiers.py
@@ -14,12 +14,11 @@
14 14
15from oslo_config import cfg 15from oslo_config import cfg
16 16
17# NOTE(kornicameister) Until https://review.openstack.org/#/c/435136/
18# is merged we only treat these below as plugins.
19# WEBHOOK, EMAIL, PAGERDUTY are now treated as built-in & hardcoded
20# user has no possibility of enabling/disabling them
21
22_KEY_MAP = { 17_KEY_MAP = {
18 'email': 'monasca_notification.plugins.email_notifier:EmailNotifier',
19 'pagerduty': 'monasca_notification.plugins.'
20 'pagerduty_notifier:PagerdutyNotifier',
21 'webhook': 'monasca_notification.plugins.webhook_notifier:WebhookNotifier',
23 'hipchat': 'monasca_notification.plugins.hipchat_notifier.HipChatNotifier', 22 'hipchat': 'monasca_notification.plugins.hipchat_notifier.HipChatNotifier',
24 'slack': 'monasca_notification.plugins.slack_notifier.SlackNotifier', 23 'slack': 'monasca_notification.plugins.slack_notifier.SlackNotifier',
25 'jira': 'monasca_notification.plugins.jira_notifier.JiraNotifier' 24 'jira': 'monasca_notification.plugins.jira_notifier.JiraNotifier'
diff --git a/monasca_notification/types/notifiers.py b/monasca_notification/types/notifiers.py
index 89cebff..833a400 100644
--- a/monasca_notification/types/notifiers.py
+++ b/monasca_notification/types/notifiers.py
@@ -21,10 +21,6 @@ from oslo_config import cfg
21from oslo_log import log as logging 21from oslo_log import log as logging
22from oslo_utils import importutils 22from oslo_utils import importutils
23 23
24from monasca_notification.plugins import email_notifier
25from monasca_notification.plugins import pagerduty_notifier
26from monasca_notification.plugins import webhook_notifier
27
28log = logging.getLogger(__name__) 24log = logging.getLogger(__name__)
29CONF = cfg.CONF 25CONF = cfg.CONF
30 26
@@ -46,12 +42,7 @@ def init(statsd_obj):
46 42
47 statsd_counter = {} 43 statsd_counter = {}
48 configured_notifiers = {} 44 configured_notifiers = {}
49 45 possible_notifiers = []
50 possible_notifiers = [
51 email_notifier.EmailNotifier(log),
52 webhook_notifier.WebhookNotifier(log),
53 pagerduty_notifier.PagerdutyNotifier(log)
54 ]
55 46
56 47
57def load_plugins(): 48def load_plugins():
diff --git a/tests/resources/notification.yaml b/tests/resources/notification.yaml
index cbc6a1f..a5b278f 100644
--- a/tests/resources/notification.yaml
+++ b/tests/resources/notification.yaml
@@ -29,6 +29,9 @@ postgresql:
29 29
30notification_types: 30notification_types:
31 plugins: 31 plugins:
32 - monasca_notification.plugins.email_notifier:EmailNotifier
33 - monasca_notification.plugins.pagerduty_notifier:PagerdutyNotifier
34 - monasca_notification.plugins.webhook_notifier:WebhookNotifier
32 - monasca_notification.plugins.hipchat_notifier:HipChatNotifier 35 - monasca_notification.plugins.hipchat_notifier:HipChatNotifier
33 - monasca_notification.plugins.slack_notifier:SlackNotifier 36 - monasca_notification.plugins.slack_notifier:SlackNotifier
34 - monasca_notification.plugins.jira_notifier:JiraNotifier 37 - monasca_notification.plugins.jira_notifier:JiraNotifier
diff --git a/tests/test_notification_processor.py b/tests/test_notification_processor.py
index 8765bc6..875d110 100644
--- a/tests/test_notification_processor.py
+++ b/tests/test_notification_processor.py
@@ -61,7 +61,7 @@ class TestNotificationProcessor(base.BaseTestCase):
61 # ------------------------------------------------------------------------ 61 # ------------------------------------------------------------------------
62 @mock.patch('pymysql.connect') 62 @mock.patch('pymysql.connect')
63 @mock.patch('monasca_notification.common.utils.monascastatsd') 63 @mock.patch('monasca_notification.common.utils.monascastatsd')
64 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 64 @mock.patch('monasca_notification.plugins.email_notifier.smtplib')
65 @mock.patch('monasca_notification.processors.notification_processor.notifiers.log') 65 @mock.patch('monasca_notification.processors.notification_processor.notifiers.log')
66 def _start_processor(self, notifications, mock_log, mock_smtp, mock_statsd, mock_pymsql): 66 def _start_processor(self, notifications, mock_log, mock_smtp, mock_statsd, mock_pymsql):
67 """Start the processor with the proper mocks 67 """Start the processor with the proper mocks
diff --git a/tests/test_notifiers.py b/tests/test_notifiers.py
index ebd44d3..7367606 100644
--- a/tests/test_notifiers.py
+++ b/tests/test_notifiers.py
@@ -1,4 +1,4 @@
1# (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP 1# (C) Copyright 2015-2017 Hewlett Packard Enterprise Development LP
2# Copyright 2017 Fujitsu LIMITED 2# Copyright 2017 Fujitsu LIMITED
3# 3#
4# Licensed under the Apache License, Version 2.0 (the "License"); 4# Licensed under the Apache License, Version 2.0 (the "License");
@@ -149,55 +149,103 @@ class TestInterface(base.BaseTestCase):
149 def _goodSendStub(self, log): 149 def _goodSendStub(self, log):
150 return NotifyStub(self.trap, False, False, False) 150 return NotifyStub(self.trap, False, False, False)
151 151
152 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 152 def test_enabled_notifications_none(self):
153 @mock.patch('monasca_notification.types.notifiers.log') 153 self.conf_override(
154 def test_enabled_notifications(self, mock_log, mock_smtp): 154 group='notification_types',
155 enabled=[]
156 )
157
155 notifiers.init(self.statsd) 158 notifiers.init(self.statsd)
159 notifiers.load_plugins()
156 notifiers.config() 160 notifiers.config()
157 161
158 notifications = notifiers.enabled_notifications() 162 notifications = notifiers.enabled_notifications()
159 163
160 self.assertEqual(len(notifications), 3) 164 self.assertEqual(len(notifications), 0)
161 self.assertEqual(sorted(notifications),
162 ["EMAIL", "PAGERDUTY", "WEBHOOK"])
163 165
164 @mock.patch('monasca_notification.types.notifiers.email_notifier') 166 def test_enabled_notifications(self):
165 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 167 self.conf_override(
168 group='notification_types',
169 enabled=[
170 'monasca_notification.plugins.email_notifier:EmailNotifier',
171 'monasca_notification.plugins.pagerduty_notifier:PagerdutyNotifier',
172 'monasca_notification.plugins.webhook_notifier:WebhookNotifier',
173 'monasca_notification.plugins.hipchat_notifier:HipChatNotifier',
174 'monasca_notification.plugins.slack_notifier:SlackNotifier',
175 'monasca_notification.plugins.jira_notifier:JiraNotifier'
176 ]
177 )
178 notifiers.init(self.statsd)
179 notifiers.load_plugins()
180 notifiers.config()
181
182 notifications = notifiers.enabled_notifications()
183 self.assertEqual(len(notifications), 6)
184 self.assertItemsEqual(notifications,
185 ['EMAIL', 'PAGERDUTY', 'WEBHOOK',
186 'HIPCHAT', 'SLACK', 'JIRA'])
187
188 @mock.patch('monasca_notification.plugins.email_notifier')
189 @mock.patch('monasca_notification.plugins.email_notifier.smtplib')
166 @mock.patch('monasca_notification.types.notifiers.log') 190 @mock.patch('monasca_notification.types.notifiers.log')
167 def test_send_notification_exception(self, mock_log, mock_smtp, mock_email): 191 @mock.patch('monasca_notification.types.notifiers.importutils')
192 def test_send_notification_exception(self, mock_im, mock_log,
193 mock_smtp, mock_email):
194 self.conf_override(
195 group='notification_types',
196 enabled=[
197 'monasca_notification.plugins.email_notifier:EmailNotifier'
198 ]
199 )
200
168 mock_log.warn = self.trap.append 201 mock_log.warn = self.trap.append
169 mock_log.error = self.trap.append 202 mock_log.error = self.trap.append
170 mock_log.exception = self.trap.append 203 mock_log.exception = self.trap.append
171 204
172 mock_email.EmailNotifier = self._sendExceptionStub 205 mock_email.EmailNotifier = self._sendExceptionStub
206 mock_im.import_class.return_value = mock_email.EmailNotifier
173 207
174 notifiers.init(self.statsd) 208 notifiers.init(self.statsd)
209 notifiers.load_plugins()
175 notifiers.config() 210 notifiers.config()
176 211
177 notifications = [] 212 notifications = [
178 notifications.append(m_notification.Notification(0, 'email', 'email notification', 213 m_notification.Notification(0, 'email', 'email notification',
179 'me@here.com', 0, 0, alarm({}))) 214 'me@here.com', 0, 0, alarm({}))
215 ]
180 216
181 notifiers.send_notifications(notifications) 217 notifiers.send_notifications(notifications)
182 218
183 self.assertIn("send_notification exception for email", self.trap) 219 self.assertIn("send_notification exception for email", self.trap)
184 220
185 @mock.patch('monasca_notification.types.notifiers.email_notifier') 221 @mock.patch('monasca_notification.plugins.email_notifier')
186 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 222 @mock.patch('monasca_notification.plugins.email_notifier.smtplib')
187 @mock.patch('monasca_notification.types.notifiers.log') 223 @mock.patch('monasca_notification.types.notifiers.log')
188 def test_send_notification_failure(self, mock_log, mock_smtp, mock_email): 224 @mock.patch('monasca_notification.types.notifiers.importutils')
225 def test_send_notification_failure(self, mock_im, mock_log,
226 mock_smtp, mock_email):
227 self.conf_override(
228 group='notification_types',
229 enabled=[
230 'monasca_notification.plugins.email_notifier:EmailNotifier'
231 ]
232 )
233
189 mock_log.warn = self.trap.append 234 mock_log.warn = self.trap.append
190 mock_log.error = self.trap.append 235 mock_log.error = self.trap.append
191 mock_log.exception = self.trap.append 236 mock_log.exception = self.trap.append
192 237
193 mock_email.EmailNotifier = self._sendFailureStub 238 mock_email.EmailNotifier = self._sendFailureStub
239 mock_im.import_class.return_value = mock_email.EmailNotifier
194 240
195 notifiers.init(self.statsd) 241 notifiers.init(self.statsd)
242 notifiers.load_plugins()
196 notifiers.config() 243 notifiers.config()
197 244
198 notifications = [] 245 notifications = [
199 notifications.append(m_notification.Notification(0, 'email', 'email notification', 246 m_notification.Notification(0, 'email', 'email notification',
200 'me@here.com', 0, 0, alarm({}))) 247 'me@here.com', 0, 0, alarm({}))
248 ]
201 249
202 sent, failed, invalid = notifiers.send_notifications(notifications) 250 sent, failed, invalid = notifiers.send_notifications(notifications)
203 251
@@ -206,28 +254,38 @@ class TestInterface(base.BaseTestCase):
206 self.assertEqual(invalid, []) 254 self.assertEqual(invalid, [])
207 255
208 @mock.patch('monasca_notification.types.notifiers.time') 256 @mock.patch('monasca_notification.types.notifiers.time')
209 @mock.patch('monasca_notification.types.notifiers.email_notifier') 257 @mock.patch('monasca_notification.plugins.email_notifier')
210 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 258 @mock.patch('monasca_notification.plugins.email_notifier.smtplib')
211 @mock.patch('monasca_notification.types.notifiers.log') 259 @mock.patch('monasca_notification.types.notifiers.log')
212 def test_send_notification_correct(self, mock_log, mock_smtp, 260 @mock.patch('monasca_notification.types.notifiers.importutils')
261 def test_send_notification_correct(self, mock_im, mock_log, mock_smtp,
213 mock_email, mock_time): 262 mock_email, mock_time):
263 self.conf_override(
264 group='notification_types',
265 enabled=[
266 'monasca_notification.plugins.email_notifier:EmailNotifier'
267 ]
268 )
269
214 mock_log.warn = self.trap.append 270 mock_log.warn = self.trap.append
215 mock_log.error = self.trap.append 271 mock_log.error = self.trap.append
216 272
217 mock_email.EmailNotifier = self._goodSendStub 273 mock_email.EmailNotifier = self._goodSendStub
218
219 mock_time.time.return_value = 42 274 mock_time.time.return_value = 42
275 mock_im.import_class.return_value = mock_email.EmailNotifier
220 276
221 notifiers.init(self.statsd) 277 notifiers.init(self.statsd)
278 notifiers.load_plugins()
222 notifiers.config() 279 notifiers.config()
223 280
224 notifications = [] 281 notifications = [
225 notifications.append(m_notification.Notification(0, 'email', 'email notification', 282 m_notification.Notification(0, 'email', 'email notification',
226 'me@here.com', 0, 0, alarm({}))) 283 'me@here.com', 0, 0, alarm({})),
227 notifications.append(m_notification.Notification(1, 'email', 'email notification', 284 m_notification.Notification(1, 'email', 'email notification',
228 'foo@here.com', 0, 0, alarm({}))) 285 'foo@here.com', 0, 0, alarm({})),
229 notifications.append(m_notification.Notification(2, 'email', 'email notification', 286 m_notification.Notification(2, 'email', 'email notification',
230 'bar@here.com', 0, 0, alarm({}))) 287 'bar@here.com', 0, 0, alarm({}))
288 ]
231 289
232 sent, failed, invalid = notifiers.send_notifications(notifications) 290 sent, failed, invalid = notifiers.send_notifications(notifications)
233 291
@@ -238,25 +296,36 @@ class TestInterface(base.BaseTestCase):
238 for n in sent: 296 for n in sent:
239 self.assertEqual(n.notification_timestamp, 42) 297 self.assertEqual(n.notification_timestamp, 42)
240 298
241 @mock.patch('monasca_notification.types.notifiers.email_notifier') 299 @mock.patch('monasca_notification.plugins.email_notifier')
242 @mock.patch('monasca_notification.types.notifiers.email_notifier.smtplib') 300 @mock.patch('monasca_notification.plugins.email_notifier.smtplib')
243 @mock.patch('monasca_notification.types.notifiers.log') 301 @mock.patch('monasca_notification.types.notifiers.log')
244 def test_statsd(self, mock_log, mock_smtp, mock_email): 302 @mock.patch('monasca_notification.types.notifiers.importutils')
303 def test_statsd(self, mock_im, mock_log, mock_smtp, mock_email):
304 self.conf_override(
305 group='notification_types',
306 enabled=[
307 'monasca_notification.plugins.email_notifier:EmailNotifier'
308 ]
309 )
310
245 mock_log.warn = self.trap.append 311 mock_log.warn = self.trap.append
246 mock_log.error = self.trap.append 312 mock_log.error = self.trap.append
247 313
248 mock_email.EmailNotifier = self._goodSendStub 314 mock_email.EmailNotifier = self._goodSendStub
315 mock_im.import_class.return_value = mock_email.EmailNotifier
249 316
250 notifiers.init(self.statsd) 317 notifiers.init(self.statsd)
318 notifiers.load_plugins()
251 notifiers.config() 319 notifiers.config()
252 320
253 notifications = [] 321 notifications = [
254 notifications.append(m_notification.Notification(0, 'email', 'email notification', 322 m_notification.Notification(0, 'email', 'email notification',
255 'me@here.com', 0, 0, alarm({}))) 323 'me@here.com', 0, 0, alarm({})),
256 notifications.append(m_notification.Notification(1, 'email', 'email notification', 324 m_notification.Notification(1, 'email', 'email notification',
257 'foo@here.com', 0, 0, alarm({}))) 325 'foo@here.com', 0, 0, alarm({})),
258 notifications.append(m_notification.Notification(2, 'email', 'email notification', 326 m_notification.Notification(2, 'email', 'email notification',
259 'bar@here.com', 0, 0, alarm({}))) 327 'bar@here.com', 0, 0, alarm({}))
328 ]
260 329
261 notifiers.send_notifications(notifications) 330 notifiers.send_notifications(notifications)
262 331
@@ -275,11 +344,11 @@ class TestInterface(base.BaseTestCase):
275 344
276 notifiers.init(self.statsd) 345 notifiers.init(self.statsd)
277 notifiers.load_plugins() 346 notifiers.load_plugins()
278 self.assertEqual(len(notifiers.possible_notifiers), 5) 347 notifiers.config()
279 348
280 configured_plugins = ["email", "webhook", "pagerduty", "hipchat", "slack"] 349 self.assertEqual(len(notifiers.possible_notifiers), 2)
281 for plugin in notifiers.configured_notifiers: 350 self.assertItemsEqual(['hipchat', 'slack'],
282 self.asssertIn(plugin.type in configured_plugins) 351 notifiers.configured_notifiers)
283 352
284 @mock.patch('monasca_notification.types.notifiers.log') 353 @mock.patch('monasca_notification.types.notifiers.log')
285 def test_invalid_plugin_load_exception_ignored(self, mock_log): 354 def test_invalid_plugin_load_exception_ignored(self, mock_log):
@@ -294,7 +363,7 @@ class TestInterface(base.BaseTestCase):
294 363
295 notifiers.init(self.statsd) 364 notifiers.init(self.statsd)
296 notifiers.load_plugins() 365 notifiers.load_plugins()
297 self.assertEqual(len(notifiers.possible_notifiers), 4) 366 self.assertEqual(len(notifiers.possible_notifiers), 1)
298 self.assertEqual(len(self.trap), 1) 367 self.assertEqual(len(self.trap), 1)
299 368
300 configured_plugins = ["email", "webhook", "pagerduty", "slack"] 369 configured_plugins = ["email", "webhook", "pagerduty", "slack"]