Commit a6eed1ee authored by Andrey Vertiprahov's avatar Andrey Vertiprahov Committed by Dmitry Volodin
Browse files

Save discovery alarms to context.

parent 4db6bd37
......@@ -12,6 +12,9 @@ import datetime
from time import perf_counter
import asyncio
# Third-party modules
from typing import Dict, Any
# NOC modules
from noc.core.log import PrefixLoggerAdapter
from noc.core.debug import error_report
......@@ -104,7 +107,7 @@ class Job(object):
self.start_time = None
self.duration = None
self.logger = PrefixLoggerAdapter(scheduler.logger, self.get_display_key())
self.context = {}
self.context: Dict[str, Any] = {}
def load_context(self, data):
self.context = data or {}
......
......@@ -21,7 +21,7 @@ import bson
import cachetools
import orjson
from pymongo import UpdateOne
from typing import List, Dict
from typing import List, Dict, Any, Optional
from builtins import str, object
# NOC modules
......@@ -81,7 +81,8 @@ class MODiscoveryJob(PeriodicJob):
super().schedule_next(status)
# Update alarm statuses
# Clean up all open alarms as they has been disabled
self.update_alarms(self.problems if self.get_umbrella_settings() else [], self.umbrella_cls)
if self.get_umbrella_settings():
self.update_alarms(self.problems, self.umbrella_cls)
# Write job log
key = "discovery-%s-%s" % (self.attrs[self.ATTR_CLASS], self.attrs[self.ATTR_KEY])
problems = {}
......@@ -298,13 +299,31 @@ class MODiscoveryJob(PeriodicJob):
def update_alarms(
self, problems: List[ProblemItem], group_cls: str = None, group_reference: str = None
):
# @todo Save reference to job context
"""
Sync problems to alarm and use active_problems context variable
for check active alarm group.
* If empty problems and `group reference` not in active_problems- do nothing
* If empty problems and `group reference` in active_problems - send empty ensure_group to dispose and remove it from context
* If has problems - send ensure_group to dispose and save reference_group to active_problems context
:param problems: List problems
:param group_cls: Group Alarm Class
:param group_reference: Group Reference
:return:
"""
self.logger.info("Updating alarm statuses")
group_cls = AlarmClass.get_by_name(group_cls or "Group")
group_cls: Optional["AlarmClass"] = AlarmClass.get_by_name(group_cls or "Group")
if not group_cls:
self.logger.info("No umbrella alarm class. Alarm statuses not updated")
return
details = []
group_reference = group_reference or f"g:d:{self.object.id}:{group_cls.name}"
active_problems: Dict[str, List[str]] = self.context.get("active_problems", {})
if not problems and group_reference not in active_problems:
# No money, no honey
return
details: List[Dict[str, Any]] = []
now = datetime.datetime.now()
for p in problems:
if not p.alarm_class:
......@@ -328,7 +347,7 @@ class MODiscoveryJob(PeriodicJob):
]
msg = {
"$op": "ensure_group",
"reference": group_reference or f"g:d:{self.object.id}:{group_cls.name}",
"reference": group_reference,
"alarm_class": group_cls.name,
"alarms": details,
}
......@@ -341,6 +360,11 @@ class MODiscoveryJob(PeriodicJob):
self.logger.debug(
"Dispose: %s", orjson.dumps(msg, option=orjson.OPT_INDENT_2).decode("utf-8")
)
if not details and group_reference in active_problems:
del active_problems[group_reference]
else:
active_problems[group_reference] = [d["reference"] for d in details]
self.context["active_problems"] = active_problems
def get_umbrella_settings(self) -> bool:
"""
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment