Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 7a5cbc1

Browse files
author
Eoghan Glynn
committed
Avoid reset of repeat_actions attribute on alarm update
Fixes bug 1253057 Previously, when an unrelated alarm attribute was updated via the CLI, the repeat_actions attribute was also set to False as an unwanted side-effect. Now, we only set this attribute in the update call if explicitly specified as a CLI arg. Otherwise the value provided in the PUT request body reflects the pre-existing value for this attribute. Change-Id: I94468ff649dd4367848c74e94a3feb08494bb223
1 parent 8bf894f commit 7a5cbc1

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

ceilometerclient/tests/v2/test_shell.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,73 @@ def test_alarm_constrained_history(self):
138138
parsed_query=parsed_query)
139139

140140

141+
class ShellAlarmCommandTest(utils.BaseTestCase):
142+
143+
ALARM_ID = '768ff714-8cfb-4db9-9753-d484cb33a1cc'
144+
ALARM = {"alarm_actions": ["log://"],
145+
"ok_actions": [],
146+
"description": "instance running hot",
147+
"timestamp": "2013-11-20T10:38:42.206952",
148+
"enabled": True,
149+
"state_timestamp": "2013-11-19T17:20:44",
150+
"threshold_rule": {"meter_name": "cpu_util",
151+
"evaluation_periods": 3,
152+
"period": 600,
153+
"statistic": "avg",
154+
"threshold": 99.0,
155+
"query": [{"field": "resource_id",
156+
"value": "INSTANCE_ID",
157+
"op": "eq"}],
158+
"comparison_operator": "gt"},
159+
"alarm_id": ALARM_ID,
160+
"state": "insufficient data",
161+
"insufficient_data_actions": [],
162+
"repeat_actions": True,
163+
"user_id": "528d9b68fa774689834b5c04b4564f8a",
164+
"project_id": "ed9d4e2be2a748bc80108053cf4598f5",
165+
"type": "threshold",
166+
"name": "cpu_high"}
167+
168+
def setUp(self):
169+
super(ShellAlarmCommandTest, self).setUp()
170+
self.cc = mock.Mock()
171+
self.cc.alarms = mock.Mock()
172+
self.args = mock.Mock()
173+
self.args.alarm_id = self.ALARM_ID
174+
175+
def _do_test_alarm_update_repeat_actions(self, repeat_actions):
176+
self.args.threshold = 42.0
177+
if repeat_actions is not None:
178+
self.args.repeat_actions = repeat_actions
179+
orig = sys.stdout
180+
sys.stdout = six.StringIO()
181+
alarm = [alarms.Alarm(mock.Mock(), self.ALARM)]
182+
self.cc.alarms.get.return_value = alarm
183+
self.cc.alarms.update.return_value = alarm[0]
184+
185+
try:
186+
ceilometer_shell.do_alarm_update(self.cc, self.args)
187+
args, kwargs = self.cc.alarms.update.call_args
188+
self.assertEqual(self.ALARM_ID, args[0])
189+
self.assertEqual(42.0, kwargs.get('threshold'))
190+
if repeat_actions is not None:
191+
self.assertEqual(repeat_actions, kwargs.get('repeat_actions'))
192+
else:
193+
self.assertFalse('repeat_actions' in kwargs)
194+
finally:
195+
sys.stdout.close()
196+
sys.stdout = orig
197+
198+
def test_alarm_update_repeat_actions_untouched(self):
199+
self._do_test_alarm_update_repeat_actions(None)
200+
201+
def test_alarm_update_repeat_actions_set(self):
202+
self._do_test_alarm_update_repeat_actions(True)
203+
204+
def test_alarm_update_repeat_actions_clear(self):
205+
self._do_test_alarm_update_repeat_actions(False)
206+
207+
141208
class ShellSampleListCommandTest(utils.BaseTestCase):
142209

143210
METER = 'cpu_util'

ceilometerclient/v2/shell.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,6 @@ def _wrapper(func):
267267
metavar='<Webhook URL>', action='append', default=None,
268268
help=('URL to invoke when state transitions to unkown. '
269269
'May be used multiple times.'))
270-
@utils.arg('--repeat-actions', dest='repeat_actions',
271-
metavar='{True|False}', type=utils.string_to_bool,
272-
default=False,
273-
help=('True if actions should be repeatedly notified '
274-
'while alarm remains in target state'))
275270
@functools.wraps(func)
276271
def _wrapped(*args, **kwargs):
277272
return func(*args, **kwargs)
@@ -296,6 +291,11 @@ def _wrapped(*args, **kwargs):
296291
metavar='<Matching Metadata>', action='append', default=None,
297292
help=('A meter should match this resource metadata (key=value) '
298293
'additionally to the meter_name'))
294+
@utils.arg('--repeat-actions', dest='repeat_actions',
295+
metavar='{True|False}', type=utils.string_to_bool,
296+
default=False,
297+
help=('True if actions should be repeatedly notified '
298+
'while alarm remains in target state'))
299299
def do_alarm_create(cc, args={}):
300300
'''Create a new alarm (Deprecated).'''
301301
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
@@ -327,6 +327,11 @@ def do_alarm_create(cc, args={}):
327327
dest='threshold_rule/query',
328328
help='The query to find the data for computing statistics '
329329
'(key[op]value; list.)')
330+
@utils.arg('--repeat-actions', dest='repeat_actions',
331+
metavar='{True|False}', type=utils.string_to_bool,
332+
default=False,
333+
help=('True if actions should be repeatedly notified '
334+
'while alarm remains in target state'))
330335
def do_alarm_threshold_create(cc, args={}):
331336
'''Create a new alarm based on computed statistics.'''
332337
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
@@ -347,6 +352,11 @@ def do_alarm_threshold_create(cc, args={}):
347352
dest='combination_rule/operator',
348353
help='Operator to compare with, one of: ' + str(
349354
ALARM_COMBINATION_OPERATORS))
355+
@utils.arg('--repeat-actions', dest='repeat_actions',
356+
metavar='{True|False}', type=utils.string_to_bool,
357+
default=False,
358+
help=('True if actions should be repeatedly notified '
359+
'while alarm remains in target state'))
350360
def do_alarm_combination_create(cc, args={}):
351361
'''Create a new alarm based on state of other alarms.'''
352362
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
@@ -375,6 +385,10 @@ def do_alarm_combination_create(cc, args={}):
375385
metavar='<Matching Metadata>', action='append', default=None,
376386
help=('A meter should match this resource metadata (key=value) '
377387
'additionally to the meter_name'))
388+
@utils.arg('--repeat-actions', dest='repeat_actions',
389+
metavar='{True|False}', type=utils.string_to_bool,
390+
help=('True if actions should be repeatedly notified '
391+
'while alarm remains in target state'))
378392
def do_alarm_update(cc, args={}):
379393
'''Update an existing alarm.'''
380394
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
@@ -412,6 +426,10 @@ def do_alarm_update(cc, args={}):
412426
dest='threshold_rule/query',
413427
help='The query to find the data for computing statistics '
414428
'(key[op]value; list.)')
429+
@utils.arg('--repeat-actions', dest='repeat_actions',
430+
metavar='{True|False}', type=utils.string_to_bool,
431+
help=('True if actions should be repeatedly notified '
432+
'while alarm remains in target state'))
415433
def do_alarm_threshold_update(cc, args={}):
416434
'''Update an existing alarm based on computed statistics.'''
417435
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
@@ -438,6 +456,10 @@ def do_alarm_threshold_update(cc, args={}):
438456
dest='combination_rule/operator',
439457
help='Operator to compare with, one of: ' + str(
440458
ALARM_COMBINATION_OPERATORS))
459+
@utils.arg('--repeat-actions', dest='repeat_actions',
460+
metavar='{True|False}', type=utils.string_to_bool,
461+
help=('True if actions should be repeatedly notified '
462+
'while alarm remains in target state'))
441463
def do_alarm_combination_update(cc, args={}):
442464
'''Update an existing alarm based on state of other alarms.'''
443465
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))

0 commit comments

Comments
 (0)