Allow filtering alarms by severity

Add filter for alarm-list and alarm-count
Add validation of state and severity

Change-Id: I3eaaf4bb50aa0b7b51a3e357b4d465276823899d
This commit is contained in:
Ryan Brandt
2016-01-29 11:08:02 -07:00
parent 5e55919512
commit 85f4bd94c6
4 changed files with 103 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
# Copyright 2014-2016 Hewlett Packard Enterprise Development Company LP
# (C) Copyright 2014-2016 Hewlett Packard Enterprise Development Company LP
#
# 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
@@ -267,6 +267,10 @@ class AlarmsRepository(mysql_repository.MySQLRepository,
parms.append(query_parms['state'].encode('utf8'))
sub_query += " and a.state = %s "
if 'severity' in query_parms:
parms.append(query_parms['severity'].encode('utf8'))
sub_query += " and ad.severity = %s"
if 'lifecycle_state' in query_parms:
parms.append(query_parms['lifecycle_state'].encode('utf8'))
sub_query += " and a.lifecycle_state = %s"
@@ -413,6 +417,10 @@ class AlarmsRepository(mysql_repository.MySQLRepository,
parms.append(query_parms['state'].encode('utf8'))
where_clause += " and a.state = %s "
if 'severity' in query_parms:
parms.append(query_parms['severity'].encode('utf8'))
where_clause += " and ad.severity = %s "
if 'lifecycle_state' in query_parms:
parms.append(query_parms['lifecycle_state'].encode('utf8'))
where_clause += " and a.lifecycle_state = %s "

View File

@@ -1,4 +1,4 @@
# Copyright 2015,2016 Hewlett Packard Enterprise Development Company, L.P.
# (C) Copyright 2015,2016 Hewlett Packard Enterprise Development Company LP
#
# 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
@@ -19,6 +19,10 @@ import re
invalid_chars = "<>={}(),\"\\\\|;&"
restricted_chars = re.compile('[' + invalid_chars + ']')
VALID_ALARM_STATES = ["ALARM", "OK", "UNDETERMINED"]
VALID_ALARM_DEFINITION_SEVERITIES = ["LOW", "MEDIUM", "HIGH", "CRITICAL"]
def metric_name(name):
assert isinstance(name, (str, unicode)), "Metric name must be a string"
@@ -41,6 +45,20 @@ def dimension_value(value):
assert not restricted_chars.search(value), "Invalid characters in dimension value " + value
def validate_alarm_state(state):
if state not in VALID_ALARM_STATES:
raise HTTPUnprocessableEntityError("Invalid State",
"State {} must be one of {}".format(state.encode('utf8'),
VALID_ALARM_STATES))
def validate_alarm_definition_severity(severity):
if severity not in VALID_ALARM_DEFINITION_SEVERITIES:
raise HTTPUnprocessableEntityError("Invalid Severity",
"Severity {} must be one of {}".format(severity.encode('utf8'),
VALID_ALARM_DEFINITION_SEVERITIES))
def validate_sort_by(sort_by_list, allowed_sort_by):
for sort_by_field in sort_by_list:
sort_by_values = sort_by_field.split()

View File

@@ -117,6 +117,12 @@ class Alarms(alarms_api_v2.AlarmsV2API,
if alarm_id is None:
query_parms = falcon.uri.parse_query_string(req.query_string)
if 'state' in query_parms:
validation.validate_alarm_state(query_parms['state'])
if 'severity' in query_parms:
validation.validate_alarm_definition_severity(query_parms['severity'])
if 'sort_by' in query_parms:
if isinstance(query_parms['sort_by'], basestring):
query_parms['sort_by'] = [query_parms['sort_by']]
@@ -381,6 +387,13 @@ class AlarmsCount(alarms_api_v2.AlarmsCountV2API, alarming.Alarming):
helpers.validate_authorization(req, self._default_authorized_roles)
tenant_id = helpers.get_tenant_id(req)
query_parms = falcon.uri.parse_query_string(req.query_string)
if 'state' in query_parms:
validation.validate_alarm_state(query_parms['state'])
if 'severity' in query_parms:
validation.validate_alarm_definition_severity(query_parms['severity'])
if 'group_by' in query_parms:
if not isinstance(query_parms['group_by'], list):
query_parms['group_by'] = [query_parms['group_by']]

View File

@@ -109,7 +109,7 @@ class TestAlarms(base.BaseMonascaTest):
resp, response_body = self.monasca_client.create_metrics(metric)
self.assertEqual(204, resp.status)
self._waiting_for_alarms(1, alarm_def_id)
self._wait_for_alarms(1, alarm_def_id)
query_dimensions = [key + ':' + value for key, value in metric['dimensions'].items()]
query_parms="?metric_dimensions=" + ','.join(query_dimensions)
@@ -236,6 +236,62 @@ class TestAlarms(base.BaseMonascaTest):
self.assertEqual(200, resp.status)
self.assertEqual(len0, len1 + len2 + len3)
@test.attr(type="gate")
def test_list_alarms_by_severity(self):
metric_name = data_utils.rand_name("severity-metric")
alarm_defs = []
alarm_defs.append(helpers.create_alarm_definition(
name=data_utils.rand_name("alarm-severity"),
expression=metric_name + " > 12",
severity='LOW'
))
alarm_defs.append(helpers.create_alarm_definition(
name=data_utils.rand_name("alarm-severity"),
expression=metric_name + " > 12",
severity='MEDIUM'
))
alarm_defs.append(helpers.create_alarm_definition(
name=data_utils.rand_name("alarm-severity"),
expression=metric_name + " > 12",
severity='HIGH'
))
alarm_defs.append(helpers.create_alarm_definition(
name=data_utils.rand_name("alarm-severity"),
expression=metric_name + " > 12",
severity='CRITICAL'
))
alarm_def_ids = []
for definition in alarm_defs:
resp, response_body = self.monasca_client.create_alarm_definitions(definition)
self.assertEqual(201, resp.status)
alarm_def_ids.append(response_body['id'])
metric = helpers.create_metric(name=metric_name,
value=14)
resp, response_body = self.monasca_client.create_metrics(metric)
self.assertEqual(204, resp.status)
for def_id in alarm_def_ids:
self._wait_for_alarms(1, def_id)
query_parms = '?severity=LOW'
resp, response_body = self.monasca_client.list_alarms(query_parms)
self.assertEqual(200, resp.status)
for alarm in response_body['elements']:
self.assertEqual('LOW', alarm['alarm_definition']['severity'])
query_parms = '?severity=HIGH'
resp, response_body = self.monasca_client.list_alarms(query_parms)
self.assertEqual(200, resp.status)
for alarm in response_body['elements']:
self.assertEqual('HIGH', alarm['alarm_definition']['severity'])
query_parms = '?severity=CRITICAL'
resp, response_body = self.monasca_client.list_alarms(query_parms)
self.assertEqual(200, resp.status)
for alarm in response_body['elements']:
self.assertEqual('CRITICAL', alarm['alarm_definition']['severity'])
@test.attr(type="gate")
def test_list_alarms_by_lifecycle_state(self):
alarm_definition_ids, expected_metric \
@@ -408,7 +464,7 @@ class TestAlarms(base.BaseMonascaTest):
metric_2['timestamp'] = int(time.time() * 1000)
resp, response_body = self.monasca_client.create_metrics([metric_1, metric_2])
self.assertEqual(204, resp.status)
self._waiting_for_alarms(3, alarm_def_id)
self._wait_for_alarms(3, alarm_def_id)
resp, response_body = self.monasca_client.list_alarms('?alarm_definition_id=' + alarm_def_id)
self._verify_list_alarms_elements(resp, response_body,
@@ -677,7 +733,7 @@ class TestAlarms(base.BaseMonascaTest):
'hostname': 'devstack'})
self.monasca_client.create_metrics(metric1)
self.monasca_client.create_metrics(metric2)
self._waiting_for_alarms(num, alarm_definition_id)
self._wait_for_alarms(num, alarm_definition_id)
def _create_metrics_for_match_by_sub_expressions(self, num,
alarm_definition_id):
@@ -701,7 +757,7 @@ class TestAlarms(base.BaseMonascaTest):
'hostname': 'devstack'})
self.monasca_client.create_metrics(metric3)
self.monasca_client.create_metrics(metric4)
self._waiting_for_alarms(num, alarm_definition_id)
self._wait_for_alarms(num, alarm_definition_id)
def _create_metrics_for_match_by_sub_expressions_list(self, num,
alarm_definition_id):
@@ -730,9 +786,9 @@ class TestAlarms(base.BaseMonascaTest):
self.monasca_client.create_metrics(metric2)
self.monasca_client.create_metrics(metric3)
self.monasca_client.create_metrics(metric4)
self._waiting_for_alarms(num, alarm_definition_id)
self._wait_for_alarms(num, alarm_definition_id)
def _waiting_for_alarms(self, num, alarm_definition_id):
def _wait_for_alarms(self, num, alarm_definition_id):
query_param = '?alarm_definition_id=' + str(alarm_definition_id)
for i in xrange(constants.MAX_RETRIES):
time.sleep(constants.RETRY_WAIT_SECS)