diff --git a/aodhclient/tests/unit/test_alarm_cli.py b/aodhclient/tests/unit/test_alarm_cli.py index 3848eb4..7ff3dc6 100644 --- a/aodhclient/tests/unit/test_alarm_cli.py +++ b/aodhclient/tests/unit/test_alarm_cli.py @@ -113,6 +113,21 @@ class CliAlarmCreateTest(testtools.TestCase): 'gnocchi_aggregation_by_metrics_threshold requires ' '--metric, --threshold and --aggregation-method') + @mock.patch.object(argparse.ArgumentParser, 'error') + def test_validate_args_prometheus(self, mock_arg): + # Cover the test case of the method _validate_args for + # prometheus + parser = self.cli_alarm_create.get_parser('aodh alarm create') + test_parsed_args = parser.parse_args([ + '--name', 'prom_test', + '--type', 'prometheus', + '--comparison-operator', 'gt', + '--threshold', '666', + ]) + self.cli_alarm_create._validate_args(test_parsed_args) + mock_arg.assert_called_once_with( + 'Prometheus alarm requires --query and --threshold parameters.') + def test_alarm_from_args(self): # The test case to cover the method _alarm_from_args parser = self.cli_alarm_create.get_parser('aodh alarm create') @@ -179,6 +194,12 @@ class CliAlarmCreateTest(testtools.TestCase): 'type': '', 'value': 'fake-resource-id'}], 'threshold': 80.0}, + 'prometheus_rule': {'comparison_operator': 'le', + 'query': [{'field': 'resource', + 'op': 'eq', + 'type': '', + 'value': 'fake-resource-id'}], + 'threshold': 80.0}, 'gnocchi_resources_threshold_rule': { 'granularity': '60', 'metric': 'cpu', @@ -221,6 +242,24 @@ class CliAlarmCreateTest(testtools.TestCase): alarm_rep = self.cli_alarm_create._alarm_from_args(test_parsed_args) self.assertEqual(alarm, alarm_rep) + def test_alarm_from_args_for_prometheus(self): + # The test case to cover the method _alarm_from_args + parser = self.cli_alarm_create.get_parser('aodh alarm create') + test_parsed_args = parser.parse_args([ + '--name', 'alarm_prom', + '--type', 'prometheus', + '--comparison-operator', 'gt', + '--threshold', '666', + '--query', r'some_metric{some_label="some_value"}' + ]) + + prom_rule = {'comparison_operator': 'gt', + 'query': r'some_metric{some_label="some_value"}', + 'threshold': 666.0} + + alarm_rep = self.cli_alarm_create._alarm_from_args(test_parsed_args) + self.assertEqual(prom_rule, alarm_rep['prometheus_rule']) + def test_validate_time_constraint(self): starts = ['0 11 * * *', ' 0 11 * * * ', '"0 11 * * *"', '\'0 11 * * *\''] diff --git a/aodhclient/v2/alarm.py b/aodhclient/v2/alarm.py index 1e3dc7d..ac9f274 100644 --- a/aodhclient/v2/alarm.py +++ b/aodhclient/v2/alarm.py @@ -115,7 +115,11 @@ class AlarmManager(base.Manager): else: self._clean_rules(alarm_update['type'], alarm_update) - if 'threshold_rule' in alarm_update: + if 'prometheus_rule' in alarm_update: + rule = alarm_update.get('prometheus_rule') + alarm['prometheus_rule'].update(rule) + alarm_update.pop('prometheus_rule') + elif 'threshold_rule' in alarm_update: alarm['threshold_rule'].update(alarm_update.get('threshold_rule')) alarm_update.pop('threshold_rule') elif 'event_rule' in alarm_update: diff --git a/aodhclient/v2/alarm_cli.py b/aodhclient/v2/alarm_cli.py index 162279b..a6d0f6a 100644 --- a/aodhclient/v2/alarm_cli.py +++ b/aodhclient/v2/alarm_cli.py @@ -24,7 +24,7 @@ from aodhclient import exceptions from aodhclient.i18n import _ from aodhclient import utils -ALARM_TYPES = ['event', 'composite', 'threshold', +ALARM_TYPES = ['prometheus', 'event', 'composite', 'threshold', 'gnocchi_resources_threshold', 'gnocchi_aggregation_by_metrics_threshold', 'gnocchi_aggregation_by_resources_threshold', @@ -271,7 +271,9 @@ class CliAlarmCreate(show.ShowOne): 'For alarms of ' 'type gnocchi_aggregation_by_resources_threshold: ' 'need to specify a complex query json string, like:' - ' {"and": [{"=": {"ended_at": null}}, ...]}.') + ' {"and": [{"=": {"ended_at": null}}, ...]}. ' + 'For alarms of type prometheus this should be valid ' + 'PromQL query.') common_group.add_argument( '--comparison-operator', metavar='', dest='comparison_operator', choices=ALARM_OPERATORS, @@ -424,6 +426,10 @@ class CliAlarmCreate(show.ShowOne): self.parser.error('Loadbalancer member health alarm requires' '--stack-id, --pool-id and' '--autoscaling-group-id') + elif (parsed_args.type == 'prometheus' and + not (parsed_args.query and parsed_args.threshold)): + self.parser.error('Prometheus alarm requires --query and ' + '--threshold parameters.') def _alarm_from_args(self, parsed_args): alarm = utils.dict_from_parsed_args( @@ -440,6 +446,10 @@ class CliAlarmCreate(show.ShowOne): 'query']) alarm['event_rule'] = utils.dict_from_parsed_args( parsed_args, ['event_type', 'query']) + alarm['prometheus_rule'] = ( + utils.dict_from_parsed_args(parsed_args, + ['comparison_operator', 'threshold', + 'query'])) alarm['gnocchi_resources_threshold_rule'] = ( utils.dict_from_parsed_args(parsed_args, ['granularity', 'comparison_operator',