From b59b7be69f298c70b368b15ed6b10554d930c834 Mon Sep 17 00:00:00 2001 From: Sundaresan Rajangam Date: Thu, 18 Aug 2016 14:53:13 -0700 Subject: [PATCH] Support for configuring alarm for a specific object Presently, the uve_keys field in the alarm schema takes only list of uve-types. This patch adds support for specifying uve objects in addition to uve-types in the uve-keys. uve object can be specified in the format : Change-Id: I7e25d49a206c289dd5ada1d6145cbc7255878afe Closes-Bug: #1606187 --- src/opserver/alarmgen.py | 41 +++++++++++-------- src/opserver/alarmgen_config_handler.py | 19 +++++---- .../test/test_alarmgen_config_handler.py | 38 ++++++++++++++++- src/schema/alarm.xsd | 2 +- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/opserver/alarmgen.py b/src/opserver/alarmgen.py index 29194b17cb0..eceee2064ee 100644 --- a/src/opserver/alarmgen.py +++ b/src/opserver/alarmgen.py @@ -1368,15 +1368,18 @@ def run_uve_processing(self): def examine_uve_for_alarms(self, uve_key, uve): table = uve_key.split(':', 1)[0] alarm_cfg = self._config_handler.alarm_config_db() - if not alarm_cfg.has_key(table): - new_uve_alarms = {} - else: - prevt = UTCTimestampUsec() - aproc = AlarmProcessor(self._logger) - for alarm_fqname, alarm_obj in alarm_cfg[table].iteritems(): - aproc.process_alarms(alarm_fqname, alarm_obj, uve_key, uve) - new_uve_alarms = aproc.uve_alarms - self.tab_perf[table].record_call(UTCTimestampUsec() - prevt) + prevt = UTCTimestampUsec() + aproc = AlarmProcessor(self._logger) + # Process all alarms configured for this uve-type + for alarm_fqname, alarm_obj in \ + alarm_cfg.get(table, {}).iteritems(): + aproc.process_alarms(alarm_fqname, alarm_obj, uve_key, uve) + # Process all alarms configured for this uve-key + for alarm_fqname, alarm_obj in \ + alarm_cfg.get(uve_key, {}).iteritems(): + aproc.process_alarms(alarm_fqname, alarm_obj, uve_key, uve) + new_uve_alarms = aproc.uve_alarms + self.tab_perf[table].record_call(UTCTimestampUsec() - prevt) del_types = [] if not self.tab_alarms.has_key(table): @@ -1431,18 +1434,24 @@ def alarm_config_change_worker(self, partition, alarm_config_change_map): self._logger.debug('Alarm config change worker for partition %d' % (partition)) try: - for table, alarm_map in alarm_config_change_map.iteritems(): + for uve_key, alarm_map in alarm_config_change_map.iteritems(): self._logger.debug('Handle alarm config change for ' - '[partition:table:{alarms}] -> [%d:%s:%s]' % - (partition, table, str(alarm_map))) + '[partition:uve_key:{alarms}] -> [%d:%s:%s]' % + (partition, uve_key, str(alarm_map))) + uve_type_name = uve_key.split(':', 1) try: - uves = self.ptab_info[partition][table] + if len(uve_type_name) == 1: + uves = self.ptab_info[partition][uve_type_name[0]] + else: + uve = self.ptab_info[partition][uve_type_name[0]]\ + [uve_type_name[1]] + uves = {uve_type_name[1]: uve} except KeyError: continue else: - for uve, data in uves.iteritems(): - self._logger.debug('process alarm for uve %s' % (uve)) - self.examine_uve_for_alarms(table+':'+uve, + for name, data in uves.iteritems(): + self._logger.debug('process alarm for uve %s' % (name)) + self.examine_uve_for_alarms(uve_type_name[0]+':'+name, data.values()) gevent.sleep(0) except Exception as e: diff --git a/src/opserver/alarmgen_config_handler.py b/src/opserver/alarmgen_config_handler.py index 83f3e7d46ed..4c7b148d2ac 100644 --- a/src/opserver/alarmgen_config_handler.py +++ b/src/opserver/alarmgen_config_handler.py @@ -49,18 +49,23 @@ def _update_alarm_config_table(self, alarm_fqname, alarm_obj, uve_keys, operation): alarm_config_change_map = {} for key in uve_keys: + uve_type_name = key.split(':', 1) try: - table = UVE_MAP[key] + table = UVE_MAP[uve_type_name[0]] except KeyError: - self._logger('Invalid table name "%s" specified in ' + self._logger('Invalid uve_key "%s" specified in ' 'alarm config "%s"' % (key, alarm_fqname), SandeshLevel.SYS_ERR) else: + if len(uve_type_name) == 2: + uve_key = table+':'+uve_type_name[1] + else: + uve_key = table try: - alarm_table = self._alarm_config_db[table] + alarm_table = self._alarm_config_db[uve_key] except KeyError: - self._alarm_config_db[table] = {} - alarm_table = self._alarm_config_db[table] + self._alarm_config_db[uve_key] = {} + alarm_table = self._alarm_config_db[uve_key] finally: if operation == 'CREATE' or operation == 'UPDATE': if not isinstance(alarm_obj, AlarmBase): @@ -75,10 +80,10 @@ def _update_alarm_config_table(self, alarm_fqname, alarm_obj, uve_keys, if alarm_table.has_key(alarm_fqname): del alarm_table[alarm_fqname] if not len(alarm_table): - del self._alarm_config_db[table] + del self._alarm_config_db[uve_key] else: assert(0) - alarm_config_change_map[table] = {alarm_fqname:operation} + alarm_config_change_map[uve_key] = {alarm_fqname:operation} return alarm_config_change_map # end _update_alarm_config_table diff --git a/src/opserver/test/test_alarmgen_config_handler.py b/src/opserver/test/test_alarmgen_config_handler.py index 1c914b13dbd..1e5be0513d5 100644 --- a/src/opserver/test/test_alarmgen_config_handler.py +++ b/src/opserver/test/test_alarmgen_config_handler.py @@ -78,7 +78,8 @@ def test_handle_config_update(self): alarm_config1 = self._get_config_object('alarm', { 'name': 'alarm1', - 'uve_keys': ['analytics-node', 'control-node'], + 'uve_keys': ['analytics-node', 'control-node', + 'vrouter:host1'], 'alarm_severity': AlarmBase.ALARM_CRITICAL, 'alarm_rules': { 'or_list': [ @@ -102,7 +103,8 @@ def test_handle_config_update(self): alarm_config1_1 = self._get_config_object('alarm', { 'name': 'alarm1', - 'uve_keys': ['invalid', 'control-node', 'config-node'], + 'uve_keys': ['invalid', 'control-node', 'config-node', + 'vrouter:host2'], 'alarm_severity': AlarmBase.ALARM_CRITICAL, 'alarm_rules': { 'or_list': [ @@ -240,6 +242,10 @@ def test_handle_config_update(self): 'ObjectBgpRouter': { 'global-syscfg-default:alarm1': AlarmBase(config=alarm_config1) + }, + 'ObjectVRouter:host1': { + 'global-syscfg-default:alarm1': + AlarmBase(config=alarm_config1) } }, alarm_config_change_map={ @@ -248,6 +254,9 @@ def test_handle_config_update(self): }, 'ObjectBgpRouter': { 'global-syscfg-default:alarm1': 'CREATE' + }, + 'ObjectVRouter:host1': { + 'global-syscfg-default:alarm1': 'CREATE' } } ) @@ -278,6 +287,10 @@ def test_handle_config_update(self): 'ObjectConfigNode': { 'global-syscfg-default:alarm1': AlarmBase(config=alarm_config1_1) + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': + AlarmBase(config=alarm_config1_1) } }, alarm_config_change_map={ @@ -289,6 +302,12 @@ def test_handle_config_update(self): }, 'ObjectConfigNode': { 'global-syscfg-default:alarm1': 'CREATE' + }, + 'ObjectVRouter:host1': { + 'global-syscfg-default:alarm1': 'DELETE' + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': 'CREATE' } } ) @@ -324,6 +343,10 @@ def test_handle_config_update(self): 'ObjectVNTable': { 'default-domain:admin:alarm1': AlarmBase(config=alarm_config2) + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': + AlarmBase(config=alarm_config1_1) } }, alarm_config_change_map={ @@ -367,6 +390,10 @@ def test_handle_config_update(self): AlarmBase(config=alarm_config2), 'default-domain:demo:alarm1': AlarmBase(config=alarm_config3) + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': + AlarmBase(config=alarm_config1_1) } }, alarm_config_change_map={ @@ -409,6 +436,10 @@ def test_handle_config_update(self): AlarmBase(config=alarm_config2_1), 'default-domain:demo:alarm1': AlarmBase(config=alarm_config3) + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': + AlarmBase(config=alarm_config1_1) } }, alarm_config_change_map={ @@ -450,6 +481,9 @@ def test_handle_config_update(self): }, 'ObjectConfigNode': { 'global-syscfg-default:alarm1': 'DELETE' + }, + 'ObjectVRouter:host2': { + 'global-syscfg-default:alarm1': 'DELETE' } } ) diff --git a/src/schema/alarm.xsd b/src/schema/alarm.xsd index 8dba00fe246..7314fd172ca 100644 --- a/src/schema/alarm.xsd +++ b/src/schema/alarm.xsd @@ -78,7 +78,7 @@ + 'List of UVE tables or UVE objects where this alarm config should be applied. For example, rules based on NodeStatus UVE can be applied to multiple object types or specific uve objects such as analytics-node, config-node, control-node:, etc.,') -->