diff --git a/src/base/sandesh/process_info.sandesh b/src/base/sandesh/process_info.sandesh index e4e6064b996..970d0ca6503 100644 --- a/src/base/sandesh/process_info.sandesh +++ b/src/base/sandesh/process_info.sandesh @@ -95,6 +95,7 @@ struct DiskPartitionUsageStats { 2: string partition_name 3: u64 partition_space_used_1k 4: u64 partition_space_available_1k + 5: u16 percentage_partition_space_used } // Sent by the node manager diff --git a/src/nodemgr/common/event_manager.py b/src/nodemgr/common/event_manager.py index 2abb7ddd625..6ff41b22c46 100644 --- a/src/nodemgr/common/event_manager.py +++ b/src/nodemgr/common/event_manager.py @@ -377,6 +377,12 @@ def send_disk_usage_info_base(self, NodeStatusUVE, NodeStatus, int(partition_space_used_1k) disk_usage_stat.partition_space_available_1k = \ int(partition_space_available_1k) + total_disk_space = \ + disk_usage_stat.partition_space_used_1k + \ + disk_usage_stat.partition_space_available_1k + disk_usage_stat.percentage_partition_space_used = \ + int(round((float(disk_usage_stat.partition_space_used_1k)/ \ + float(total_disk_space))*100)) except ValueError: sys.stderr.write("Failed to get local disk space usage" + "\n") else: diff --git a/src/opserver/alarmgen.py b/src/opserver/alarmgen.py index 5aa414eedb6..db3d29b95a2 100644 --- a/src/opserver/alarmgen.py +++ b/src/opserver/alarmgen.py @@ -216,17 +216,16 @@ def process_alarms(self, ext, uv, local_uve): or_list = ext.obj.__call__(uv, local_uve) self._logger.debug("Alarm[%s] %s: %s" % (uv, nm, str(or_list))) if or_list: - self.uve_alarms[nm] = UVEAlarmInfo(type = nm, severity = sev, - timestamp = 0, token = "", - any_of = or_list, ack = False) + self.uve_alarms[nm] = UVEAlarmInfo(type=nm, severity=sev, + timestamp=0, token="", + rules=or_list, ack=False) except Exception as ex: template = "Exception {0} in Alarm Processing. Arguments:\n{1!r}" messag = template.format(type(ex).__name__, ex.args) self._logger.error("%s : traceback %s" % \ (messag, traceback.format_exc())) - self.uve_alarms[nm] = UVEAlarmInfo(type = nm, severity = sev, - timestamp = 0, token = "", - any_of = [AllOf(all_of=[])], ack = False) + self.uve_alarms[nm] = UVEAlarmInfo(type=nm, severity=sev, + timestamp=0, token="", rules=[], ack=False) class AlarmStateMachine: tab_alarms_timer = {} diff --git a/src/opserver/plugins/alarm_address_mismatch/main.py b/src/opserver/plugins/alarm_address_mismatch/main.py index 58864ad3c73..a0468b0bd5d 100644 --- a/src/opserver/plugins/alarm_address_mismatch/main.py +++ b/src/opserver/plugins/alarm_address_mismatch/main.py @@ -11,76 +11,56 @@ def __init__(self): def __call__(self, uve_key, uve_data): or_list = [] - and_list = [] - trigger = True - - if trigger: - if "ContrailConfig" not in uve_data: - trigger = False - else: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["ContrailConfig"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) - - try: - uattr = uve_data["ContrailConfig"]["elements"] - if isinstance(uattr,list): - uattr = uattr[0][0] - lval = json.loads(uattr["virtual_router_ip_address"]) - except KeyError: - lval = None - - if trigger: - if "VrouterAgent" not in uve_data: - trigger = False - else: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["VrouterAgent"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) - - if trigger: - try: - rval1 = uve_data["VrouterAgent"]["self_ip_list"] - except KeyError: - rval1 = None - - if not isinstance(rval1,list) or lval not in rval1: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="not in", - operand1=Operand1(keys=\ - ["ContrailConfig","elements","virtual_router_ip_address"], - json=2), - operand2=Operand2(keys=["VrouterAgent","self_ip_list"])), - json_operand1_value=json.dumps(lval), - json_operand2_value=json.dumps(rval1))) - else: - trigger = False - - if trigger: + + if "ContrailConfig" not in uve_data: + return None + + try: + uattr = uve_data["ContrailConfig"]["elements"] + except KeyError: + return None + else: try: - rval2 = uve_data["VrouterAgent"]["control_ip"] + lval = json.loads(uattr["virtual_router_ip_address"]) except KeyError: - rval2 = None - - if lval != rval2: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=\ - ["ContrailConfig","elements", - "virtual_router_ip_address"], - json=2), - operand2=Operand2(keys=["VrouterAgent","control_ip"])), - json_operand1_value=json.dumps(lval), - json_operand2_value=json.dumps(rval2))) - else: - trigger = False - - if trigger: - or_list.append(AllOf(all_of=and_list)) + lval = None + + if "VrouterAgent" not in uve_data: + return None + + try: + rval1 = uve_data["VrouterAgent"]["self_ip_list"] + except KeyError: + rval1 = None + + if not isinstance(rval1,list) or lval not in rval1: + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="not in", + operand1="ContrailConfig.elements." + \ + "virtual_router_ip_address", + operand2="VrouterAgent.self_ip_list"), + match=[AlarmMatch(json_operand1_value=json.dumps(lval), + json_operand2_value=json.dumps(rval1))])) + or_list.append(AlarmRuleMatch(rule=and_list)) + + try: + rval2 = uve_data["VrouterAgent"]["control_ip"] + except KeyError: + rval2 = None + + if lval != rval2: + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="ContrailConfig.elements." + \ + "virtual_router_ip_address", + operand2="VrouterAgent.control_ip"), + match=[AlarmMatch(json_operand1_value=json.dumps(lval), + json_operand2_value=json.dumps(rval2))])) + or_list.append(AlarmRuleMatch(rule=and_list)) + + if len(or_list): return or_list else: return None @@ -93,17 +73,21 @@ def __init__(self): AlarmBase.__init__(self, AlarmBase.SYS_ERR) def __call__(self, uve_key, uve_data): + or_list = [] if "ContrailConfig" not in uve_data: return None try: uattr = uve_data["ContrailConfig"]["elements"] - if isinstance(uattr,list): - uattr = uattr[0][0] - lval = json.loads(uattr["bgp_router_parameters"])["address"] + bgp_router_param = uattr["bgp_router_parameters"] except KeyError: - lval = None + return None + else: + try: + lval = json.loads(bgp_router_param)["address"] + except KeyError: + lval = None if "BgpRouterState" not in uve_data: return None @@ -113,17 +97,18 @@ def __call__(self, uve_key, uve_data): except KeyError: rval = None - and_list = [] if not isinstance(rval,list) or lval not in rval: - and_list.append(AnyOf(any_of=[AlarmElement(\ - rule=AlarmTemplate(oper="not in", - operand1=Operand1(keys=["ContrailConfig",\ - "elements","bgp_router_parameters","address"], - json=2), - operand2=Operand2(keys=\ - ["BgpRouterState","bgp_router_ip_list"])), - json_operand1_value=json.dumps(lval), - json_operand2_value=json.dumps(rval))])) - return and_list + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="not in", + operand1="ContrailConfig.elements." + \ + "bgp_router_parameters.address", + operand2="BgpRouterState.bgp_router_ip_list"), + match=[AlarmMatch(json_operand1_value=json.dumps(lval), + json_operand2_value=json.dumps(rval))])) + or_list.append(AlarmRuleMatch(rule=and_list)) + + if len(or_list): + return or_list return None diff --git a/src/opserver/plugins/alarm_bgp_connectivity/main.py b/src/opserver/plugins/alarm_bgp_connectivity/main.py index ef42f39a112..dd7e7a920e7 100644 --- a/src/opserver/plugins/alarm_bgp_connectivity/main.py +++ b/src/opserver/plugins/alarm_bgp_connectivity/main.py @@ -15,37 +15,32 @@ def __call__(self, uve_key, uve_data): v1 = uve_data.get("BgpRouterState", None) if v1 is not None: and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["BgpRouterState"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) v2 = v1.get("num_up_bgp_peer", None) if v2 is None: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["BgpRouterState","num_up_bgp_peer"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps(None))) - or_list.append(AllOf(all_of=and_list)) + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="BgpRouterState.num_up_bgp_peer", + operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) if v1 is not None: - lval = v1.get("num_up_bgp_peer",None) - rval = v1.get("num_bgp_peer",None) + lval = v1.get("num_up_bgp_peer", None) + rval = v1.get("num_bgp_peer", None) else: lval = None rval = None - if lval != rval: - and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["BgpRouterState","num_up_bgp_peer"]), - operand2=Operand2(keys=["BgpRouterState","num_bgp_peer"])), - json_operand1_value=json.dumps(lval), - json_operand2_value=json.dumps(rval))) - or_list.append(AllOf(all_of=and_list)) + if lval != rval: + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="BgpRouterState.num_up_bgp_peer", + operand2="BgpRouterState.num_bgp_peer"), + match=[AlarmMatch(json_operand1_value=json.dumps(lval), + json_operand2_value=json.dumps(rval))])) + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: - return None + return None diff --git a/src/opserver/plugins/alarm_config_incorrect/main.py b/src/opserver/plugins/alarm_config_incorrect/main.py index 8df38d49303..33fa6cb861b 100644 --- a/src/opserver/plugins/alarm_config_incorrect/main.py +++ b/src/opserver/plugins/alarm_config_incorrect/main.py @@ -10,17 +10,16 @@ def __call__(self, uve_key, uve_data): or_list = [] if not uve_data.has_key("ContrailConfig"): and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["ContrailConfig"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps(None))) - or_list.append(AllOf(all_of=and_list)) + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="ContrailConfig", operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: - return None + return None class ConfIncorrectCompute(ConfIncorrect): """Compute Node config missing or incorrect. diff --git a/src/opserver/plugins/alarm_disk_usage/main.py b/src/opserver/plugins/alarm_disk_usage/main.py index 69fe5d1a77a..07f3c3cc118 100644 --- a/src/opserver/plugins/alarm_disk_usage/main.py +++ b/src/opserver/plugins/alarm_disk_usage/main.py @@ -4,39 +4,38 @@ class DiskUsage(AlarmBase): """Disk Usage crosses a threshold. - NodeMgr reports disk usage in DatabaseUsageInfo.database_usage""" + NodeMgr reports disk usage in NodeStatus.disk_usage_info""" def __init__(self): AlarmBase.__init__(self, AlarmBase.SYS_ERR) - self._threshold = 0.90 + self._threshold = 50 def __call__(self, uve_key, uve_data): or_list = [] - db_usage_info = uve_data.get("DatabaseUsageInfo", None) - if db_usage_info is None: + node_status = uve_data.get("NodeStatus", None) + if node_status is None: return None - db_usage_list = db_usage_info.get("database_usage", None) - if db_usage_list is None: + disk_usage_list = node_status.get("disk_usage_info", None) + if disk_usage_list is None: return None - for db_usage in db_usage_list: - used_space = db_usage["disk_space_used_1k"] - available_space = db_usage["disk_space_available_1k"] - use_space_threshold = available_space * self._threshold - if used_space > use_space_threshold: - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper=">", - operand1=Operand1(\ - keys=["DatabaseUsageInfo","database_usage","disk_space_used_1k"]), - operand2=Operand2(json_value=str(use_space_threshold))), - json_operand1_value=str(used_space), - json_vars={\ - "DatabaseUsageInfo.database_usage.disk_space_used_1k":\ - str(used_space), - "DatabaseUsageInfo.database_usage.disk_space_available_1k":\ - str(available_space)})])) + match_list = [] + for disk_usage in disk_usage_list: + if disk_usage["percentage_partition_space_used"] > self._threshold: + match_list.append(AlarmMatch(json_operand1_value=json.dumps( + disk_usage["percentage_partition_space_used"]), json_vars={ + "NodeStatus.disk_usage_info.partition_name":\ + json.dumps(disk_usage["partition_name"])})) + if len(match_list): + and_list = [AlarmConditionMatch( + condition=AlarmCondition(operation=">", + operand1="NodeStatus.disk_usage_info." +\ + "percentage_partition_space_used", + operand2=json.dumps(self._threshold), + vars=["NodeStatus.disk_usage_info.partition_name"]), + match=match_list)] + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: return None - diff --git a/src/opserver/plugins/alarm_partial_sysinfo/main.py b/src/opserver/plugins/alarm_partial_sysinfo/main.py index 448a83f9443..4c6f4bb24ad 100644 --- a/src/opserver/plugins/alarm_partial_sysinfo/main.py +++ b/src/opserver/plugins/alarm_partial_sysinfo/main.py @@ -16,24 +16,21 @@ def __call__(self, uve_key, uve_data): 'ObjectBgpRouter':"BgpRouterState", 'ObjectVRouter':"VrouterAgent", } sname = smap[tab] - val = None if sname in uve_data: - if "build_info" in uve_data[sname]: - val = uve_data[sname]["build_info"] - - if val is None: - and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=[sname,"build_info"]), - operand2=Operand2(json_value="null")), - json_operand1_value="null")) - or_list.append(AllOf(all_of=and_list)) + try: + build_info = uve_data[sname]["build_info"] + except KeyError: + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1=sname+".build_info", operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: - return None + return None class PartialSysinfoCompute(PartialSysinfo): """System Info Incomplete. diff --git a/src/opserver/plugins/alarm_process_connectivity/main.py b/src/opserver/plugins/alarm_process_connectivity/main.py index 74bb33babef..5227a01bb1b 100644 --- a/src/opserver/plugins/alarm_process_connectivity/main.py +++ b/src/opserver/plugins/alarm_process_connectivity/main.py @@ -11,34 +11,37 @@ def __init__(self): def __call__(self, uve_key, uve_data): or_list = [] - v2 = None v1 = uve_data.get("NodeStatus",None) - if v1 is not None: - v2 = v1.get("process_status",None) + if v1 is None: + return None + v2 = v1.get("process_status",None) if v2 is None: - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["NodeStatus","process_status"]), - operand2=Operand2(json_value="null")), - json_operand1_value="null")])) + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="NodeStatus.process_status", operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) return or_list - value = None - proc_status_list = v2 - for proc_status in proc_status_list: - value = str(proc_status) + proc_status_list = v2 + match_list = [] + for proc_status in proc_status_list: if proc_status["state"] != "Functional": - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(\ - keys=["NodeStatus","process_status","state"]), - operand2=Operand2(json_value=json.dumps("Functional"))), - json_operand1_value=json.dumps(proc_status["state"]), - json_vars={\ - "NodeStatus.process_status.module_id":\ - proc_status["module_id"], - "NodeStatus.process_status.instance_id":\ - proc_status["instance_id"]})])) + match_list.append(AlarmMatch(json_operand1_value=json.dumps( + proc_status["state"]), json_vars={ + "NodeStatus.process_status.module_id":\ + json.dumps(proc_status["module_id"]), + "NodeStatus.process_status.instance_id":\ + json.dumps(proc_status["instance_id"])})) + if len(match_list): + or_list.append(AlarmRuleMatch(rule=[AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="NodeStatus.process_status.state", + operand2=json.dumps("Functional"), + vars=["NodeStatus.process_status.module_id", + "NodeStatus.process_status.instance_id"]), + match=match_list)])) if len(or_list): return or_list else: diff --git a/src/opserver/plugins/alarm_process_status/main.py b/src/opserver/plugins/alarm_process_status/main.py index 7203232fd39..67aa9eb6f91 100644 --- a/src/opserver/plugins/alarm_process_status/main.py +++ b/src/opserver/plugins/alarm_process_status/main.py @@ -10,35 +10,36 @@ def __init__(self): AlarmBase.__init__(self, AlarmBase.SYS_ERR) def __call__(self, uve_key, uve_data): - or_list = [] + or_list = [] v2 = None v1 = uve_data.get("NodeStatus",None) - if v1 is not None: - v2 = v1.get("process_info",None) + if v1 is None: + return None + + v2 = v1.get("process_info",None) if v2 is None: - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["NodeStatus","process_info"]), - operand2=Operand2(json_value="null")), - json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=[AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="NodeStatus.process_info", operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])])) return or_list - value = None proc_status_list = v2 + match_list = [] for proc_status in proc_status_list: - value = str(proc_status) if proc_status["process_state"] != "PROCESS_STATE_RUNNING": - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(\ - keys=["NodeStatus","process_info","process_state"]), - operand2=Operand2(json_value=\ - json.dumps("PROCESS_STATE_RUNNING"))), - json_operand1_value=json.dumps(proc_status["process_state"]), - json_vars={\ - "NodeStatus.process_info.process_name":\ - proc_status["process_name"]})])) + match_list.append(AlarmMatch(json_operand1_value=json.dumps( + proc_status["process_state"]), json_vars={ + "NodeStatus.process_info.process_name":\ + json.dumps(proc_status["process_name"])})) + if len(match_list): + or_list.append(AlarmRuleMatch(rule=[AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="NodeStatus.process_info.process_state", + operand2=json.dumps("PROCESS_STATE_RUNNING"), + vars=["NodeStatus.process_info.process_name"]), + match=match_list)])) if len(or_list): return or_list else: diff --git a/src/opserver/plugins/alarm_prouter_connectivity/main.py b/src/opserver/plugins/alarm_prouter_connectivity/main.py index d6610e1bd20..42380893f9c 100644 --- a/src/opserver/plugins/alarm_prouter_connectivity/main.py +++ b/src/opserver/plugins/alarm_prouter_connectivity/main.py @@ -20,30 +20,36 @@ def __call__(self, uve_key, uve_data): not "elements" in contrail_config: return None uattr = contrail_config["elements"] - if isinstance(uattr,list): - uattr = uattr[0][0] if not "virtual_router_refs" in uattr: return None or_list = [] - v2 = None + and_list = [] + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="ContrailConfig.elements.virtual_router_refs", + operand2="null"), + match=[AlarmMatch(json_operand1_value=json.dumps( + uattr["virtual_router_refs"]))])) v1 = uve_data.get("ProuterData",None) if v1 is not None: v2 = v1.get("connected_agent_list",None) - if v2 is None: - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["ProuterData","connected_agent_list"]), - operand2=Operand2(json_value="null")), - json_operand1_value="null")])) - return or_list + if v2 is None: + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="ProuterData.connected_agent_list", + operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) + return or_list - if not (len(v2) == 1): - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="size!=", - operand1=Operand1(keys=["ProuterData","connected_agent_list"]), - operand2=Operand2(json_value=json.dumps(1))), - json_operand1_value=json.dumps(v2))])) - return or_list + if len(v2) != 1: + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="size!=", + operand1="ProuterData.connected_agent_list", + operand2=json.dumps(1)), + match=[AlarmMatch(json_operand1_value=json.dumps(v2))])) + or_list.append(AlarmRuleMatch(rule=and_list)) + return or_list return None diff --git a/src/opserver/plugins/alarm_storage/main.py b/src/opserver/plugins/alarm_storage/main.py index 9df80dbe242..c44c4e269e1 100644 --- a/src/opserver/plugins/alarm_storage/main.py +++ b/src/opserver/plugins/alarm_storage/main.py @@ -25,20 +25,19 @@ def __call__(self, uve_key, uve_data): status = cluster_stat['status'] if status != 0: if status == 1: - status_string = 'HEALTH_WARN' self._sev = AlarmBase.SYS_WARN else: - status_string = 'HEALTH_ERR' self._sev = AlarmBase.SYS_ERR health_summary = cluster_stat['health_summary'] - or_list.append(AllOf(all_of=[AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["StorageCluster", "info_stats", "status"]), - operand2=Operand2(json_value=json.dumps("HEALTH_OK"))), - json_operand1_value=json.dumps(status_string), - json_vars={\ - "StorageCluster.info_stats.health_summary":\ - json.dumps(health_summary)})])) + and_list = [AlarmConditionMatch(condition=AlarmCondition( + operation="!=", operand1="StorageCluster.info_stats.status", + operand2=json.dumps(0), + vars=["StorageCluster.info_stats.health_summary"]), + match=[AlarmMatch(json_operand1_value=json.dumps(status), + json_vars={ + "StorageCluster.info_stats.health_summary":\ + json.dumps(health_summary)})])] + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: diff --git a/src/opserver/plugins/alarm_vrouter_interface/main.py b/src/opserver/plugins/alarm_vrouter_interface/main.py index ae5b25a5557..9759c03b430 100644 --- a/src/opserver/plugins/alarm_vrouter_interface/main.py +++ b/src/opserver/plugins/alarm_vrouter_interface/main.py @@ -13,32 +13,24 @@ def __call__(self, uve_key, uve_data): or_list = [] if "VrouterAgent" in uve_data: and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["VrouterAgent"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) - ust = uve_data["VrouterAgent"] - - if "error_intf_list" in ust: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["VrouterAgent","error_intf_list"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) - - if ust["error_intf_list"] == []: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["VrouterAgent", - "error_intf_list"]), - operand2=Operand2(json_value="[]")), - json_operand1_value=json.dumps(\ - uve_data["VrouterAgent"]["error_intf_list"]))) - or_list.append(AllOf(all_of=and_list)) + if "error_intf_list" in ust: + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation='!=', + operand1='VrouterAgent.error_intf_list', + operand2='null'), + match=[AlarmMatch(json_operand1_value=json.dumps( + ust["error_intf_list"]))])) + if ust["error_intf_list"] != []: + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="VrouterAgent.error_intf_list", + operand2=json.dumps([])), + match=[AlarmMatch(json_operand1_value=json.dumps( + ust["error_intf_list"]))])) + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: - return None + return None diff --git a/src/opserver/plugins/alarm_xmpp_connectivity/main.py b/src/opserver/plugins/alarm_xmpp_connectivity/main.py index 36f65478402..b31548251ea 100644 --- a/src/opserver/plugins/alarm_xmpp_connectivity/main.py +++ b/src/opserver/plugins/alarm_xmpp_connectivity/main.py @@ -15,19 +15,14 @@ def __call__(self, uve_key, uve_data): v1 = uve_data.get("BgpRouterState", None) if v1 is not None: and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["BgpRouterState"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps({}))) v2 = v1.get("num_up_xmpp_peer", None) if v2 is None: - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="==", - operand1=Operand1(keys=["BgpRouterState","num_up_xmpp_peer"]), - operand2=Operand2(json_value="null")), - json_operand1_value=json.dumps(None))) - or_list.append(AllOf(all_of=and_list)) + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="==", + operand1="BgpRouterState.num_up_xmpp_peer", + operand2="null"), + match=[AlarmMatch(json_operand1_value="null")])) + or_list.append(AlarmRuleMatch(rule=and_list)) if v1 is not None: lval = v1.get("num_up_xmpp_peer",None) @@ -38,13 +33,13 @@ def __call__(self, uve_key, uve_data): if lval != rval: and_list = [] - and_list.append(AlarmElement(\ - rule=AlarmTemplate(oper="!=", - operand1=Operand1(keys=["BgpRouterState","num_up_xmpp_peer"]), - operand2=Operand2(keys=["BgpRouterState","num_xmpp_peer"])), - json_operand1_value=json.dumps(lval), - json_operand2_value=json.dumps(rval))) - or_list.append(AllOf(all_of=and_list)) + and_list.append(AlarmConditionMatch( + condition=AlarmCondition(operation="!=", + operand1="BgpRouterState.num_up_xmpp_peer", + operand2="BgpRouterState.num_xmpp_peer"), + match=[AlarmMatch(json_operand1_value=json.dumps(lval), + json_operand2_value=json.dumps(rval))])) + or_list.append(AlarmRuleMatch(rule=and_list)) if len(or_list): return or_list else: diff --git a/src/opserver/test-requirements.txt b/src/opserver/test-requirements.txt index 8e62f6cf868..cd5184f1d54 100644 --- a/src/opserver/test-requirements.txt +++ b/src/opserver/test-requirements.txt @@ -24,11 +24,14 @@ cassandra-driver==3.0.0 ../libpartition/dist/libpartition-0.1dev.tar.gz ../discovery/client/dist/discoveryclient-0.1dev.tar.gz ../config/common/dist/cfgm_common-0.1dev.tar.gz +../opserver/plugins/alarm_address_mismatch/dist/alarm_address_mismatch-0.1dev.tar.gz ../opserver/plugins/alarm_bgp_connectivity/dist/alarm_bgp_connectivity-0.1dev.tar.gz +../opserver/plugins/alarm_config_incorrect/dist/alarm_config_incorrect-0.1dev.tar.gz +../opserver/plugins/alarm_disk_usage/dist/alarm_disk_usage-0.1dev.tar.gz ../opserver/plugins/alarm_partial_sysinfo/dist/alarm_partial_sysinfo-0.1dev.tar.gz ../opserver/plugins/alarm_process_connectivity/dist/alarm_process_connectivity-0.1dev.tar.gz ../opserver/plugins/alarm_process_status/dist/alarm_process_status-0.1dev.tar.gz +../opserver/plugins/alarm_prouter_connectivity/dist/alarm_prouter_connectivity-0.1dev.tar.gz +../opserver/plugins/alarm_storage/dist/alarm_storage-0.1dev.tar.gz ../opserver/plugins/alarm_vrouter_interface/dist/alarm_vrouter_interface-0.1dev.tar.gz ../opserver/plugins/alarm_xmpp_connectivity/dist/alarm_xmpp_connectivity-0.1dev.tar.gz -../opserver/plugins/alarm_storage/dist/alarm_storage-0.1dev.tar.gz -../opserver/plugins/alarm_prouter_connectivity/dist/alarm_prouter_connectivity-0.1dev.tar.gz diff --git a/src/opserver/test/test_alarm_plugins.py b/src/opserver/test/test_alarm_plugins.py new file mode 100644 index 00000000000..a7c889d7e5d --- /dev/null +++ b/src/opserver/test/test_alarm_plugins.py @@ -0,0 +1,1387 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. +# + +import signal +import unittest +import logging +from collections import namedtuple + +from opserver.sandesh.alarmgen_ctrl.sandesh_alarm_base.ttypes import * +from alarm_process_status.main import ProcessStatus +from alarm_bgp_connectivity.main import BgpConnectivity +from alarm_xmpp_connectivity.main import XmppConnectivity +from alarm_partial_sysinfo.main import PartialSysinfoCompute,\ + PartialSysinfoAnalytics, PartialSysinfoConfig, PartialSysinfoControl +from alarm_config_incorrect.main import ConfIncorrectCompute,\ + ConfIncorrectAnalytics, ConfIncorrectConfig, ConfIncorrectControl,\ + ConfIncorrectDatabase +from alarm_address_mismatch.main import AddressMismatchControl,\ + AddressMismatchCompute +from alarm_prouter_connectivity.main import ProuterConnectivity +from alarm_vrouter_interface.main import VrouterInterface +from alarm_storage.main import StorageClusterState +from alarm_disk_usage.main import DiskUsage + + +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(levelname)s %(message)s') + +TestCase = namedtuple('TestCase', ['name', 'input', 'output']) +TestInput = namedtuple('TestInput', ['uve_key', 'uve_data']) +TestOutput = namedtuple('TestOutput', ['or_list']) + + +class TestAlarmPlugins(unittest.TestCase): + + def setUp(self): + self.maxDiff = None + # end setUp + + def tearDown(self): + pass + # end tearDown + + def test_alarm_address_mismatch(self): + tests = [ + TestCase( + name='ContrailConfig == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'bgp_router_ip_list': ['10.1.1.1'] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='BgpRouterState == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'bgp_router_parameters': \ + '{"address": "10.1.1.1"}' + } + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='ContrailConfig.elements.bgp_router_parameters.address'+\ + ' == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'bgp_router_parameters': \ + '{"router_type": "control-node"}' + } + }, + 'BgpRouterState': { + 'num_bgp_peer': 1, + 'bgp_router_ip_list': ['10.1.1.1'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.bgp_router_parameters' +\ + '.address not in BgpRouterState.' +\ + 'bgp_router_ip_list', None, + [('null', '["10.1.1.1"]', None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.bgp_router_ip_list == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'bgp_router_parameters': \ + '{"address": "10.1.1.1"}' + } + }, + 'BgpRouterState': { + 'num_bgp_peer': 1 + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.bgp_router_parameters' +\ + '.address not in BgpRouterState.' +\ + 'bgp_router_ip_list', None, + [('"10.1.1.1"', 'null', None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.bgp_router_parameters.address' +\ + ' not in BgpRouterState.bgp_router_ip_list', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'bgp_router_ip_list': ['10.1.1.1'] + }, + 'ContrailConfig': { + 'elements': { + 'bgp_router_parameters': \ + '{"address": "1.1.1.2"}' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.bgp_router_parameters' +\ + '.address not in BgpRouterState.' +\ + 'bgp_router_ip_list', None, + [('"1.1.1.2"', '["10.1.1.1"]', None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.bgp_router_parameters.address' +\ + ' in BgpRouterState.bgp_router_ip_list', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'bgp_router_ip_list': ['10.1.1.1'] + }, + 'ContrailConfig': { + 'elements': { + 'bgp_router_parameters': \ + '{"address": "10.1.1.1"}' + } + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(AddressMismatchControl(), tests) + + tests = [ + TestCase( + name='ContrailConfig == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='VrouterAgent == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"10.1.1.1"' + } + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_ip_address ' +\ + '== null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'], + 'control_ip': '10.1.1.1' + }, + 'ContrailConfig': { + 'elements': { + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address not in ' + 'VrouterAgent.self_ip_list', None, + [('null', '["10.1.1.1"]', None)]) + ] + }, + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address != ' + 'VrouterAgent.control_ip', None, + [('null', '"10.1.1.1"', None)]) + ] + } + ]) + ), + TestCase( + name='VrouterAgent.self_ip_list == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'control_ip': '10.1.1.1' + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"10.1.1.1"' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address not in ' + 'VrouterAgent.self_ip_list', None, + [('"10.1.1.1"', 'null', None)]) + ] + } + ]) + ), + TestCase( + name='VrouterAgent.control_ip == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['1.1.1.1', '10.1.1.1'], + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"10.1.1.1"' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address != ' + 'VrouterAgent.control_ip', None, + [('"10.1.1.1"', 'null', None)]) + ] + } + ]) + ), + TestCase( + name='VrouterAgent.control_ip == null, ' +\ + 'VrouterAgent.self_ip_list == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"10.1.1.1"' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address not in ' + 'VrouterAgent.self_ip_list', None, + [('"10.1.1.1"', 'null', None)]) + ] + }, + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address != ' + 'VrouterAgent.control_ip', None, + [('"10.1.1.1"', 'null', None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_ip_address ' +\ + '!= VrouterAgent.control_ip', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['1.1.1.1', '1.1.1.2'], + 'control_ip': '1.1.1.1' + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"1.1.1.2"' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address != ' + 'VrouterAgent.control_ip', None, + [('"1.1.1.2"', '"1.1.1.1"', None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_ip_address ' +\ + 'not in VrouterAgent.self_ip_list', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'], + 'control_ip': '1.1.1.2' + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"1.1.1.2"' + } + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.' +\ + 'virtual_router_ip_address not in ' + 'VrouterAgent.self_ip_list', None, + [('"1.1.1.2"', '["10.1.1.1"]', None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_ip_address ' +\ + 'in VrouterAgent.self_ip_list, ' +\ + 'ContrailConfig.elements.virtual_router_ip_address ' +\ + '== VrouterAgent.control_ip', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['1.1.1.1', '10.1.1.1'], + 'control_ip': '10.1.1.1' + }, + 'ContrailConfig': { + 'elements': { + 'virtual_router_ip_address': '"10.1.1.1"' + } + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(AddressMismatchCompute(), tests) + # end test_alarm_address_mismatch + + def test_alarm_bgp_connectivity(self): + tests = [ + TestCase( + name='BgpRouterState == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='BgpRouterState.num_up_bgp_peer == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_bgp_peer': 2 + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('BgpRouterState.num_up_bgp_peer == null', + None, [('null', None, None)]) + ] + }, + { + 'rule': [ + ('BgpRouterState.num_up_bgp_peer != ' +\ + 'BgpRouterState.num_bgp_peer', + None, [('null', '2', None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.num_up_bgp_peer != ' +\ + 'BgpRouterState.num_bgp_peer', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_bgp_peer': 2, + 'num_up_bgp_peer': 1 + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('BgpRouterState.num_up_bgp_peer != ' +\ + 'BgpRouterState.num_bgp_peer', + None, [('1', '2', None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.num_up_bgp_peer == ' +\ + 'BgpRouterState.num_bgp_peer', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_bgp_peer': 2, + 'num_up_bgp_peer': 2 + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(BgpConnectivity(), tests) + # end test_alarm_bgp_connectivity + + def test_alarm_incorrect_config(self): + tests = [ + TestCase( + name='analytics-node: ContrailConfig == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={}), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='analytics-node: ContrailConfig != null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'display_name': '"host1"' + } + } + }), + output=TestOutput(or_list=None) + ) + ] + self._verify(ConfIncorrectAnalytics(), tests) + + tests = [ + TestCase( + name='vrouter: ContrailConfig == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={}), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='vrouter: ContrailConfig != null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'display_name': '"host1"' + } + } + }), + output=TestOutput(or_list=None) + ) + ] + self._verify(ConfIncorrectCompute(), tests) + + tests= [ + TestCase( + name='config-node: ContrailConfig == null', + input=TestInput(uve_key='ObjectConfigNode:host1', + uve_data={}), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='config-node: ContrailConfig != null', + input=TestInput(uve_key='ObjectConfigNode:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'display_name': '"host1"' + } + } + }), + output=TestOutput(or_list=None) + ) + ] + self._verify(ConfIncorrectConfig(), tests) + + tests = [ + TestCase( + name='control-node: ContrailConfig == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={}), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='control-node: ContrailConfig != null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'display_name': '"host1"' + } + } + }), + output=TestOutput(or_list=None) + ) + ] + self._verify(ConfIncorrectControl(), tests) + + tests = [ + TestCase( + name='database-node: ContrailConfig == null', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={}), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='database-node: ContrailConfig != null', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'display_name': '"host1"' + } + } + }), + output=TestOutput(or_list=None) + ) + ] + self._verify(ConfIncorrectDatabase(), tests) + # end test_alarm_incorrect_config + + def test_alarm_disk_usage(self): + tests = [ + TestCase( + name='NodeStatus == null', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='NodeStatus.disk_usage_info == null', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={ + 'NodeStatus': {} + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='NodeStatus.disk_usage_info.' +\ + 'percentage_partition_space_used < threshold', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={ + 'NodeStatus': { + 'disk_usage_info': [ + { + 'partition_space_available_1k': 100663296, + 'partition_space_used_1k': 33554432, + 'partition_name': 'dev/sda1', + 'partition_type': 'ext2', + 'percentage_partition_space_used': 25 + } + ] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='NodeStatus.disk_usage_info.' +\ + 'percentage_partition_space_used > threshold', + input=TestInput(uve_key='ObjectDatabaseInfo:host1', + uve_data={ + 'NodeStatus': { + 'disk_usage_info': [ + { + 'partition_space_available_1k': 100663296, + 'partition_space_used_1k': 33554432, + 'partition_name': 'dev/sda1', + 'partition_type': 'ext2', + 'percentage_partition_space_used': 25 + }, + { + 'partition_space_available_1k': 60397978, + 'partition_space_used_1k': 73819750, + 'partition_name': 'dev/sda2', + 'partition_type': 'ext4', + 'percentage_partition_space_used': 55 + } + ] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('NodeStatus.disk_usage_info.' +\ + 'percentage_partition_space_used > 50', + ['NodeStatus.disk_usage_info.' +\ + 'partition_name'], + [('55', None, { + 'NodeStatus.disk_usage_info.' +\ + 'partition_name': '"dev/sda2"'})] + ) + ] + } + ]) + ) + ] + self._verify(DiskUsage(), tests) + # end test_alarm_disk_usage + + def test_alarm_partial_sysinfo(self): + tests = [ + TestCase( + name='CollectorState == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='CollectorState.build_info == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={ + 'CollectorState': { + 'self_ip_list': ['10.10.10.1'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [('CollectorState.build_info == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='CollectorState.build_info != null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={ + 'CollectorState': { + 'self_ip_list': ['10.10.10.1'], + 'build_info': '"{"build-number":"100"}"' + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(PartialSysinfoAnalytics(), tests) + + tests = [ + TestCase( + name='ModuleCpuState == null', + input=TestInput(uve_key='ObjectConfigNode:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='ModuleCpuState.build_info == null', + input=TestInput(uve_key='ObjectConfigNode:host2', + uve_data={ + 'ModuleCpuState': { + 'config_node_ip': ['192.168.1.1'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [('ModuleCpuState.build_info == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='ModuleCpuState.build_info != null', + input=TestInput(uve_key='ObjectConfigNode:host1', + uve_data={ + 'ModuleCpuState': { + 'config_node_ip': ['10.10.10.1'], + 'build_info': '"{"build-number":"2729"}"' + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(PartialSysinfoConfig(), tests) + + tests = [ + TestCase( + name='BgpRouterState == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='BgpRouterState.build_info == null', + input=TestInput(uve_key='ObjectBgpRouter:host2', + uve_data={ + 'BgpRouterState': { + 'bgp_router_ip_list': ['192.168.1.1'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [('BgpRouterState.build_info == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.build_info != null', + input=TestInput(uve_key='ObjectBgpRouter:host3', + uve_data={ + 'BgpRouterState': { + 'bgp_router_ip_list': ['10.10.10.1'], + 'build_info': '"{"build-number":"2121"}"' + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(PartialSysinfoControl(), tests) + + tests = [ + TestCase( + name='VrouterAgent == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='VrouterAgent.build_info == null', + input=TestInput(uve_key='ObjectVRouter:host2', + uve_data={ + 'VrouterAgent': { + 'control_ip': '192.168.1.1' + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [('VrouterAgent.build_info == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='VrouterAgent.build_info != null', + input=TestInput(uve_key='ObjectVRouter:host3', + uve_data={ + 'VrouterAgent': { + 'control_ip': '10.10.10.1', + 'build_info': '"{"build-number":"2829"}"' + }, + 'ContrailConfig': { + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(PartialSysinfoCompute(), tests) + # end test_alarm_partial_sysinfo + + def test_alarm_process_connectivity(self): + tests = [ + TestCase( + name='NodeStatus == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='NodeStatus.process_status == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {}}), + output=TestOutput(or_list=[ + { + 'rule': [('NodeStatus.process_status == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='All processes: NodeStatus.process_status.state' +\ + ' == Functional', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {'process_status': [ + { + 'instance_id': '0', + 'module_id': 'contrail-snmp-collector', + 'state': 'Functional' + }, + { + 'instance_id': '0', + 'module_id': 'contrail-topology', + 'state': 'Functional' + } + ]}} + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='One process: NodeStatus.process_status.state' +\ + ' != Functional', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {'process_status': [ + { + 'instance_id': '0', + 'module_id': 'contrail-snmp-collector', + 'state': 'Functional' + }, + { + 'instance_id': '0', + 'module_id': 'contrail-topology', + 'state': 'Non-Functional' + } + ]}} + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('NodeStatus.process_status.state != "Functional"', + ['NodeStatus.process_status.module_id', + 'NodeStatus.process_status.instance_id'], + [('"Non-Functional"', None, { + 'NodeStatus.process_status.module_id':\ + '"contrail-topology"', + 'NodeStatus.process_status.instance_id': '0'}) + ]) + ] + } + ]) + ), + TestCase( + name='Multiple processes: NodeStatus.process_status.state' +\ + ' != Functional', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {'process_status': [ + { + 'instance_id': '0', + 'module_id': 'contrail-snmp-collector', + 'state': 'Non-Functional' + }, + { + 'instance_id': '0', + 'module_id': 'contrail-topology', + 'state': 'Functional' + }, + { + 'instance_id': '1', + 'module_id': 'contrail-snmp-collector', + 'state': 'Non-Functional' + } + ]}} + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('NodeStatus.process_status.state != "Functional"', + ['NodeStatus.process_status.module_id', + 'NodeStatus.process_status.instance_id'], + [('"Non-Functional"', None, { + 'NodeStatus.process_status.module_id':\ + '"contrail-snmp-collector"', + 'NodeStatus.process_status.instance_id': '0'}), + ('"Non-Functional"', None, { + 'NodeStatus.process_status.module_id':\ + '"contrail-snmp-collector"', + 'NodeStatus.process_status.instance_id': '1'}) + ]) + ] + } + ]) + ), + ] + # end test_alarm_process_connectivity + + def test_alarm_process_status(self): + tests = [ + TestCase( + name='NodeStatus == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='NodeStatus.process_info == null', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {}}), + output=TestOutput(or_list=[ + { + 'rule': [('NodeStatus.process_info == null', + None, [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='All processes: NodeStatus.process_info.process_state' +\ + ' == PROCESS_STATE_RUNNING', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {'process_info': [ + { + 'process_name': 'contrail-topology', + 'process_state': 'PROCESS_STATE_RUNNING' + }, + { + 'process_name': 'contrail-collector', + 'process_state': 'PROCESS_STATE_RUNNING' + } + ]}} + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='One process: NodeStatus.process_info.process_state != ' +\ + 'PROCESS_STATE_RUNNING', + input=TestInput(uve_key='ObjectCollectorInfo:host1', + uve_data={'NodeStatus': {'process_info': [ + { + 'process_name': 'contrail-topology', + 'process_state': 'PROCESS_STATE_STOPPED' + }, + { + 'process_name': 'contrail-snmp-collector', + 'process_state': 'PROCESS_STATE_RUNNING' + } + ]}} + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('NodeStatus.process_info.process_state ' +\ + '!= "PROCESS_STATE_RUNNING"', + ['NodeStatus.process_info.process_name'], + [('"PROCESS_STATE_STOPPED"', None, { + 'NodeStatus.process_info.process_name':\ + '"contrail-topology"'})]) + ] + } + ]) + ), + TestCase( + name='Multiple processes: with process_state != ' +\ + 'PROCESS_STATE_RUNNING', + input=TestInput(uve_key='ObjectCollectorInfo:host4', + uve_data={'NodeStatus': {'process_info': [ + { + 'process_name': 'contrail-topology', + 'process_state': 'PROCESS_STATE_STOPPED' + }, + { + 'process_name': 'contrail-snmp-collector', + 'process_state': 'PROCESS_STATE_RUNNING' + }, + { + 'process_name': 'contrail-query-engine', + 'process_state': 'PROCESS_STATE_EXITED' + } + ]}} + ), + output=TestOutput(or_list=[ + { + 'rule': [('NodeStatus.process_info.process_state ' +\ + '!= "PROCESS_STATE_RUNNING"', + ['NodeStatus.process_info.process_name'], + [('"PROCESS_STATE_STOPPED"', None, { + 'NodeStatus.process_info.process_name':\ + '"contrail-topology"'}), + ('"PROCESS_STATE_EXITED"', None, { + 'NodeStatus.process_info.process_name':\ + '"contrail-query-engine"'}) + ]) + ] + } + ]) + ) + ] + self._verify(ProcessStatus(), tests) + # end test_alarm_process_status + + def test_prouter_connectivity(self): + tests = [ + TestCase( + name='ProuterData == null', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={} + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='ProuterData.connected_agent_list == null', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={ + 'ProuterData': {} + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_refs == null', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={ + 'ContrailConfig': { + 'elements': { + } + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_refs != null &' +\ + ' ProuterData.connected_agent_list == null', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'virtual_router_refs': '[{"to": ["tor1"]}]' + } + }, + 'ProuterData': { + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.virtual_router_refs ' +\ + '!= null', None, + [('"[{\\"to\\": [\\"tor1\\"]}]"', + None, None)]), + ('ProuterData.connected_agent_list == null', None, + [('null', None, None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_refs != null &' +\ + ' ProuterData.connected_agent_list size!= 1', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'virtual_router_refs': '[{"to": ["tor1"]}]' + } + }, + 'ProuterData': { + 'connected_agent_list': ['tor1', 'tor2'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('ContrailConfig.elements.virtual_router_refs ' +\ + '!= null', None, + [('"[{\\"to\\": [\\"tor1\\"]}]"', None, None)] + ), + ('ProuterData.connected_agent_list size!= 1', None, + [('["tor1", "tor2"]', None, None)]) + ] + } + ]) + ), + TestCase( + name='ContrailConfig.elements.virtual_router_refs != null &' +\ + ' ProuterData.connected_agent_list size= 1', + input=TestInput(uve_key='ObjectPRouter:prouter1', + uve_data={ + 'ContrailConfig': { + 'elements': { + 'virtual_router_refs': '[{"to": ["tor1"]}]' + } + }, + 'ProuterData': { + 'connected_agent_list': ['tor1'] + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(ProuterConnectivity(), tests) + # end test_prouter_connectivity + + def test_alarm_storage(self): + tests = [ + TestCase( + name='StorageCluster.info_stats.status == 0', + input=TestInput(uve_key='ObjectStorageClusterTable:cls1', + uve_data={ + 'StorageCluster': { + 'info_stats': [ + { + 'status': 0, + 'health_summary': 'HEALTH_OK' + } + ] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='StorageCluster.info_stats.status != 0', + input=TestInput(uve_key='ObjectStorageClusterTable:cls1', + uve_data={ + 'StorageCluster': { + 'info_stats': [ + { + 'status': 1, + 'health_summary': 'HEALTH_WARN' + } + ] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('StorageCluster.info_stats.status != 0', + ['StorageCluster.info_stats.health_summary'], + [('1', None, { + 'StorageCluster.info_stats.health_summary':\ + '"HEALTH_WARN"'})]) + ] + } + ]) + ), + ] + self._verify(StorageClusterState(), tests) + # end test_alarm_storage + + def test_alarm_vrouter_interface(self): + tests = [ + TestCase( + name='VrouterAgent == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='VrouterAgent.error_intf_list == null', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='VrouterAgent.error_intf_list == []', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'], + 'error_intf_list': [] + } + } + ), + output=TestOutput(or_list=None) + ), + TestCase( + name='VrouterAgent.error_intf_list != []', + input=TestInput(uve_key='ObjectVRouter:host1', + uve_data={ + 'VrouterAgent': { + 'self_ip_list': ['10.1.1.1'], + 'error_intf_list': ['error1'] + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('VrouterAgent.error_intf_list != null', None, + [('["error1"]', None, None)]), + ('VrouterAgent.error_intf_list != []', None, + [('["error1"]', None, None)]) + ] + } + ]) + ) + ] + self._verify(VrouterInterface(), tests) + # end test_alarm_vrouter_interface + + def test_alarm_xmpp_connectivity(self): + tests = [ + TestCase( + name='BgpRouterState == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={}), + output=TestOutput(or_list=None) + ), + TestCase( + name='BgpRouterState.num_up_xmpp_peer == null', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_xmpp_peer': 3 + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('BgpRouterState.num_up_xmpp_peer == null', + None, [('null', None, None)]) + ] + }, + { + 'rule': [ + ('BgpRouterState.num_up_xmpp_peer != ' +\ + 'BgpRouterState.num_xmpp_peer', + None, [('null', '3', None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.num_up_xmpp_peer != ' +\ + 'BgpRouterState.num_xmpp_peer', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_xmpp_peer': 3, + 'num_up_xmpp_peer': 2 + } + } + ), + output=TestOutput(or_list=[ + { + 'rule': [ + ('BgpRouterState.num_up_xmpp_peer != ' +\ + 'BgpRouterState.num_xmpp_peer', + None, [('2', '3', None)]) + ] + } + ]) + ), + TestCase( + name='BgpRouterState.num_up_xmpp_peer == ' +\ + 'BgpRouterState.num_xmpp_peer', + input=TestInput(uve_key='ObjectBgpRouter:host1', + uve_data={ + 'BgpRouterState': { + 'num_xmpp_peer': 1, + 'num_up_xmpp_peer': 1 + } + } + ), + output=TestOutput(or_list=None) + ) + ] + self._verify(XmppConnectivity(), tests) + # end test_alarm_xmpp_connectivity + + def _verify(self, plugin, tests): + for test in tests: + logging.info('Test: %s' % (test.name)) + exp_or_list = None + if test.output.or_list is not None: + exp_or_list = [] + for elt in test.output.or_list: + and_list = [] + for condition, vars, match in elt['rule']: + oper1, tmp = condition.split(' ', 1) + oper, oper2 = tmp.rsplit(' ', 1) + and_list.append(AlarmConditionMatch( + condition=AlarmCondition( + operation=oper, operand1=oper1, + operand2=oper2, vars=vars), + match=[AlarmMatch( + json_operand1_value=e[0], + json_operand2_value=e[1], + json_vars=e[2]) for e in match])) + exp_or_list.append(AlarmRuleMatch(rule=and_list)) + or_list = plugin.__call__(test.input.uve_key, test.input.uve_data) + self.assertEqual(exp_or_list, or_list) + # end _verify + + +# end class TestAlarmPlugins + +def _term_handler(*_): + raise IntSignal() + +if __name__ == '__main__': + gevent.signal(signal.SIGINT, _term_handler) + unittest.main(verbosity=2, catchbreak=True) diff --git a/src/opserver/test/test_analytics_uve.py b/src/opserver/test/test_analytics_uve.py index 9615d6c2574..308ccda5321 100755 --- a/src/opserver/test/test_analytics_uve.py +++ b/src/opserver/test/test_analytics_uve.py @@ -365,10 +365,15 @@ def test_06_alarmgen_basic(self): alarm_gen1.send_vrouterinfo("myvrouter1") assert(vizd_obj.verify_uvetable_alarm("ObjectVRouter", "ObjectVRouter:myvrouter1", "PartialSysinfoCompute", - any_of = [[{"json_operand1_value":"null", - "rule": {"AlarmTemplate":{"oper":"==", - "operand1":{"Operand1":{"keys":["ObjectVRouter","build_info"]}}, - "operand2":{"Operand2":{"json_value":"null"}}}}}]])) + rules=[{"rule": [{ + "condition": { + "operation": "==", + "operand1": "ObjectVRouter.build_info", + "operand2": "null" + }, + "match": [{"json_operand1_value": "null"}] + }]}] + )) # Now try to clear the alarm by sending build_info alarm_gen1.send_vrouterinfo("myvrouter1", b_info = True) diff --git a/src/opserver/test/utils/analytics_fixture.py b/src/opserver/test/utils/analytics_fixture.py index d7701f2a70e..ab3118f2e41 100644 --- a/src/opserver/test/utils/analytics_fixture.py +++ b/src/opserver/test/utils/analytics_fixture.py @@ -753,7 +753,7 @@ def verify_alarmgen_partition(self, part, own, uves = None): return False @retry(delay=2, tries=5) - def verify_uvetable_alarm(self, table, name, type, is_set = True, any_of = None): + def verify_uvetable_alarm(self, table, name, type, is_set=True, rules=None): vag = self.alarmgen.get_introspect() ret = vag.get_UVETableAlarm(table) self.logger.info("verify_uvetable_alarm %s, %s, %s [%s]: %s" % \ @@ -774,29 +774,23 @@ def verify_uvetable_alarm(self, table, name, type, is_set = True, any_of = None) if not ret['uves']: ret['uves'] = [] alarms = {} - for uves in ret['uves']: - elem = uves['uai']['UVEAlarms'] + for uves in ret['uves']: + elem = uves['uai']['UVEAlarms'] if elem['name'] != name: continue for alm in elem['alarms']: - if len(alm['any_of']): - alarms[alm['type']] = [] - for ee in alm['any_of']: - all_of = [] - if ee['all_of'] is not None: - for ff in ee['all_of']: - all_of.append(ff) - alarms[alm['type']].append(all_of) + if len(alm['rules']): + alarms[alm['type']] = alm['rules'] if type in alarms: if is_set: - if any_of: - if len(any_of) != len(alarms[type]): + if rules: + if len(rules) != len(alarms[type]): return False agg1 = 0 agg2 = 0 - for idx in range(0,len(any_of)): - agg1 += len(any_of[idx]) - agg2 += len(alarms[type][idx]) + for idx in range(0,len(rules)): + agg1 += len(rules[idx]['rule']) + agg2 += len(alarms[type][idx]['rule']) if agg1 != agg2: return False return is_set