From 723dd4fe23e40a5f24e0f2a809a008623123aa87 Mon Sep 17 00:00:00 2001 From: Sundaresan Rajangam Date: Mon, 24 Oct 2016 18:52:50 -0700 Subject: [PATCH] Add support for <, > and range operators in alarm configuration Change-Id: I455fc40f8076ec56233c5a765e6302c4c9d3860b Closes-Bug: #1634293 --- src/config/api-server/vnc_cfg_types.py | 14 +++ src/opserver/alarmgen.py | 6 + src/opserver/test/test_alarm.py | 156 +++++++++++++++++++++++++ src/schema/alarm.xsd | 3 + 4 files changed, 179 insertions(+) diff --git a/src/config/api-server/vnc_cfg_types.py b/src/config/api-server/vnc_cfg_types.py index f22e5cfc300..94a4b0c9475 100644 --- a/src/config/api-server/vnc_cfg_types.py +++ b/src/config/api-server/vnc_cfg_types.py @@ -2139,6 +2139,20 @@ def _check_alarm_rules(cls, alarm_rules): except ValueError: return (False, (400, 'Invalid json_value %s ' 'specified in alarm_rules' % (json_val))) + if and_cond['operation'] == 'range': + if json_val is None: + return (False, (400, 'json_value not specified' + ' for "range" operation')) + val = json.loads(json_val) + if not (isinstance(val, list) and + len(val) == 2 and + isinstance(val[0], (int, long, float)) and + isinstance(val[1], (int, long, float)) and + val[0] < val[1]): + return (False, (400, 'Invalid json_value %s ' + 'for "range" operation. json_value should ' + 'be specified as "[x, y]", where x < y' % + (json_val))) else: return (False, (400, 'operand2 should have ' '"uve_attribute" or "json_value"')) diff --git a/src/opserver/alarmgen.py b/src/opserver/alarmgen.py index ea61451a474..d1de74726b9 100644 --- a/src/opserver/alarmgen.py +++ b/src/opserver/alarmgen.py @@ -355,8 +355,12 @@ def _compare_operand_vals(self, val1, val2, operation): return val1 == val2 elif operation == '!=': return val1 != val2 + elif operation == '<': + return val1 < val2 elif operation == '<=': return val1 <= val2 + elif operation == '>': + return val1 > val2 elif operation == '>=': return val1 >= val2 elif operation == 'in': @@ -367,6 +371,8 @@ def _compare_operand_vals(self, val1, val2, operation): if not isinstance(val2, list): return True return val1 not in val2 + elif operation == 'range': + return val2[0] <= val1 <= val2[1] elif operation == 'size==': if not isinstance(val1, list): return False diff --git a/src/opserver/test/test_alarm.py b/src/opserver/test/test_alarm.py index 9b79e2e7b5b..d84b0f752a3 100755 --- a/src/opserver/test/test_alarm.py +++ b/src/opserver/test/test_alarm.py @@ -1145,6 +1145,51 @@ def test_05_evaluate_uve_for_alarms(self): } ) + alarm_config13 = self.get_alarm_config_object( + { + 'name': 'alarm13', + 'uve_keys': ['key13'], + 'alarm_severity': AlarmBase.ALARM_MAJOR, + 'alarm_rules': { + 'or_list': [ + { + 'and_list': [ + { + 'operand1': 'A.B.C', + 'operation': '<', + 'operand2': { + 'uve_attribute': 'A.B.D' + } + }, + { + 'operand1': 'A.B.C', + 'operation': '>', + 'operand2': { + 'json_value': '100' + } + } + ] + }, + { + 'and_list': [ + { + 'operand1': 'A.B.C', + 'operation': 'range', + 'operand2': { + 'json_value': '[500, 1000]' + } + } + ] + } + ] + }, + 'kwargs': { + 'parent_type': 'global-system-config', + 'fq_name': ['global-syscfg-default', 'alarm13'] + } + } + ) + tests = [ TestCase(name='operand1 not present/null in UVE', input=TestInput(alarm_cfg=alarm_config1, @@ -2421,6 +2466,117 @@ def test_05_evaluate_uve_for_alarms(self): ] } ]) + ), + TestCase( + name='Test operation < and > - no condition match', + input=TestInput(alarm_cfg=alarm_config13, + uve_key='table13:host13', + uve={ + 'A': { + 'B': { + 'C': 5, + 'D': 5 + } + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='Test operation < and > - condition match', + input=TestInput(alarm_cfg=alarm_config13, + uve_key='table13:host13', + uve={ + 'A': { + 'B': { + 'C': 150, + 'D': 200 + } + } + } + ), + output=TestOutput(or_list=[ + { + 'and_list': [ + { + 'condition': { + 'operand1': 'A.B.C', + 'operand2': { + 'uve_attribute': 'A.B.D' + }, + 'operation': '<' + }, + 'match': [ + { + 'json_operand1_val': '150', + 'json_operand2_val': '200' + } + ] + }, + { + 'condition': { + 'operand1': 'A.B.C', + 'operand2': { + 'json_value': '100' + }, + 'operation': '>' + }, + 'match': [ + { + 'json_operand1_val': '150' + } + ] + } + ] + } + ]) + ), + TestCase( + name='Test range operation - no condition match', + input=TestInput(alarm_cfg=alarm_config13, + uve_key='table13:host13', + uve={ + 'A': { + 'B': { + 'C': 1500, + } + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='Test range operation - condition match', + input=TestInput(alarm_cfg=alarm_config13, + uve_key='table13:host13', + uve={ + 'A': { + 'B': { + 'C': 500, + } + } + } + ), + output=TestOutput(or_list=[ + { + 'and_list': [ + { + 'condition': { + 'operand1': 'A.B.C', + 'operand2': { + 'json_value': '[500, 1000]' + }, + 'operation': 'range' + }, + 'match': [ + { + 'json_operand1_val': '500' + } + ] + } + ] + } + ]) ) ] diff --git a/src/schema/alarm.xsd b/src/schema/alarm.xsd index 7314fd172ca..e50137c0605 100644 --- a/src/schema/alarm.xsd +++ b/src/schema/alarm.xsd @@ -8,10 +8,13 @@ + + +