Merge "Add a alarm notification using trusts"

This commit is contained in:
Jenkins 2014-04-25 11:33:06 +00:00 committed by Gerrit Code Review
commit ad72ca88ab
4 changed files with 91 additions and 1 deletions

View File

@ -54,7 +54,8 @@ class RestAlarmNotifier(notifier.AlarmNotifier):
"""Rest alarm notifier.""" """Rest alarm notifier."""
@staticmethod @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(_( LOG.info(_(
"Notifying alarm %(alarm_id)s from %(previous)s " "Notifying alarm %(alarm_id)s from %(previous)s "
"to %(current)s with action %(action)s because " "to %(current)s with action %(action)s because "
@ -65,6 +66,8 @@ class RestAlarmNotifier(notifier.AlarmNotifier):
'current': current, 'reason': reason, 'current': current, 'reason': reason,
'reason_data': reason_data} 'reason_data': reason_data}
kwargs = {'data': jsonutils.dumps(body)} kwargs = {'data': jsonutils.dumps(body)}
if headers:
kwargs['headers'] = headers
if action.scheme == 'https': if action.scheme == 'https':
default_verify = int(cfg.CONF.alarm.rest_notifier_ssl_verify) default_verify = int(cfg.CONF.alarm.rest_notifier_ssl_verify)

View File

@ -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)

View File

@ -24,6 +24,7 @@ from ceilometer.alarm import service
from ceilometer import messaging from ceilometer import messaging
from ceilometer.openstack.common import context from ceilometer.openstack.common import context
from ceilometer.openstack.common.fixture import config from ceilometer.openstack.common.fixture import config
from ceilometer.openstack.common.fixture import mockpatch
from ceilometer.openstack.common import test from ceilometer.openstack.common import test
@ -203,3 +204,21 @@ class TestAlarmNotifier(test.BaseTestCase):
'condition': {'threshold': 42}, 'condition': {'threshold': 42},
}) })
self.assertTrue(LOG.error.called) 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'})

View File

@ -174,6 +174,8 @@ ceilometer.alarm.notifier =
test = ceilometer.alarm.notifier.test:TestAlarmNotifier test = ceilometer.alarm.notifier.test:TestAlarmNotifier
http = ceilometer.alarm.notifier.rest:RestAlarmNotifier http = ceilometer.alarm.notifier.rest:RestAlarmNotifier
https = 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 = ceilometer.event.trait_plugin =
split = ceilometer.event.trait_plugins:SplitterTraitPlugin split = ceilometer.event.trait_plugins:SplitterTraitPlugin