Add trust+zaqar:// action
Allow Zaqar messages to be posted to a queue under the user's own tenant by using a Keystone trust. Change-Id: Ia9e200ecef13ba46479a155fee064d6dded08917
This commit is contained in:
parent
b9242bf984
commit
ef08bc2e6a
@ -384,7 +384,7 @@ class Alarm(base.Base):
|
||||
|
||||
@staticmethod
|
||||
def _is_trust_url(url):
|
||||
return url.scheme in ('trust+http', 'trust+https')
|
||||
return url.scheme.startswith('trust+')
|
||||
|
||||
def update_actions(self, old_alarm=None):
|
||||
trustor_user_id = pecan.request.headers.get('X-User-Id')
|
||||
|
@ -20,14 +20,12 @@ from aodh import keystone_client
|
||||
from aodh.notifier import rest
|
||||
|
||||
|
||||
class TrustRestAlarmNotifier(rest.RestAlarmNotifier):
|
||||
"""Notifier supporting keystone trust authentication.
|
||||
class TrustAlarmNotifierMixin(object):
|
||||
"""Mixin class to add Keystone trust support to an AlarmNotifier.
|
||||
|
||||
This alarm notifier is intended to be used to call an endpoint using
|
||||
keystone authentication. It uses the aodh service user to
|
||||
authenticate using the trust ID provided.
|
||||
|
||||
The URL must be in the form trust+http://trust-id@host/action.
|
||||
Provides a notify() method that interprets the trust ID and then calls
|
||||
the parent class's notify(), passing the necessary authentication data in
|
||||
the headers.
|
||||
"""
|
||||
|
||||
def notify(self, action, alarm_id, alarm_name, severity, previous, current,
|
||||
@ -45,6 +43,17 @@ class TrustRestAlarmNotifier(rest.RestAlarmNotifier):
|
||||
action.fragment)
|
||||
|
||||
headers = {'X-Auth-Token': keystone_client.get_auth_token(client)}
|
||||
super(TrustRestAlarmNotifier, self).notify(
|
||||
super(TrustAlarmNotifierMixin, self).notify(
|
||||
action, alarm_id, alarm_name, severity, previous, current, reason,
|
||||
reason_data, headers)
|
||||
|
||||
|
||||
class TrustRestAlarmNotifier(TrustAlarmNotifierMixin, 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 aodh service user to
|
||||
authenticate using the trust ID provided.
|
||||
|
||||
The URL must be in the form ``trust+http://trust-id@host/action``.
|
||||
"""
|
||||
|
@ -22,6 +22,7 @@ import six.moves.urllib.parse as urlparse
|
||||
from aodh.i18n import _LE, _LI
|
||||
from aodh import keystone_client
|
||||
from aodh import notifier
|
||||
from aodh.notifier import trust
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@ -144,7 +145,7 @@ class ZaqarAlarmNotifier(notifier.AlarmNotifier):
|
||||
'current': current, 'reason': reason,
|
||||
'reason_data': reason_data}
|
||||
message = dict(body=body)
|
||||
self.notify_zaqar(action, message)
|
||||
self.notify_zaqar(action, message, headers)
|
||||
|
||||
@property
|
||||
def client(self):
|
||||
@ -152,7 +153,7 @@ class ZaqarAlarmNotifier(notifier.AlarmNotifier):
|
||||
self._zclient = self.get_zaqar_client(self._get_client_conf())
|
||||
return self._zclient
|
||||
|
||||
def notify_zaqar(self, action, message):
|
||||
def notify_zaqar(self, action, message, headers=None):
|
||||
queue_info = urlparse.parse_qs(action.query)
|
||||
try:
|
||||
# NOTE(flwang): Try to get build a pre-signed client if user has
|
||||
@ -187,3 +188,41 @@ class ZaqarAlarmNotifier(notifier.AlarmNotifier):
|
||||
LOG.error(_LE("Unknown error occurred; Failed to post message to"
|
||||
" Zaqar queue"),
|
||||
exc_info=True)
|
||||
|
||||
|
||||
class TrustZaqarAlarmNotifier(trust.TrustAlarmNotifierMixin,
|
||||
ZaqarAlarmNotifier):
|
||||
"""Zaqar notifier using a Keystone trust to post to user-defined queues.
|
||||
|
||||
The URL must be in the form ``trust+zaqar://trust_id@?queue_name=example``.
|
||||
"""
|
||||
|
||||
def _get_client_conf(self, auth_token):
|
||||
return {
|
||||
'auth_opts': {
|
||||
'backend': 'keystone',
|
||||
'options': {
|
||||
'os_auth_token': auth_token,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def notify_zaqar(self, action, message, headers):
|
||||
queue_info = urlparse.parse_qs(action.query)
|
||||
try:
|
||||
queue_name = queue_info.get('queue_name')[-1]
|
||||
except IndexError:
|
||||
LOG.error(_LE("Required 'queue_name' query option missing in"
|
||||
" action %s"),
|
||||
action)
|
||||
return
|
||||
|
||||
try:
|
||||
conf = self._get_client_conf(headers['X-Auth-Token'])
|
||||
client = self.get_zaqar_client(conf)
|
||||
queue = client.queue(queue_name)
|
||||
queue.post(message)
|
||||
except Exception:
|
||||
LOG.error(_LE("Unknown error occurred; Failed to post message to"
|
||||
" Zaqar queue"),
|
||||
exc_info=True)
|
||||
|
@ -405,6 +405,21 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
self.assertEqual(1, self.zaqar.subscriptions)
|
||||
self.assertEqual(1, self.zaqar.posts)
|
||||
|
||||
def test_trust_zaqar_notifier_action(self):
|
||||
client = mock.MagicMock()
|
||||
client.session.auth.get_access.return_value.auth_token = 'token_1234'
|
||||
|
||||
self.useFixture(
|
||||
mockpatch.Patch('aodh.keystone_client.get_trusted_client',
|
||||
lambda *args: client))
|
||||
|
||||
action = 'trust+zaqar://trust-1234:delete@?queue_name=foobar-critical'
|
||||
self._msg_notifier.sample({}, 'alarm.update',
|
||||
self._notification(action))
|
||||
time.sleep(1)
|
||||
self.assertEqual(0, self.zaqar.subscriptions)
|
||||
self.assertEqual(1, self.zaqar.posts)
|
||||
|
||||
|
||||
class FakeZaqarClient(object):
|
||||
|
||||
|
@ -102,6 +102,7 @@ aodh.notifier =
|
||||
trust+http = aodh.notifier.trust:TrustRestAlarmNotifier
|
||||
trust+https = aodh.notifier.trust:TrustRestAlarmNotifier
|
||||
zaqar = aodh.notifier.zaqar:ZaqarAlarmNotifier
|
||||
trust+zaqar = aodh.notifier.zaqar:TrustZaqarAlarmNotifier
|
||||
|
||||
wsgi_scripts =
|
||||
aodh-api = aodh.api.app:build_wsgi_app
|
||||
|
Loading…
Reference in New Issue
Block a user