Пример #1
0
 def process_segment(r, segment):
     # Self alarms
     if segment.id in aseg:
         for a in aseg[segment.id]:
             r["alarms"] += [{
                 "alarm_id": a.id,
                 "object": a.managed_object,
                 "alarm": a,
                 "severity": a.severity,
                 "timestamp": a.timestamp,
                 "duration": a.display_duration,
                 "escalation_tt": a.escalation_tt or "",
                 "summary": {
                     "subscriber":
                     SummaryItem.items_to_dict(a.direct_subscribers),
                     "service":
                     SummaryItem.items_to_dict(a.direct_services)
                 }
             }]
     for ns in NetworkSegment.objects.filter(parent=segment.id):
         if ns.id not in seen_seg:
             continue
         sr = {
             "segment": ns,
             "children": [],
             "alarms": [],
             "summary": {
                 "subscriber": {},
                 "service": {}
             }
         }
         process_segment(sr, ns)
         r["children"] += [sr]
Пример #2
0
 def get_data(self):
     r = self.object.copy()
     if r["resolved"]:
         r["duration"] = r["close_ts"] - r["open_ts"]
     else:
         r["duration"] = datetime.datetime.now() - r["open_ts"]
     r["alarms"] = []
     now = datetime.datetime.now()
     for ac in (ActiveAlarm, ArchivedAlarm):
         for a in ac.objects.filter(escalation_tt=r["full_id"]):
             if a.status == "C":
                 duration = a.clear_timestamp - a.timestamp
             else:
                 duration = now - a.timestamp
             r["alarms"] += [{
                 "alarm": a,
                 "id": a.id,
                 "timestamp": a.timestamp,
                 "duration": duration,
                 "subject": a.subject,
                 "summary": {
                     "subscriber":
                     SummaryItem.items_to_dict(a.total_subscribers),
                     "service":
                     SummaryItem.items_to_dict(a.total_services)
                 }
             }]
     return r
Пример #3
0
 def get_data(self):
     # Calculate contained objects
     summary = {
         "service": SummaryItem.items_to_dict(self.object.total_services),
         "subscriber": SummaryItem.items_to_dict(self.object.total_subscribers)
     }
     objects = []
     for mo in self.object.managed_objects.filter(is_managed=True):
         ss = ServiceSummary.get_object_summary(mo)
         objects += [{
             "id": mo.id,
             "name": mo.name,
             "object": mo,
             "summary": ss
         }]
     # Update object statuses
     mos = [o["id"] for o in objects]
     alarms = set(d["managed_object"] for d in ActiveAlarm._get_collection().find({
         "managed_object": {
             "$in": mos
         }
     }, {"_id": 0, "managed_object": 1}))
     o_status = ObjectStatus.get_statuses(mos)
     for o in objects:
         if o["id"] in o_status:
             if o["id"] in alarms:
                 o["status"] = "alarm"
             else:
                 o["status"] = "up"
         else:
             o["status"] = "down"
     # Calculate children
     children = []
     for ns in NetworkSegment.objects.filter(parent=self.object.id):
         children += [{
             "id": ns.id,
             "name": ns.name,
             "object": ns,
             "summary": {
                 "service": SummaryItem.items_to_dict(ns.total_services),
                 "subscriber": SummaryItem.items_to_dict(ns.total_subscribers),
             }
         }]
     # Calculate VLANs
     vlans = []
     if self.object.vlan_border:
         vlans = list(VLAN.objects.filter(segment=self.object.id).order_by("vlan"))
     #
     return {
         "object": self.object,
         "managed_objects": sorted(objects, key=operator.itemgetter("name")),
         "children": sorted(children, key=operator.itemgetter("name")),
         "parent": self.object.parent,
         "summary": summary,
         "vlans": vlans
     }
Пример #4
0
 def flatten(ca, r, level):
     ca._level = level
     ca.service_summary = {
         "service": SummaryItem.items_to_dict(ca.direct_services),
         "subscriber": SummaryItem.items_to_dict(ca.direct_subscribers)
     }
     r += [ca]
     if hasattr(ca, "_children"):
         for c in sorted(ca._children,
                         key=operator.attrgetter("timestamp")):
             flatten(c, r, level + 1)
Пример #5
0
    def get_data(self):
        def update_dict(d1, d2):
            for k in d2:
                if k in d1:
                    d1[k] += d2[k]
                else:
                    d1[k] = d2[k]

        summary = {"subscriber": {}, "service": {}}
        if self.current_user.is_superuser:
            qs = ActiveAlarm.objects.filter(root__exists=False)
        else:
            qs = ActiveAlarm.objects.filter(
                adm_path__in=self.get_user_domains(), root__exists=False)
        for a in qs.only("total_subscribers", "total_services"):
            update_dict(summary["subscriber"],
                        SummaryItem.items_to_dict(a.total_subscribers or []))
            update_dict(summary["service"],
                        SummaryItem.items_to_dict(a.total_services or []))
        return {
            "summary": summary,
            "is_clear": not summary["subscriber"] and not summary["service"],
        }
Пример #6
0
    def update_summary(self):
        def update_dict(d1, d2):
            for k in d2:
                if k in d1:
                    d1[k] += d2[k]
                else:
                    d1[k] = d2[k]

        services = SummaryItem.items_to_dict(self.direct_services)
        subscribers = SummaryItem.items_to_dict(self.direct_subscribers)
        objects = {
            self.managed_object.object_profile.id: 1
        }

        for a in ActiveAlarm.objects.filter(root=self.id):
            a.update_summary()
            update_dict(
                objects,
                SummaryItem.items_to_dict(a.total_objects)
            )
            update_dict(
                services,
                SummaryItem.items_to_dict(a.total_services)
            )
            update_dict(
                subscribers,
                SummaryItem.items_to_dict(a.total_subscribers)
            )
        obj_list = ObjectSummaryItem.dict_to_items(objects)
        svc_list = SummaryItem.dict_to_items(services)
        sub_list = SummaryItem.dict_to_items(subscribers)
        if svc_list != self.total_services or sub_list != self.total_subscribers or obj_list != self.total_objects:
            ns = ServiceSummary.get_severity({
                "service": services,
                "subscriber": subscribers,
                "objects": objects
            })
            self.total_objects = obj_list
            self.total_services = svc_list
            self.total_subscribers = sub_list
            if ns != self.severity:
                self.change_severity(severity=ns, to_save=False)
            self.safe_save()
Пример #7
0
    def get_data(self):
        def get_segment_path(segment):
            if segment.parent:
                return segment_path[segment.parent] + [segment]
            else:
                return [segment]

        def update_summary(segment):
            """
            Calculate summary for segment and all nested segments
            """
            services = {}
            subscribers = {}
            # Calculate direct segments' coverage
            for o in segment["objects"].values():
                update_dict(services, o["services"])
                update_dict(subscribers, o["subscribers"])
            # Flatten objects
            segment["objects"] = sorted(segment["objects"].values(), key=lambda x: -x["weight"])
            # Calculate children's coverage
            for s in segment["segments"].values():
                update_summary(s)
                update_dict(services, s["services"])
                update_dict(subscribers, s["subscribers"])
            segment["segments"] = sorted(segment["segments"].values(), key=lambda x: -x["weight"])
            segment["services"] = services
            segment["subscribers"] = subscribers
            segment["summary"] = {"service": services, "subscriber": subscribers}
            segment["weight"] = ServiceSummary.get_weight(segment["summary"])

        def update_dict(d1, d2):
            for k in d2:
                if k in d1:
                    d1[k] += d2[k]
                else:
                    d1[k] = d2[k]

        segment_path = cachetools.LRUCache(maxsize=10000)
        segment_path.__missing__ = get_segment_path
        # Build tree
        tree = {"segment": None, "segments": {}, "objects": {}, "subscribers": {}, "services": {}}
        if self.current_user.is_superuser:
            qs = ActiveAlarm.objects.filter(root__exists=False)
        else:
            qs = ActiveAlarm.objects.filter(
                adm_path__in=self.get_user_domains(), root__exists=False
            )
        now = datetime.datetime.now()
        for alarm in qs:
            if not alarm.total_services and not alarm.total_subscribers:
                continue
            ct = tree
            for sp in segment_path[alarm.managed_object.segment]:
                if sp.id not in ct["segments"]:
                    ct["segments"][sp.id] = {
                        "segment": sp,
                        "segments": {},
                        "objects": {},
                        "subscribers": {},
                        "services": {},
                    }
                ct = ct["segments"][sp.id]
            subscribers = SummaryItem.items_to_dict(alarm.total_subscribers)
            services = SummaryItem.items_to_dict(alarm.total_services)
            ct["objects"][alarm.id] = {
                "object": alarm.managed_object,
                "alarm": alarm,
                "severity": alarm.severity,
                "timestamp": alarm.timestamp,
                "duration": now - alarm.timestamp,
                "escalation_tt": alarm.escalation_tt,
                "subscribers": subscribers,
                "services": services,
                "summary": {"subscriber": subscribers, "service": services},
            }
            ct["objects"][alarm.id]["weight"] = ServiceSummary.get_weight(
                ct["objects"][alarm.id]["summary"]
            )
        # Calculate segment summaries
        update_summary(tree)
        # Calculate total summaries
        services = {}
        subscribers = {}
        for s in tree["segments"]:
            update_dict(services, s["summary"]["service"])
            update_dict(subscribers, s["summary"]["subscriber"])
        for o in tree["objects"]:
            update_dict(services, o["summary"]["service"])
            update_dict(subscribers, o["summary"]["subscriber"])
        tree["summary"] = {"subscriber": subscribers, "service": services}
        return tree
Пример #8
0
    def instance_to_dict(self, o, fields=None):
        s = AlarmSeverity.get_severity(o.severity)
        n_events = (ActiveEvent.objects.filter(alarms=o.id).count() +
                    ArchivedEvent.objects.filter(alarms=o.id).count())
        mtc = o.managed_object.id in Maintenance.currently_affected()
        if o.status == "C":
            # For archived alarms
            mtc = Maintenance.objects.filter(
                start__lte=o.clear_timestamp,
                stop__lte=o.timestamp,
                affected_objects__in=[
                    MaintenanceObject(object=o.managed_object)
                ]).count() > 0

        d = {
            "id":
            str(o.id),
            "status":
            o.status,
            "managed_object":
            o.managed_object.id,
            "managed_object__label":
            o.managed_object.name,
            "administrative_domain":
            o.managed_object.administrative_domain_id,
            "administrative_domain__label":
            o.managed_object.administrative_domain.name,
            "severity":
            o.severity,
            "severity__label":
            s.name,
            "alarm_class":
            str(o.alarm_class.id),
            "alarm_class__label":
            o.alarm_class.name,
            "timestamp":
            self.to_json(o.timestamp),
            "subject":
            o.subject,
            "events":
            n_events,
            "duration":
            o.duration,
            "clear_timestamp":
            self.to_json(o.clear_timestamp) if o.status == "C" else None,
            "row_class":
            s.style.css_class_name,
            "segment__label":
            o.managed_object.segment.name,
            "segment":
            str(o.managed_object.segment.id),
            "location_1":
            self.location(o.managed_object.container.id)[0]
            if o.managed_object.container else "",
            "location_2":
            self.location(o.managed_object.container.id)[1]
            if o.managed_object.container else "",
            "escalation_tt":
            o.escalation_tt,
            "escalation_error":
            o.escalation_error,
            "platform":
            o.managed_object.platform.name
            if o.managed_object.platform else "",
            "address":
            o.managed_object.address,
            "isInMaintenance":
            mtc,
            "summary":
            self.f_glyph_summary({
                "subscriber":
                SummaryItem.items_to_dict(o.total_subscribers),
                "service":
                SummaryItem.items_to_dict(o.total_services)
            }),
            "total_objects":
            sum(x.summary for x in o.total_objects)
        }
        if fields:
            d = dict((k, d[k]) for k in fields)
        return d
Пример #9
0
    def get_ajax_data(self, **kwargs):
        def update_dict(d, s):
            for k in s:
                if k in d:
                    d[k] += s[k]
                else:
                    d[k] = s[k]

        zoom = int(self.handler.get_argument("z"))
        west = float(self.handler.get_argument("w"))
        east = float(self.handler.get_argument("e"))
        north = float(self.handler.get_argument("n"))
        south = float(self.handler.get_argument("s"))
        ms = int(self.handler.get_argument("maintenance"))
        active_layers = [
            l for l in self.get_pop_layers()
            if l.min_zoom <= zoom <= l.max_zoom
        ]
        alarms = []
        services = {}
        subscribers = {}
        t_data = defaultdict(list)
        if self.current_user.is_superuser:
            qs = ActiveAlarm.objects.all()
        else:
            qs = ActiveAlarm.objects.filter(
                adm_path__in=self.get_user_domains())
        if ms == 0:
            # Filter out equipment under maintenance
            qs = qs.filter(
                managed_object__nin=Maintenance.currently_affected())
        for a in qs.only("id", "managed_object", "direct_subscribers",
                         "direct_services"):
            s_sub, s_service = {}, {}
            if a.direct_subscribers:
                s_sub = SummaryItem.items_to_dict(a.direct_subscribers)
            if a.direct_services:
                s_service = SummaryItem.items_to_dict(a.direct_services)
            mo = a.managed_object
            if not mo:
                continue
            if mo.x and mo.y:
                w = ServiceSummary.get_weight({
                    "subscriber": s_sub,
                    "service": s_service
                })
                # @todo: Should we add the object's weight to summary?
                # @todo: Check west/south hemisphere
                if active_layers and west <= mo.x <= east and south <= mo.y <= north:
                    t_data[mo.x, mo.y] += [(mo, w)]
            else:
                w = 0
            alarms += [{
                "alarm_id": str(a.id),
                "managed_object": mo.name,
                "x": mo.x,
                "y": mo.y,
                "w": max(w, 1),
            }]
            if s_service:
                update_dict(services, s_service)
            if s_sub:
                update_dict(subscribers, s_sub)
        links = None
        o_seen = set()
        points = None
        o_data = {}
        if t_data and active_layers:
            # Create lines
            bbox = get_bbox(west, east, north, south)
            lines = []
            for d in ObjectConnection._get_collection().find(
                {
                    "type": "pop_link",
                    "layer": {
                        "$in": [l.id for l in active_layers]
                    },
                    "line": {
                        "$geoIntersects": {
                            "$geometry": bbox
                        }
                    },
                },
                {
                    "_id": 0,
                    "connection": 1,
                    "line": 1
                },
            ):
                for c in d["line"]["coordinates"]:
                    if tuple(c) in t_data:
                        for c in d["line"]["coordinates"]:
                            tc = tuple(c)
                            o_data[tc] = t_data.get(tc, [])
                        o_seen.add(tuple(c))
                        lines += [d["line"]]
                        break
            if lines:
                links = geojson.FeatureCollection(features=lines)
            # Create points
            points = []
            for x, y in o_data:
                mos = {}
                for mo, w in o_data[x, y]:
                    if mo not in mos:
                        mos[mo] = w
                mos = sorted(mos, key=lambda z: mos[z],
                             reverse=True)[:self.TOOLTIP_LIMIT]
                points += [
                    geojson.Feature(
                        geometry=geojson.Point(coordinates=[x, y]),
                        properties={
                            "alarms":
                            len(t_data[x, y]),
                            "objects": [{
                                "id": mo.id,
                                "name": mo.name,
                                "address": mo.address
                            } for mo in mos],
                        },
                    )
                ]
            points = geojson.FeatureCollection(features=points)
        return {
            "alarms":
            alarms,
            "summary":
            self.f_glyph_summary({
                "service": services,
                "subscriber": subscribers
            }),
            "links":
            links,
            "pops":
            points,
        }
Пример #10
0
    def get_data(self):
        def get_container_path(self):
            # Get container path
            if not self.object:
                return None
            cp = []
            if self.object.container:
                c = self.object.container.id
                while c:
                    try:
                        o = Object.objects.get(id=c)
                        # @todo: Address data
                        if o.container:
                            cp.insert(0, {"id": o.id, "name": o.name})
                        c = o.container.id if o.container else None
                    except DoesNotExist:
                        metrics["error", ("type", "no_such_object")] += 1
                        break
            return cp

        if not self.object:
            return None
        # @todo: Stage
        # @todo: Service range
        # @todo: Open TT
        now = datetime.datetime.now()
        # Get object status and uptime

        alarms = list(
            ActiveAlarm.objects.filter(managed_object=self.object.id))

        current_start = None
        duration = None
        if self.object.is_managed:
            if self.object.get_status():
                if alarms:
                    current_state = "alarm"
                else:
                    current_state = "up"
                uptime = Uptime.objects.filter(object=self.object.id,
                                               stop=None).first()
                if uptime:
                    current_start = uptime.start
            else:
                current_state = "down"
                outage = Outage.objects.filter(object=self.object.id,
                                               stop=None).first()
                if outage is not None:
                    current_start = outage.start
        else:
            current_state = "unmanaged"
        if current_start:
            duration = now - current_start

        cp = get_container_path(self)

        # MAC addresses
        macs = []
        o_macs = DiscoveryID.macs_for_object(self.object)
        if o_macs:
            for f, l in o_macs:
                if f == l:
                    macs += [f]
                else:
                    macs += ["%s - %s" % (f, l)]

        # Links
        uplinks = set(self.object.data.uplinks)
        if len(uplinks) > 1:
            if self.object.segment.lost_redundancy:
                redundancy = "L"
            else:
                redundancy = "R"
        else:
            redundancy = "N"
        links = []
        for l in Link.object_links(self.object):
            local_interfaces = []
            remote_interfaces = []
            remote_objects = set()
            for i in l.interfaces:
                if i.managed_object.id == self.object.id:
                    local_interfaces += [i]
                else:
                    remote_interfaces += [i]
                    remote_objects.add(i.managed_object)
            if len(remote_objects) == 1:
                ro = remote_objects.pop()
                if ro.id in uplinks:
                    role = "uplink"
                else:
                    role = "downlink"
                links += [{
                    "id":
                    l.id,
                    "role":
                    role,
                    "local_interface":
                    sorted(local_interfaces,
                           key=lambda x: split_alnum(x.name)),
                    "remote_object":
                    ro,
                    "remote_interface":
                    sorted(remote_interfaces,
                           key=lambda x: split_alnum(x.name)),
                    "remote_status":
                    "up" if ro.get_status() else "down",
                }]
            links = sorted(
                links,
                key=lambda x: (x["role"] != "uplink",
                               split_alnum(x["local_interface"][0].name)),
            )
        # Build global services summary
        service_summary = ServiceSummary.get_object_summary(self.object)

        # Interfaces
        interfaces = []
        metrics_map = [
            "Interface | Load | In",
            "Interface | Load | Out",
            "Interface | Errors | In",
            "Interface | Errors | Out",
        ]

        mo = ManagedObject.objects.filter(id=self.object.id)

        ifaces_metrics, last_ts = get_interface_metrics(mo[0])
        ifaces_metrics = ifaces_metrics[mo[0]]

        objects_metrics, last_time = get_objects_metrics(mo[0])
        objects_metrics = objects_metrics.get(mo[0])

        meta = {}
        metric_type_name = dict(MetricType.objects.filter().scalar(
            "name", "measure"))
        metric_type_field = dict(MetricType.objects.filter().scalar(
            "field_name", "measure"))
        if objects_metrics:
            for path, mres in six.iteritems(objects_metrics):
                for key in mres:
                    metric_name = "%s | %s" % (key, path) if any(
                        path.split("|")) else key
                    meta[metric_name] = {
                        "type": metric_type_name[key],
                        "value": mres[key]
                    }

        for i in Interface.objects.filter(managed_object=self.object.id,
                                          type="physical"):
            load_in = "-"
            load_out = "-"
            errors_in = "-"
            errors_out = "-"
            iface_metrics = ifaces_metrics.get(str(i.name))
            if iface_metrics:
                for key, value in six.iteritems(iface_metrics):
                    if key not in metrics_map:
                        continue
                    metric_type = metric_type_name.get(
                        key) or metric_type_field.get(key)
                    if key == "Interface | Load | In":
                        load_in = ("%s%s" %
                                   (self.humanize_speed(value, metric_type),
                                    metric_type) if value else "-")
                    if key == "Interface | Load | Out":
                        load_out = ("%s%s" %
                                    (self.humanize_speed(value, metric_type),
                                     metric_type) if value else "-")
                    if key == "Interface | Errors | In":
                        errors_in = value if value else "-"
                    if key == "Interface | Errors | Out":
                        errors_out = value if value else "-"
            interfaces += [{
                "id":
                i.id,
                "name":
                i.name,
                "admin_status":
                i.admin_status,
                "oper_status":
                i.oper_status,
                "mac":
                i.mac or "",
                "full_duplex":
                i.full_duplex,
                "load_in":
                load_in,
                "load_out":
                load_out,
                "errors_in":
                errors_in,
                "errors_out":
                errors_out,
                "speed":
                max([i.in_speed or 0, i.out_speed or 0]) / 1000,
                "untagged_vlan":
                None,
                "tagged_vlan":
                None,
                "profile":
                i.profile,
                "service":
                i.service,
                "service_summary":
                service_summary.get("interface").get(i.id, {}),
                "description":
                i.description,
            }]

            si = list(i.subinterface_set.filter(enabled_afi="BRIDGE"))
            if len(si) == 1:
                si = si[0]
                interfaces[-1]["untagged_vlan"] = si.untagged_vlan
                interfaces[-1]["tagged_vlans"] = list_to_ranges(
                    si.tagged_vlans).replace(",", ", ")
        interfaces = sorted(interfaces, key=lambda x: split_alnum(x["name"]))
        # Resource groups
        # Service groups (i.e. server)
        static_services = set(self.object.static_service_groups)
        service_groups = []
        for rg_id in self.object.effective_service_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            service_groups += [{
                "id": rg_id,
                "name": rg.name,
                "technology": rg.technology,
                "is_static": rg_id in static_services,
            }]
        # Client groups (i.e. client)
        static_clients = set(self.object.static_client_groups)
        client_groups = []
        for rg_id in self.object.effective_client_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            client_groups += [{
                "id": rg_id,
                "name": rg.name,
                "technology": rg.technology,
                "is_static": rg_id in static_clients,
            }]
        # @todo: Administrative domain path
        # Alarms
        alarm_list = []
        for a in alarms:
            alarm_list += [{
                "id": a.id,
                "root_id": self.get_root(alarms),
                "timestamp": a.timestamp,
                "duration": now - a.timestamp,
                "subject": a.subject,
                "managed_object": a.managed_object,
                "service_summary": {
                    "service": SummaryItem.items_to_dict(a.total_services),
                    "subscriber":
                    SummaryItem.items_to_dict(a.total_subscribers),
                },
                "alarm_class": a.alarm_class,
            }]
        alarm_list = sorted(alarm_list, key=operator.itemgetter("timestamp"))

        # Maintenance
        maintenance = []
        for m in Maintenance.objects.filter(
                affected_objects__object=self.object.id,
                is_completed=False,
                start__lte=now + datetime.timedelta(hours=1),
        ):
            maintenance += [{
                "maintenance": m,
                "id": m.id,
                "subject": m.subject,
                "start": m.start,
                "stop": m.stop,
                "in_progress": m.start <= now,
            }]
        # Get Inventory
        inv = []
        for p in self.object.get_inventory():
            c = self.get_nested_inventory(p)
            c["name"] = p.name or self.object.name
            inv += [c]
        # Build result

        if self.object.platform is not None:
            platform = self.object.platform.name
        else:
            platform = "Unknown"
        if self.object.version is not None:
            version = self.object.version.version
        else:
            version = ""

        r = {
            "id":
            self.object.id,
            "object":
            self.object,
            "name":
            self.object.name,
            "address":
            self.object.address,
            "platform":
            platform,
            # self.object.platform.name if self.object.platform else "Unknown",
            "version":
            version,
            # self.object.version.version if self.object.version else "",
            "description":
            self.object.description,
            "object_profile":
            self.object.object_profile.id,
            "object_profile_name":
            self.object.object_profile.name,
            "macs":
            ", ".join(sorted(macs)),
            "segment":
            self.object.segment,
            "firmware_status":
            FirmwarePolicy.get_status(self.object.platform,
                                      self.object.version),
            "firmware_recommended":
            FirmwarePolicy.get_recommended_version(self.object.platform),
            "service_summary":
            service_summary,
            "container_path":
            cp,
            "current_state":
            current_state,
            # Start of uptime/downtime
            "current_start":
            current_start,
            # Current uptime/downtime
            "current_duration":
            duration,
            "service_groups":
            service_groups,
            "client_groups":
            client_groups,
            "tt": [],
            "links":
            links,
            "alarms":
            alarm_list,
            "interfaces":
            interfaces,
            "metrics":
            meta,
            "maintenance":
            maintenance,
            "redundancy":
            redundancy,
            "inventory":
            self.flatten_inventory(inv),
            "serial_number":
            self.object.get_attr("Serial Number"),
            "attributes":
            list(
                ManagedObjectAttribute.objects.filter(
                    managed_object=self.object.id)),
            "confdb":
            self.object.get_confdb(),
        }
        return r
Пример #11
0
    def update_summary(self):
        """
        Update summaries
        :return:
        """
        def update_dict(d1, d2):
            for k in d2:
                if k in d1:
                    d1[k] += d2[k]
                else:
                    d1[k] = d2[k]

        objects = dict(
            (d["object_profile"], d["count"])
            for d in self.managed_objects.values(
                "object_profile"
            ).annotate(
                count=Count("id")
            ).order_by("count"))
        # Direct services
        mo_ids = self.managed_objects.values_list("id", flat=True)
        services, subscribers = ServiceSummary.get_direct_summary(mo_ids)
        self.direct_services = SummaryItem.dict_to_items(services)
        self.direct_subscribers = SummaryItem.dict_to_items(subscribers)
        self.direct_objects = ObjectSummaryItem.dict_to_items(objects)
        siblings = set()
        for ns in NetworkSegment.objects.filter(parent=self.id):
            if ns.id in siblings:
                continue
            update_dict(services, SummaryItem.items_to_dict(ns.total_services))
            update_dict(subscribers, SummaryItem.items_to_dict(ns.total_subscribers))
            update_dict(objects, ObjectSummaryItem.items_to_dict(ns.total_objects))
            siblings.add(ns.id)
            if ns.sibling:
                siblings.add(ns.sibling.id)
        self.total_services = SummaryItem.dict_to_items(services)
        self.total_subscribers = SummaryItem.dict_to_items(subscribers)
        self.total_objects = ObjectSummaryItem.dict_to_items(objects)
        self.save()
        # Update upwards
        ns = self.parent
        while ns:
            services = SummaryItem.items_to_dict(ns.direct_services)
            subscribers = SummaryItem.items_to_dict(ns.direct_subscribers)
            objects = ObjectSummaryItem.items_to_dict(ns.direct_objects)
            for nsc in NetworkSegment.objects.filter(parent=ns.id):
                update_dict(services, SummaryItem.items_to_dict(nsc.total_services))
                update_dict(subscribers, SummaryItem.items_to_dict(nsc.total_subscribers))
                update_dict(objects, ObjectSummaryItem.items_to_dict(nsc.total_objects))
            ns.total_services = SummaryItem.dict_to_items(services)
            ns.total_subscribers = SummaryItem.dict_to_items(subscribers)
            ns.total_objects = ObjectSummaryItem.dict_to_items(objects)
            ns.save()
            ns = ns.parent
Пример #12
0
 def raise_alarm(self, r, e):
     managed_object = self.eval_expression(r.managed_object, event=e)
     if not managed_object:
         self.logger.info("Empty managed object, ignoring")
         return
     # @todo: Make configurable
     if not managed_object.is_managed:
         self.logger.info(
             "Managed object is not managed. Do not raise alarm")
         return
     if e.managed_object.id != managed_object.id:
         metrics["alarm_change_mo"] += 1
         self.logger.info("Changing managed object to %s",
                          managed_object.name)
     discriminator, vars = r.get_vars(e)
     if r.unique:
         assert discriminator is not None
         a = ActiveAlarm.objects.filter(
             managed_object=managed_object.id,
             discriminator=discriminator).first()
         if not a:
             # Try to reopen alarm
             a = ArchivedAlarm.objects.filter(
                 managed_object=managed_object.id,
                 discriminator=discriminator,
                 control_time__gte=e.timestamp).first()
             if a:
                 # Reopen alarm
                 self.logger.info("[%s|%s|%s] %s reopens alarm %s(%s)",
                                  e.id, managed_object.name,
                                  managed_object.address,
                                  e.event_class.name, a.alarm_class.name,
                                  a.id)
                 a = a.reopen("Reopened by disposition rule '%s'" %
                              r.u_name)
                 metrics["alarm_reopen"] += 1
         if a:
             # Active alarm found, refresh
             self.logger.info(
                 "[%s|%s|%s] Contributing event %s to active alarm %s(%s)",
                 e.id, managed_object.name, managed_object.address,
                 e.event_class.name, a.alarm_class.name, a.id)
             # Contribute event to alarm
             e.contribute_to_alarm(a)
             if e.timestamp < a.timestamp:
                 # Set to earlier date
                 a.timestamp = e.timestamp
                 a.save()
             elif e.timestamp > a.last_update:
                 # Refresh last update
                 a.last_update = e.timestamp
                 a.save()
             metrics["alarm_contribute"] += 1
             return
     # Calculate alarm coverage
     summary = ServiceSummary.get_object_summary(managed_object)
     summary["object"] = {managed_object.object_profile.id: 1}
     #
     severity = max(ServiceSummary.get_severity(summary), 1)
     self.logger.info("[%s|%s|%s] %s: Calculated alarm severity is: %s",
                      e.id, managed_object.name, managed_object.address,
                      r.u_name, severity)
     # Create new alarm
     a = ActiveAlarm(
         timestamp=e.timestamp,
         last_update=e.timestamp,
         managed_object=managed_object.id,
         alarm_class=r.alarm_class,
         severity=severity,
         vars=vars,
         discriminator=discriminator,
         direct_services=SummaryItem.dict_to_items(summary["service"]),
         direct_subscribers=SummaryItem.dict_to_items(
             summary["subscriber"]),
         total_objects=ObjectSummaryItem.dict_to_items(summary["object"]),
         total_services=SummaryItem.dict_to_items(summary["service"]),
         total_subscribers=SummaryItem.dict_to_items(summary["subscriber"]),
         log=[
             AlarmLog(timestamp=datetime.datetime.now(),
                      from_status="A",
                      to_status="A",
                      message="Alarm risen from event %s(%s) by rule '%s'" %
                      (str(e.id), str(e.event_class.name), r.u_name))
         ],
         opening_event=e.id)
     a.save()
     e.contribute_to_alarm(a)
     self.logger.info("[%s|%s|%s] %s raises alarm %s(%s): %r", e.id,
                      managed_object.name, managed_object.address,
                      e.event_class.name, a.alarm_class.name, a.id, a.vars)
     metrics["alarm_raise"] += 1
     self.correlate(r, a)
     # Notify about new alarm
     if not a.root:
         a.managed_object.event(
             a.managed_object.EV_ALARM_RISEN, {
                 "alarm": a,
                 "subject": a.subject,
                 "body": a.body,
                 "symptoms": a.alarm_class.symptoms,
                 "recommended_actions": a.alarm_class.recommended_actions,
                 "probable_causes": a.alarm_class.probable_causes
             },
             delay=a.alarm_class.get_notification_delay())
     # Gather diagnostics when necessary
     AlarmDiagnosticConfig.on_raise(a)
     # Watch for escalations, when necessary
     if config.correlator.auto_escalation and not a.root:
         AlarmEscalation.watch_escalations(a)
Пример #13
0
 def get_data(self):
     if not self.object:
         return None
     # Get container path
     cp = []
     if self.object.managed_object.container:
         c = self.object.managed_object.container.id
         while c:
             try:
                 o = Object.objects.get(id=c)
                 # @todo: Address data
                 if o.container:
                     cp.insert(0, {"id": o.id, "name": o.name})
                 c = o.container.id if o.container else None
             except DoesNotExist:
                 metrics["error", ("type", "user_not_found")] += 1
                 break
     # Build log
     log = []
     if self.object.log:
         log = [{
             "timestamp": l.timestamp,
             "from_status": l.from_status,
             "to_status": l.to_status,
             "message": l.message
         } for l in self.object.log]
     # Build alarm tree
     alarms = self.get_alarms()
     # Service summary
     service_summary = {
         "service": SummaryItem.items_to_dict(self.object.total_services),
         "subscriber":
         SummaryItem.items_to_dict(self.object.total_subscribers)
     }
     # Maintenance
     mainteinance = Maintenance.objects.filter(
         is_completed=False,
         start__lte=datetime.datetime.now(),
         affected_objects__in=[
             MaintenanceObject(object=self.object.managed_object)
         ])
     mo = self.object.managed_object
     # Build result
     r = {
         "id":
         self.object.id,
         "alarm":
         self.object,
         "severity":
         AlarmSeverity.get_severity(self.object.severity),
         "managed_object":
         self.object.managed_object,
         "timestamp":
         self.object.timestamp,
         "duration":
         self.object.display_duration,
         "subject":
         self.object.subject,
         "body":
         self.object.body,
         "container_path":
         cp,
         "log":
         log,
         "service_summary":
         service_summary,
         "alarms":
         alarms,
         "diagnostic":
         AlarmDiagnostic.get_diagnostics(self.object),
         "maintenance":
         mainteinance,
         "lon":
         mo.x,
         "lat":
         mo.y,
         "zoom":
         mo.default_zoom,
         "tt_system":
         self.object.managed_object.tt_system.name
         if self.object.managed_object.tt_system else None,
         "tt_system_failed":
         (self.object.status == "A" and not self.object.escalation_tt
          and self.object.managed_object.tt_system
          and self.object.managed_object.tt_system.is_failed()),
         "escalation_ctx":
         self.object.escalation_ctx,
         "escalation_close_ctx":
         getattr(self.object, "escalation_close_ctx", None)
     }
     return r
Пример #14
0
    def instance_to_dict(self, o, fields=None):
        s = AlarmSeverity.get_severity(o.severity)
        n_events = (ActiveEvent.objects.filter(alarms=o.id).count() +
                    ArchivedEvent.objects.filter(alarms=o.id).count())

        d = {
            "id":
            str(o.id),
            "status":
            o.status,
            "managed_object":
            o.managed_object.id,
            "managed_object__label":
            o.managed_object.name,
            "administrative_domain":
            o.managed_object.administrative_domain_id,
            "administrative_domain__label":
            o.managed_object.administrative_domain.name,
            "severity":
            o.severity,
            "severity__label":
            s.name,
            "alarm_class":
            str(o.alarm_class.id),
            "alarm_class__label":
            o.alarm_class.name,
            "timestamp":
            self.to_json(o.timestamp),
            "subject":
            o.subject,
            "events":
            n_events,
            "duration":
            o.duration,
            "clear_timestamp":
            self.to_json(o.clear_timestamp) if o.status == "C" else None,
            "row_class":
            s.style.css_class_name,
            "segment__label":
            o.managed_object.segment.name,
            "segment":
            str(o.managed_object.segment.id),
            "location_1":
            self.location(o.managed_object.container.id)[0]
            if o.managed_object.container else "",
            "location_2":
            self.location(o.managed_object.container.id)[1]
            if o.managed_object.container else "",
            "escalation_tt":
            o.escalation_tt,
            "escalation_error":
            o.escalation_error,
            "platform":
            o.managed_object.platform.name
            if o.managed_object.platform else "",
            "address":
            o.managed_object.address,
            "ack_ts":
            self.to_json(o.ack_ts),
            "ack_user":
            o.ack_user,
            "summary":
            self.f_glyph_summary({
                "subscriber":
                SummaryItem.items_to_dict(o.total_subscribers),
                "service":
                SummaryItem.items_to_dict(o.total_services),
            }),
            "total_objects":
            sum(x.summary for x in o.total_objects),
            "total_subscribers":
            self.f_summary(
                {"subscriber":
                 SummaryItem.items_to_dict(o.total_subscribers)}),
            "total_services":
            self.f_summary(
                {"service": SummaryItem.items_to_dict(o.total_services)}),
            "logs": [{
                "timestamp": self.to_json(ll.timestamp),
                "user": ll.source or "NOC",
                "message": ll.message,
            } for ll in o.log if getattr(ll, "source", None)
                     ][:config.web.api_alarm_comments_limit],
        }
        if fields:
            d = {k: d[k] for k in fields}
        return d
Пример #15
0
    def get_data(self):

        intervals = (
            ("y", 31557617),  # 60 * 60 * 24 * 7 * 52
            ("w", 604800),  # 60 * 60 * 24 * 7
            ("d", 86400),  # 60 * 60 * 24
            ("h", 3600),  # 60 * 60
            ("m", 60),
            ("s", 1),
        )

        def display_time(seconds):
            result = []

            for name, count in intervals:
                value = seconds // count
                if value:
                    seconds -= value * count
                    if value == 1:
                        name = name.rstrip("s")
                    result.append("{}{}".format(value, name))
            return ", ".join(result[:-1])

        def sortdict(dct):
            kys = sorted(dct.keys())
            res = OrderedDict()
            for x in kys:
                for k, v in dct.items():
                    if k == x:
                        res[k] = v
            return res

        def get_container_path(self):
            # Get container path
            if not self.object:
                return None
            cp = []
            if self.object.container:
                c = self.object.container.id
                while c:
                    try:
                        o = Object.objects.get(id=c)
                        # @todo: Address data
                        if o.container:
                            cp.insert(0, {"id": o.id, "name": o.name})
                        c = o.container.id if o.container else None
                    except DoesNotExist:
                        metrics["error", ("type", "no_such_object")] += 1
                        break
            return cp

        if not self.object:
            return None
        # @todo: Stage
        # @todo: Service range
        # @todo: Open TT
        now = datetime.datetime.now()
        # Get object status and uptime

        alarms = list(ActiveAlarm.objects.filter(managed_object=self.object.id))

        current_start = None
        duration = None
        if self.object.is_managed:
            if self.object.get_status():
                if alarms:
                    current_state = "alarm"
                else:
                    current_state = "up"
                uptime = Uptime.objects.filter(object=self.object.id, stop=None).first()
                if uptime:
                    current_start = uptime.start
            else:
                current_state = "down"
                outage = Outage.objects.filter(object=self.object.id, stop=None).first()
                if outage is not None:
                    current_start = outage.start
        else:
            current_state = "unmanaged"
        if current_start:
            duration = now - current_start

        cp = get_container_path(self)

        # MAC addresses
        macs = []
        o_macs = DiscoveryID.macs_for_object(self.object)
        if o_macs:
            for f, l in o_macs:
                if f == l:
                    macs += [f]
                else:
                    macs += ["%s - %s" % (f, l)]
        # Hostname
        hostname = ""
        did = DiscoveryID.objects.filter(object=self.object.id).first()
        if did and did.hostname:
            hostname = did.hostname
        # Links
        uplinks = set(self.object.data.uplinks)
        if len(uplinks) > 1:
            if self.object.segment.lost_redundancy:
                redundancy = "L"
            else:
                redundancy = "R"
        else:
            redundancy = "N"
        links = []
        for _link in Link.object_links(self.object):
            local_interfaces = []
            remote_interfaces = []
            remote_objects = set()
            for iface in _link.interfaces:
                if iface.managed_object.id == self.object.id:
                    local_interfaces += [iface]
                else:
                    remote_interfaces += [iface]
                    remote_objects.add(iface.managed_object)
            if len(remote_objects) == 1:
                ro = remote_objects.pop()
                if ro.id in uplinks:
                    role = "uplink"
                else:
                    role = "downlink"
                links += [
                    {
                        "id": _link.id,
                        "role": role,
                        "local_interface": sorted(
                            local_interfaces, key=lambda x: alnum_key(x.name)
                        ),
                        "remote_object": ro,
                        "remote_interface": sorted(
                            remote_interfaces, key=lambda x: alnum_key(x.name)
                        ),
                        "remote_status": "up" if ro.get_status() else "down",
                    }
                ]
            links = sorted(
                links,
                key=lambda x: (x["role"] != "uplink", alnum_key(x["local_interface"][0].name)),
            )
        # Build global services summary
        service_summary = ServiceSummary.get_object_summary(self.object)

        # Interfaces
        interfaces = []

        mo = ManagedObject.objects.filter(id=self.object.id)
        mo = mo[0]

        ifaces_metrics, last_ts = get_interface_metrics(mo)
        ifaces_metrics = ifaces_metrics[mo]

        objects_metrics, last_time = get_objects_metrics(mo)
        objects_metrics = objects_metrics.get(mo)

        # Sensors
        sensors_metrics = None
        s_metrics = None
        sensors = {}
        s_meta = []
        STATUS = {0: "OK", 1: "Alarm"}
        meric_map = {}
        if mo.get_caps().get("Sensor | Controller"):
            for mc in MetricType.objects.filter(scope=MetricScope.objects.get(name="Environment")):
                if meric_map:
                    meric_map["map"].update({mc.field_name: mc.name})
                else:
                    meric_map = {"table_name": mc.scope.table_name, "map": {mc.field_name: mc.name}}
            sensors_metrics, last_ts = get_interface_metrics(mo, meric_map)
            sensors_metrics = sensors_metrics[mo]

        m_tp = {}
        if mo.object_profile.metrics:
            for mt in mo.object_profile.metrics:
                if mt.get("threshold_profile"):
                    threshold_profile = ThresholdProfile.get_by_id(mt.get("threshold_profile"))
                    m_tp[MetricType.get_by_id(mt.get("metric_type")).name] = threshold_profile
        data = {}
        meta = []
        metric_type_name = dict(MetricType.objects.filter().scalar("name", "measure"))
        metric_type_field = dict(MetricType.objects.filter().scalar("field_name", "measure"))
        if objects_metrics:
            for path, mres in objects_metrics.items():
                t_v = False
                for key in mres:
                    m_path = path if any(path.split("|")) else key
                    m_path = " | ".join(kk.strip() for kk in m_path.split("|"))
                    if m_tp.get(key):
                        t_v = self.get_threshold_config(m_tp.get(key), int(mres[key]))
                    val = {
                        "name": m_path,
                        "type": "" if m_path == "Object | SysUptime" else metric_type_name[key],
                        "value": display_time(int(mres[key]))
                        if m_path == "Object | SysUptime"
                        else mres[key],
                        "threshold": t_v,
                    }
                    if data.get(key):
                        data[key] += [val]
                    else:
                        data[key] = [val]

        data = sortdict(data)
        for k, d in data.items():
            collapsed = False
            if len(d) == 1:
                collapsed = True
            for dd in d:
                isdanger = False
                if dd["threshold"]:
                    isdanger = True
                    collapsed = True
            meta.append({"name": k, "value": d, "collapsed": collapsed, "isdanger": isdanger})

        for i in Interface.objects.filter(managed_object=self.object.id, type="physical"):
            load_in = "-"
            load_out = "-"
            errors_in = "-"
            errors_out = "-"
            iface_metrics = ifaces_metrics.get(str(i.name))

            if iface_metrics:
                for key, value in iface_metrics.items():
                    metric_type = metric_type_name.get(key) or metric_type_field.get(key)
                    if key == "Interface | Load | In":
                        load_in = (
                            "%s%s" % (self.humanize_speed(value, metric_type), metric_type)
                            if value
                            else "-"
                        )
                    if key == "Interface | Load | Out":
                        load_out = (
                            "%s%s" % (self.humanize_speed(value, metric_type), metric_type)
                            if value
                            else "-"
                        )
                    if key == "Interface | Errors | In":
                        errors_in = value if value else "-"
                    if key == "Interface | Errors | Out":
                        errors_out = value if value else "-"
            interfaces += [
                {
                    "id": i.id,
                    "name": i.name,
                    "admin_status": i.admin_status,
                    "oper_status": i.oper_status,
                    "mac": i.mac or "",
                    "full_duplex": i.full_duplex,
                    "load_in": load_in,
                    "load_out": load_out,
                    "errors_in": errors_in,
                    "errors_out": errors_out,
                    "speed": max([i.in_speed or 0, i.out_speed or 0]) / 1000,
                    "untagged_vlan": None,
                    "tagged_vlan": None,
                    "profile": i.profile,
                    "service": i.service,
                    "service_summary": service_summary.get("interface").get(i.id, {}),
                    "description": i.description,
                }
            ]
            if sensors_metrics:
                s_metrics = sensors_metrics.get(str(i.name))
            if s_metrics:
                sens_metrics = []
                for i_metrics in i.profile.metrics:
                    sens_metrics.append(i_metrics.metric_type.name)
                for key, value in s_metrics.items():
                    if key not in sens_metrics:
                        continue
                    val = {
                        "name": key,
                        "type": metric_type_name[key],
                        "value": STATUS.get(value) if metric_type_name[key] == " " else value,
                        "threshold": None,
                    }
                    if sensors.get(i.name):
                        sensors[i.name] += [val]
                    else:
                        sensors[i.name] = [val]

            si = list(i.subinterface_set.filter(enabled_afi="BRIDGE"))
            if len(si) == 1:
                si = si[0]
                interfaces[-1]["untagged_vlan"] = si.untagged_vlan
                interfaces[-1]["tagged_vlans"] = list_to_ranges(si.tagged_vlans).replace(",", ", ")

        if sensors:
            sensors = sortdict(sensors)
            for k, d in sensors.items():
                for dd in d:
                    isdanger = False
                    if dd["threshold"]:
                        isdanger = True
                s_meta.append({"name": k, "value": d, "isdanger": isdanger})

        interfaces = sorted(interfaces, key=lambda x: alnum_key(x["name"]))
        # Resource groups
        # Service groups (i.e. server)
        static_services = set(self.object.static_service_groups)
        service_groups = []
        for rg_id in self.object.effective_service_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            service_groups += [
                {
                    "id": rg_id,
                    "name": rg.name,
                    "technology": rg.technology,
                    "is_static": rg_id in static_services,
                }
            ]
        # Client groups (i.e. client)
        static_clients = set(self.object.static_client_groups)
        client_groups = []
        for rg_id in self.object.effective_client_groups:
            rg = ResourceGroup.get_by_id(rg_id)
            client_groups += [
                {
                    "id": rg_id,
                    "name": rg.name,
                    "technology": rg.technology,
                    "is_static": rg_id in static_clients,
                }
            ]
        # @todo: Administrative domain path
        # Alarms
        alarm_list = []
        for a in alarms:
            alarm_list += [
                {
                    "id": a.id,
                    "root_id": self.get_root(alarms),
                    "timestamp": a.timestamp,
                    "duration": now - a.timestamp,
                    "subject": a.subject,
                    "managed_object": a.managed_object,
                    "service_summary": {
                        "service": SummaryItem.items_to_dict(a.total_services),
                        "subscriber": SummaryItem.items_to_dict(a.total_subscribers),
                    },
                    "alarm_class": a.alarm_class,
                }
            ]
        alarm_list = sorted(alarm_list, key=operator.itemgetter("timestamp"))

        # Maintenance
        maintenance = []
        for m in Maintenance.objects.filter(
            affected_objects__object=self.object.id,
            is_completed=False,
            start__lte=now + datetime.timedelta(hours=1),
        ):
            maintenance += [
                {
                    "maintenance": m,
                    "id": m.id,
                    "subject": m.subject,
                    "start": m.start,
                    "stop": m.stop,
                    "in_progress": m.start <= now,
                }
            ]
        # Get Inventory
        inv = []
        for p in self.object.get_inventory():
            c = self.get_nested_inventory(p)
            c["name"] = p.name or self.object.name
            inv += [c]
        # Build result

        if self.object.platform is not None:
            platform = self.object.platform.name
        else:
            platform = "Unknown"
        if self.object.version is not None:
            version = self.object.version.version
        else:
            version = ""

        r = {
            "id": self.object.id,
            "object": self.object,
            "name": self.object.name,
            "address": self.object.address,
            "platform": platform,
            # self.object.platform.name if self.object.platform else "Unknown",
            "version": version,
            # self.object.version.version if self.object.version else "",
            "description": self.object.description,
            "object_profile": self.object.object_profile.id,
            "object_profile_name": self.object.object_profile.name,
            "hostname": hostname,
            "macs": ", ".join(sorted(macs)),
            "segment": self.object.segment,
            "firmware_status": FirmwarePolicy.get_status(self.object.platform, self.object.version),
            "firmware_recommended": FirmwarePolicy.get_recommended_version(self.object.platform),
            "service_summary": service_summary,
            "container_path": cp,
            "current_state": current_state,
            # Start of uptime/downtime
            "current_start": current_start,
            # Current uptime/downtime
            "current_duration": duration,
            "service_groups": service_groups,
            "client_groups": client_groups,
            "tt": [],
            "links": links,
            "alarms": alarm_list,
            "interfaces": interfaces,
            "metrics": meta,
            "sensors": s_meta,
            "maintenance": maintenance,
            "redundancy": redundancy,
            "inventory": self.flatten_inventory(inv),
            "serial_number": self.object.get_attr("Serial Number"),
            "attributes": list(
                ManagedObjectAttribute.objects.filter(managed_object=self.object.id)
            ),
            "confdb": None,
        }
        try:
            r["confdb"] = self.object.get_confdb()
        except (SyntaxError, ValueError):
            pass
        return r