Use user_id/project_id from service_credentials in alarm_change

Like recording alarm history in aodh-api when update alarm. the user_id
and project_id is the operator credential, we need to spedify the user_id
and project from service_credentials when evaluator update alarm.

Change-Id: I8a96ab4f39b522d6ed52a9c6ea095182869775fd
This commit is contained in:
liu-sheng 2015-07-27 12:41:59 +08:00
parent 61717e7a8d
commit 469860fca4
5 changed files with 67 additions and 18 deletions

View File

@ -34,6 +34,7 @@ import uuid
import aodh
from aodh import coordination
from aodh.i18n import _
from aodh import keystone_client
from aodh import messaging
from aodh import rpc
from aodh import storage
@ -65,6 +66,13 @@ class Evaluator(object):
self.conf = conf
self.notifier = notifier
self.storage_conn = None
self._ks_client = None
@property
def ks_client(self):
if self._ks_client is None:
self._ks_client = keystone_client.get_client(self.conf)
return self._ks_client
@property
def _storage_conn(self):
@ -77,10 +85,7 @@ class Evaluator(object):
return
type = models.AlarmChange.STATE_TRANSITION
detail = json.dumps({'state': alarm.state})
# TODO(liusheng) the user_id and project_id should be
# specify than None?
user_id = None
project_id = None
user_id, project_id = self.ks_client.user_id, self.ks_client.project_id
on_behalf_of = alarm.project_id
now = timeutils.utcnow()
payload = dict(event_id=str(uuid.uuid4()),

View File

@ -20,7 +20,6 @@ import requests
from aodh.evaluator import threshold
from aodh.i18n import _
from aodh import keystone_client
LOG = log.getLogger(__name__)
@ -39,13 +38,6 @@ class GnocchiThresholdEvaluator(threshold.ThresholdEvaluator):
def __init__(self, conf, notifier):
super(threshold.ThresholdEvaluator, self).__init__(conf, notifier)
self.gnocchi_url = cfg.CONF.gnocchi_url
self._ks_client = None
@property
def ks_client(self):
if self._ks_client is None:
self._ks_client = keystone_client.get_client(cfg.CONF)
return self._ks_client
def _get_headers(self, content_type="application/json"):
return {

View File

@ -26,6 +26,9 @@ class TestEvaluatorBase(base.BaseTestCase):
self.evaluator = self.EVALUATOR(self.conf, self.notifier)
self.storage_conn = mock.MagicMock()
self.evaluator.storage_conn = self.storage_conn
self.evaluator._ks_client = mock.Mock(user_id='fake_user_id',
project_id='fake_project_id',
auth_token='fake_token')
self.prepare_alarms()
@staticmethod

View File

@ -45,12 +45,6 @@ class TestGnocchiThresholdEvaluate(base.TestEvaluatorBase):
EVALUATOR = gnocchi.GnocchiThresholdEvaluator
def setUp(self):
ks_client = mock.Mock(auth_token='fake_token')
ks_client.users.find.return_value = 'gnocchi'
self.useFixture(mockpatch.Patch(
'keystoneclient.v2_0.client.Client',
return_value=ks_client))
super(TestGnocchiThresholdEvaluate, self).setUp()
self.useFixture(mockpatch.Patch('ceilometerclient.client.get_client',

View File

@ -15,6 +15,7 @@
"""Tests for aodh/evaluator/threshold.py
"""
import datetime
import json
import uuid
from ceilometerclient import exc
@ -25,6 +26,7 @@ import pytz
from six import moves
from aodh.evaluator import threshold
from aodh import messaging
from aodh.storage import models
from aodh.tests import constants
from aodh.tests.evaluator import base
@ -223,6 +225,59 @@ class TestEvaluate(base.TestEvaluatorBase):
in zip(self.alarms, reasons, reason_datas)]
self.assertEqual(expected, self.notifier.notify.call_args_list)
def _construct_payloads(self):
payloads = []
for alarm in self.alarms:
type = models.AlarmChange.STATE_TRANSITION
detail = json.dumps({'state': alarm.state})
on_behalf_of = alarm.project_id
payload = dict(
event_id='fake_event_id_%s' % self.alarms.index(alarm),
alarm_id=alarm.alarm_id,
type=type,
detail=detail,
user_id='fake_user_id',
project_id='fake_project_id',
on_behalf_of=on_behalf_of,
timestamp=datetime.datetime(2015, 7, 26, 3, 33, 21, 876795))
payloads.append(payload)
return payloads
@mock.patch.object(uuid, 'uuid4')
@mock.patch.object(timeutils, 'utcnow')
@mock.patch.object(messaging, 'get_notifier')
def test_alarm_change_record(self, get_notifier, utcnow, mock_uuid):
# the context.RequestContext() method need to generate uuid,
# so we need to provide 'fake_uuid_0' and 'fake_uuid_1' for that.
mock_uuid.side_effect = ['fake_event_id_0', 'fake_uuid_0',
'fake_event_id_1', 'fake_uuid_1']
change_notifier = mock.MagicMock()
get_notifier.return_value = change_notifier
utcnow.return_value = datetime.datetime(2015, 7, 26, 3, 33, 21, 876795)
self._set_all_alarms('ok')
with mock.patch('ceilometerclient.client.get_client',
return_value=self.api_client):
avgs = [self._get_stat('avg', self.alarms[0].rule['threshold'] + v)
for v in moves.xrange(1, 6)]
maxs = [self._get_stat('max', self.alarms[1].rule['threshold'] - v)
for v in moves.xrange(4)]
self.api_client.statistics.list.side_effect = [avgs, maxs]
self._evaluate_all_alarms()
self._assert_all_alarms('alarm')
expected = [mock.call(alarm) for alarm in self.alarms]
update_calls = self.storage_conn.update_alarm.call_args_list
self.assertEqual(expected, update_calls)
payloads = self._construct_payloads()
expected_payloads = [mock.call(p) for p in payloads]
change_records = \
self.storage_conn.record_alarm_change.call_args_list
self.assertEqual(expected_payloads, change_records)
notify_calls = change_notifier.info.call_args_list
notification = "alarm.state_transition"
expected_payloads = [mock.call(mock.ANY, notification, p)
for p in payloads]
self.assertEqual(expected_payloads, notify_calls)
def test_equivocal_from_known_state(self):
self._set_all_alarms('ok')
with mock.patch('ceilometerclient.client.get_client',