summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ceilometer/alarm/notifier/rest.py5
-rw-r--r--ceilometer/alarm/notifier/trust.py66
-rw-r--r--ceilometer/tests/alarm/test_notifier.py19
-rw-r--r--setup.cfg2
4 files changed, 91 insertions, 1 deletions
diff --git a/ceilometer/alarm/notifier/rest.py b/ceilometer/alarm/notifier/rest.py
index b13befed..93a9f9c9 100644
--- a/ceilometer/alarm/notifier/rest.py
+++ b/ceilometer/alarm/notifier/rest.py
@@ -54,7 +54,8 @@ class RestAlarmNotifier(notifier.AlarmNotifier):
"""Rest alarm notifier."""
@staticmethod
- def notify(action, alarm_id, previous, current, reason, reason_data):
+ def notify(action, alarm_id, previous, current, reason, reason_data,
+ headers=None):
LOG.info(_(
"Notifying alarm %(alarm_id)s from %(previous)s "
"to %(current)s with action %(action)s because "
@@ -65,6 +66,8 @@ class RestAlarmNotifier(notifier.AlarmNotifier):
'current': current, 'reason': reason,
'reason_data': reason_data}
kwargs = {'data': jsonutils.dumps(body)}
+ if headers:
+ kwargs['headers'] = headers
if action.scheme == 'https':
default_verify = int(cfg.CONF.alarm.rest_notifier_ssl_verify)
diff --git a/ceilometer/alarm/notifier/trust.py b/ceilometer/alarm/notifier/trust.py
new file mode 100644
index 00000000..b3190b1b
--- /dev/null
+++ b/ceilometer/alarm/notifier/trust.py
@@ -0,0 +1,66 @@
+# -*- encoding: utf-8 -*-
+#
+# Copyright © 2014 eNovance
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+"""Rest alarm notifier with trusted authentication."""
+
+try:
+ import urllib.parse
+ SplitResult = urllib.parse.SplitResult
+except ImportError:
+ import urlparse
+ SplitResult = urlparse.SplitResult
+
+from keystoneclient.v3 import client as keystone_client
+from oslo.config import cfg
+
+from ceilometer.alarm import notifier
+
+
+class TrustRestAlarmNotifier(notifier.rest.RestAlarmNotifier):
+ """Notifier supporting keystone trust authentication.
+
+ This alarm notifier is intended to be used to call an endpoint using
+ keystone authentication. It uses the ceilometer service user to
+ authenticate using the trust ID provided.
+
+ The URL must be in the form trust+http://trust-id@host/action.
+ """
+
+ @staticmethod
+ def notify(action, alarm_id, previous, current, reason, reason_data):
+ trust_id = action.username
+
+ auth_url = cfg.CONF.service_credentials.os_auth_url.replace(
+ "v2.0", "v3")
+ client = keystone_client.Client(
+ username=cfg.CONF.service_credentials.os_username,
+ password=cfg.CONF.service_credentials.os_password,
+ cacert=cfg.CONF.service_credentials.os_cacert,
+ auth_url=auth_url,
+ region_name=cfg.CONF.service_credentials.os_region_name,
+ insecure=cfg.CONF.service_credentials.insecure,
+ trust_id=trust_id)
+
+ # Remove the fake user
+ netloc = action.netloc.split("@")[1]
+ # Remove the trust prefix
+ scheme = action.scheme[6:]
+
+ action = SplitResult(scheme, netloc, action.path, action.query,
+ action.fragment)
+
+ headers = {'X-Auth-Token': client.auth_token}
+ notifier.rest.RestAlarmNotifier.notify(
+ action, alarm_id, previous, current, reason, reason_data, headers)
diff --git a/ceilometer/tests/alarm/test_notifier.py b/ceilometer/tests/alarm/test_notifier.py
index 8f282833..3e4ba8ac 100644
--- a/ceilometer/tests/alarm/test_notifier.py
+++ b/ceilometer/tests/alarm/test_notifier.py
@@ -24,6 +24,7 @@ from ceilometer.alarm import service
from ceilometer import messaging
from ceilometer.openstack.common import context
from ceilometer.openstack.common.fixture import config
+from ceilometer.openstack.common.fixture import mockpatch
from ceilometer.openstack.common import test
@@ -203,3 +204,21 @@ class TestAlarmNotifier(test.BaseTestCase):
'condition': {'threshold': 42},
})
self.assertTrue(LOG.error.called)
+
+ def test_notify_alarm_trust_action(self):
+ action = 'trust+http://trust-1234@host/action'
+ url = 'http://host/action'
+
+ client = mock.MagicMock()
+ client.auth_token = 'token_1234'
+
+ self.useFixture(mockpatch.Patch('keystoneclient.v3.client.Client',
+ lambda **kwargs: client))
+
+ with mock.patch('eventlet.spawn_n', self._fake_spawn_n):
+ with mock.patch.object(requests, 'post') as poster:
+ self.service.notify_alarm(context.get_admin_context(),
+ self._notification(action))
+ poster.assert_called_with(
+ url, data=DATA_JSON,
+ headers={'X-Auth-Token': 'token_1234'})
diff --git a/setup.cfg b/setup.cfg
index 8446e6db..80b2c9f4 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -174,6 +174,8 @@ ceilometer.alarm.notifier =
test = ceilometer.alarm.notifier.test:TestAlarmNotifier
http = ceilometer.alarm.notifier.rest:RestAlarmNotifier
https = ceilometer.alarm.notifier.rest:RestAlarmNotifier
+ trust+http = ceilometer.alarm.notifier.trust:TrustRestAlarmNotifier
+ trust+https = ceilometer.alarm.notifier.trust:TrustRestAlarmNotifier
ceilometer.event.trait_plugin =
split = ceilometer.event.trait_plugins:SplitterTraitPlugin