Esempio n. 1
0
    def _set_agents_summary(self):
        results = env.dataprovider.query(["max(heartbeat.create_time)", "heartbeat.analyzer(-1).analyzerid/group_by"])
        if not results:
            return

        c = Criterion()
        for create_time, analyzerid in results:
            c |= Criterion("heartbeat.create_time", "==", create_time) & Criterion("heartbeat.analyzer(-1).analyzerid", "==", analyzerid)

        agents = {
            "up": utils.AttrObj(count=0, title=_("Online"), label="label-success", status=["online"]),
            "down": utils.AttrObj(count=0, title=_("Offline"), label="label-danger", status=["offline", "missing", "unknown"])
        }
        heartbeat_error_margin = env.config.general.get_int("heartbeat_error_margin", 3)

        for heartbeat in env.dataprovider.get(c):
            heartbeat = heartbeat["heartbeat"]
            analyzer = heartbeat["analyzer"][-1]
            analyzer.status = utils.get_analyzer_status_from_latest_heartbeat(heartbeat, heartbeat_error_margin)[0]

            for key, values in agents.items():
                if analyzer.status in values.status:
                    values.count += 1

        parameters = env.request.menu_parameters
        val = agents["down"] if agents["down"].count else agents["up"]
        data = resource.HTMLNode("a", localization.format_number(val.count), title=val.title, _class="label " + val.label, href=url_for("Agents.agents", status=val.status, **parameters))

        return utils.AttrObj(
            name="agents",
            title=resource.HTMLNode("a", _("Agents"), href=url_for("Agents.agents", **parameters)),
            data=[data]
        )
Esempio n. 2
0
    def _get_analyzers(self, reqstatus):
        # Do not take the control menu into account.
        # The expected behavior is yet to be determined.
        results = env.dataprovider.query(["max(heartbeat.create_time)", "heartbeat.analyzer(-1).analyzerid/group_by"])
        if not results:
            return

        c = Criterion()
        for create_time, analyzerid in results:
            c |= Criterion("heartbeat.create_time", "==", create_time) & Criterion("heartbeat.analyzer(-1).analyzerid", "==", analyzerid)

        for heartbeat in env.dataprovider.get(c):
            heartbeat = heartbeat["heartbeat"]
            status, status_text = utils.get_analyzer_status_from_latest_heartbeat(
                heartbeat, self._heartbeat_error_margin
            )

            if reqstatus and status not in reqstatus:
                continue

            delta = heartbeat.get("create_time") - utils.timeutil.now()

            analyzerid = heartbeat["analyzer(-1).analyzerid"]
            heartbeat_listing = url_for("HeartbeatDataSearch.forensic", criteria=Criterion("heartbeat.analyzer(-1).analyzerid", "==", analyzerid), _default=None)
            alert_listing = url_for("AlertDataSearch.forensic", criteria=Criterion("alert.analyzer.analyzerid", "==", analyzerid), _default=None)
            heartbeat_analyze = url_for(".analyze", analyzerid=analyzerid)

            analyzer = heartbeat["analyzer(-1)"]
            node_name = analyzer["node.name"] or _("Node name n/a")
            osversion = analyzer["osversion"] or _("OS version n/a")
            ostype = analyzer["ostype"] or _("OS type n/a")

            yield {
                "id": analyzerid,
                "label": "%s - %s %s" % (node_name, ostype, osversion),
                "location": analyzer["node.location"] or _("Node location n/a"),
                "node": node_name,
                "name": analyzer["name"],
                "model": analyzer["model"],
                "class": analyzer["class"],
                "version": analyzer["version"],
                "latest_heartbeat": localization.format_timedelta(delta, add_direction=True),
                "status": status,
                "status_text": status_text,
                "links": [
                    resource.HTMLNode("a", _("Alert listing"), href=alert_listing),
                    resource.HTMLNode("a", _("Heartbeat listing"), href=heartbeat_listing),
                    resource.HTMLNode("a", _("Heartbeat analysis"), href=heartbeat_analyze)
                ]
            }
Esempio n. 3
0
    def _get_analyzers(self):
        criteria = None
        if "filter_path" in self.parameters:
            criteria = "%s == '%s'" % (self.parameters["filter_path"],
                                       utils.escape_criteria(self.parameters["filter_value"]))

        for (analyzerid,) in env.idmef_db.getValues(["heartbeat.analyzer(-1).analyzerid/group_by"], criteria):
            analyzer, heartbeat = env.idmef_db.getAnalyzer(analyzerid)
            status, status_text = utils.get_analyzer_status_from_latest_heartbeat(
                heartbeat, self._heartbeat_error_margin
            )

            if self.parameters["status"] and status not in self.parameters["status"]:
                continue

            delta = float(heartbeat.get("create_time")) - time.time()

            parameters = {"heartbeat.analyzer(-1).analyzerid": analyzerid}
            heartbeat_listing = utils.create_link(view.getViewPath("HeartbeatListing"), parameters)

            parameters = {"analyzer_object_0": "alert.analyzer.analyzerid",
                          "analyzer_operator_0": "=",
                          "analyzer_value_0": analyzerid}
            alert_listing = utils.create_link(view.getViewPath("AlertListing"), parameters)

            parameters = {"analyzerid": analyzerid}
            heartbeat_analyze = utils.create_link(self.view_path + "/HeartbeatAnalyze", parameters)

            node_name = analyzer["node.name"] or _("Node name n/a")
            osversion = analyzer["osversion"] or _("OS version n/a")
            ostype = analyzer["ostype"] or _("OS type n/a")

            yield {"id": analyzerid,
                   "label": "%s - %s %s" % (node_name, ostype, osversion),
                   "location": analyzer["node.location"] or _("Node location n/a"),
                   "node": node_name,
                   "name": analyzer["name"],
                   "model": analyzer["model"],
                   "class": analyzer["class"],
                   "version": analyzer["version"],
                   "latest_heartbeat": localization.format_timedelta(delta, add_direction=True),
                   "status": status,
                   "status_text": status_text,
                   "links": [
                       {"text": _("Alert listing"), "link": alert_listing},
                       {"text": _("Heartbeat listing"), "link": heartbeat_listing},
                       {"text": _("Heartbeat analysis"), "link": heartbeat_analyze,
                        "class": "widget-link", "title": _("Heartbeat analysis")},
                   ]}
Esempio n. 4
0
    def analyze(self, analyzerid):
        analyzer, heartbeat = self._get_analyzer(analyzerid)
        delta = heartbeat["create_time"] - utils.timeutil.now()
        analyzer.last_heartbeat_time = localization.format_timedelta(delta, add_direction=True)

        analyzer.status = None
        analyzer.events = []

        res = env.dataprovider.get(Criterion("heartbeat.analyzer(-1).analyzerid", "=", analyzerid), limit=self._heartbeat_count)

        prev = None
        total_interval = 0

        # Iterate from oldest heartbeat to newest
        for obj in reversed(res):
            cur = HeartbeatObject(obj["heartbeat"])

            if not (prev and cur.status and cur.interval):
                prev = cur
                continue

            total_interval += cur.interval

            event = None
            if cur.status == "starting":
                if prev.status == "exiting":
                    event = utils.AttrObj(time=cur.time_str, value=_("Normal sensor start"), type="start")
                else:
                    event = utils.AttrObj(time=cur.time_str, value=_("Unexpected sensor restart"), type="unexpected_restart")

            elif cur.status == "running":
                delta = cur.time - prev.time
                if abs(delta.total_seconds() - cur.interval) > self._heartbeat_error_margin:
                    delta = localization.format_timedelta(delta, granularity="second")
                    event = utils.AttrObj(time=cur.time_str, value=_("Unexpected heartbeat interval: %(delta)s") % {'delta': delta}, type="abnormal_heartbeat_interval")

            elif cur.status == "exiting":
                event = utils.AttrObj(time=cur.time_str, value=_("Normal sensor stop"), type="normal_stop")

            if event:
                analyzer.events.append(event)

            prev = cur

        if prev:
            analyzer.status, analyzer.status_meaning = \
                utils.get_analyzer_status_from_latest_heartbeat(obj["heartbeat"], self._heartbeat_error_margin)
            if analyzer.status == "missing":
                delta = utils.timeutil.now() - prev.time
                analyzer.events.append(utils.AttrObj(time=prev.time_str, value=_("Sensor is down since %s") % localization.format_timedelta(delta), type="down"))

        if not analyzer.status:
            analyzer.status, analyzer.status_meaning = "unknown", _("Unknown")

        if not analyzer.events:
            delta = localization.format_timedelta(total_interval / self._heartbeat_count)
            analyzer.events.append(utils.AttrObj(
                time="",
                value=_("No anomaly in the last %(count)d heartbeats (one heartbeat every %(delta)s average)") % {'count': self._heartbeat_count, 'delta': delta},
                type="no_anomaly"
            ))

        return template.PrewikkaTemplate(__name__, "templates/heartbeatanalyze.mak").render(analyzer=analyzer)
Esempio n. 5
0
    def _get_analyzers(self, reqstatus):
        # Do not take the control menu into account.
        # The expected behavior is yet to be determined.
        for (analyzerid, ) in env.dataprovider.query(
            ["heartbeat.analyzer(-1).analyzerid/group_by"]):
            analyzer, heartbeat = self._get_analyzer(analyzerid)
            status, status_text = utils.get_analyzer_status_from_latest_heartbeat(
                heartbeat, self._heartbeat_error_margin)

            if reqstatus and status not in reqstatus:
                continue

            delta = float(heartbeat.get("create_time")) - time.time()

            heartbeat_listing = url_for(
                "HeartbeatListing.render",
                **{"heartbeat.analyzer(-1).analyzerid": analyzerid})
            alert_listing = url_for(
                "AlertListing.render", **{
                    "analyzer_object_0": "alert.analyzer.analyzerid",
                    "analyzer_operator_0": "=",
                    "analyzer_value_0": analyzerid
                })
            heartbeat_analyze = url_for(".analyze", analyzerid=analyzerid)

            node_name = analyzer["node.name"] or _("Node name n/a")
            osversion = analyzer["osversion"] or _("OS version n/a")
            ostype = analyzer["ostype"] or _("OS type n/a")

            yield {
                "id":
                analyzerid,
                "label":
                "%s - %s %s" % (node_name, ostype, osversion),
                "location":
                analyzer["node.location"] or _("Node location n/a"),
                "node":
                node_name,
                "name":
                analyzer["name"],
                "model":
                analyzer["model"],
                "class":
                analyzer["class"],
                "version":
                analyzer["version"],
                "latest_heartbeat":
                localization.format_timedelta(delta, add_direction=True),
                "status":
                status,
                "status_text":
                status_text,
                "links": [
                    {
                        "text": _("Alert listing"),
                        "link": alert_listing
                    },
                    {
                        "text": _("Heartbeat listing"),
                        "link": heartbeat_listing
                    },
                    {
                        "text": _("Heartbeat analysis"),
                        "link": heartbeat_analyze,
                        "class": "widget-link",
                        "title": _("Heartbeat analysis")
                    },
                ]
            }
Esempio n. 6
0
    def analyze(self, analyzerid):
        analyzer, heartbeat = self._get_analyzer(analyzerid)
        delta = float(heartbeat["create_time"]) - time.time()
        analyzer.last_heartbeat_time = localization.format_timedelta(
            delta, add_direction=True)

        analyzer.status = None
        analyzer.events = []

        res = env.dataprovider.get(Criterion(
            "heartbeat.analyzer(-1).analyzerid", "=", analyzerid),
                                   limit=self._heartbeat_count)

        prev = None
        latest = True
        total_interval = 0

        for idx, cur in enumerate(res):
            cur = cur["heartbeat"]
            cur_status, cur_interval, cur_time = cur.get(
                "additional_data('Analyzer status').data"
            )[0], cur["heartbeat_interval"], cur["create_time"]
            cur_time_str = localization.format_datetime(float(cur_time))

            try:
                prev = res[idx + 1]["heartbeat"]
                prev_status, prev_time = prev.get(
                    "additional_data('Analyzer status').data"
                )[0], prev["create_time"]
            except:
                break

            if not cur_status or not cur_interval:
                continue

            total_interval += int(cur_interval)

            if latest:
                latest = False
                analyzer.status, analyzer.status_meaning = \
                    utils.get_analyzer_status_from_latest_heartbeat(cur, self._heartbeat_error_margin)
                if analyzer.status == "missing":
                    delta = time.time() - float(cur_time)
                    analyzer.events.append(
                        utils.AttrObj(time=cur_time_str,
                                      value=_("Sensor is down since %s") %
                                      localization.format_timedelta(delta),
                                      type="down"))

            event = None
            if cur_status == "starting":
                if prev_status == "exiting":
                    event = utils.AttrObj(time=cur_time_str,
                                          value=_("Normal sensor start"),
                                          type="start")
                else:
                    event = utils.AttrObj(time=cur_time_str,
                                          value=_("Unexpected sensor restart"),
                                          type="unexpected_restart")

            elif cur_status == "running":
                delta = abs(int(cur_time) - int(prev_time) - int(cur_interval))
                if delta > self._heartbeat_error_margin:
                    delta = localization.format_timedelta(delta,
                                                          granularity="second")
                    event = utils.AttrObj(
                        time=cur_time_str,
                        value=_("Unexpected heartbeat interval: %(delta)s") %
                        {'delta': delta},
                        type="abnormal_heartbeat_interval")

            elif cur_status == "exiting":
                event = utils.AttrObj(time=cur_time_str,
                                      value=_("Normal sensor stop"),
                                      type="normal_stop")

            if event:
                analyzer.events.append(event)

        if not analyzer.status:
            analyzer.status, analyzer.status_meaning = "unknown", _("Unknown")

        if not analyzer.events:
            delta = localization.format_timedelta(total_interval /
                                                  self._heartbeat_count)
            analyzer.events.append(
                utils.AttrObj(
                    time="",
                    value=
                    _("No anomaly in the last %(count)d heartbeats (one heartbeat every %(delta)s average)"
                      ) % {
                          'count': self._heartbeat_count,
                          'delta': delta
                      },
                    type="no_anomaly"))

        return template.PrewikkaTemplate(
            __name__,
            "templates/heartbeatanalyze.mak").render(analyzer=analyzer)
Esempio n. 7
0
    def render(self):
        analyzerid = self.parameters["analyzerid"]

        analyzer, heartbeat = env.idmef_db.getAnalyzer(analyzerid)
        delta = float(heartbeat["create_time"]) - time.time()
        analyzer.last_heartbeat_time = localization.format_timedelta(delta, add_direction=True)

        analyzer.status = None
        analyzer.events = [ ]

        idents = env.idmef_db.getHeartbeatIdents(criteria="heartbeat.analyzer(-1).analyzerid == %s" % analyzerid,
                                                      limit=self._heartbeat_count)
        prev = None
        latest = True
        total_interval = 0

        for idx, ident in enumerate(idents):
            cur = env.idmef_db.getHeartbeat(ident)["heartbeat"]
            cur_status, cur_interval, cur_time = cur.get("additional_data('Analyzer status').data")[0], cur["heartbeat_interval"], cur["create_time"]
            cur_time_str = localization.format_datetime(float(cur_time))

            try:
                prev = env.idmef_db.getHeartbeat(idents[idx + 1])["heartbeat"]
                prev_status, prev_time = prev.get("additional_data('Analyzer status').data")[0], prev["create_time"]
            except:
                break

            if not cur_status or not cur_interval:
                continue

            total_interval += int(cur_interval)

            if latest:
                latest = False
                analyzer.status, analyzer.status_meaning = \
                    utils.get_analyzer_status_from_latest_heartbeat(cur, self._heartbeat_error_margin)
                if analyzer.status == "missing":
                    delta = time.time() - float(cur_time)
                    analyzer.events.append({ "time": cur_time_str, "value": _("Sensor is down since %s") % localization.format_timedelta(delta), "type": "down"})

            event = None
            if cur_status == "starting":
                if prev_status == "exiting":
                    event = { "time": cur_time_str, "value": _("Normal sensor start"), "type": "start" }
                else:
                    event = { "time": cur_time_str, "value": _("Unexpected sensor restart"), "type": "unexpected_restart" }

            elif cur_status == "running":
                delta = abs(int(cur_time) - int(prev_time) - int(cur_interval))
                if delta > self._heartbeat_error_margin:
                    delta = localization.format_timedelta(delta, granularity="second")
                    event = { "time": cur_time_str, "value": _("Unexpected heartbeat interval: %(delta)s") % {'delta': delta}, "type": "abnormal_heartbeat_interval" }


            elif cur_status == "exiting":
                event = { "time": cur_time_str, "value": _("Normal sensor stop"), "type": "normal_stop" }


            if event:
                analyzer.events.append(event)


        if not analyzer.status:
            analyzer.status, analyzer.status_meaning = "unknown", _("Unknown")

        if not analyzer.events:
            delta = localization.format_timedelta(total_interval / self._heartbeat_count)
            analyzer.events.append({ "time": "", "value":
                                     _("No anomaly in the last %(count)d heartbeats (one heartbeat every %(delta)s average)") %
                                       {'count': self._heartbeat_count, 'delta':delta}, "type": "no_anomaly" })

        self.dataset["analyzer"] = analyzer