Esempio n. 1
0
 def find_object(self, v):
     """
     Find object by remote system/remote id
     :param v:
     :return:
     """
     if not v.get("remote_system") or not v.get("remote_id"):
         self.logger.warning("RS or RID not found")
         return None
     if not hasattr(self, "_service_remote_ids"):
         self.logger.info("Filling service collection")
         coll = ServiceModel._get_collection()
         self._service_remote_ids = {
             c["remote_id"]: c["_id"]
             for c in coll.find(
                 {
                     "remote_system": v["remote_system"].id,
                     "remote_id": {
                         "$exists": True
                     }
                 },
                 {
                     "remote_id": 1,
                     "_id": 1
                 },
             )
         }
     if v["remote_id"] in self._service_remote_ids:
         return ServiceModel.objects.get(
             id=self._service_remote_ids[v["remote_id"]])
     return None
Esempio n. 2
0
 def iter_services(sd):
     yield sd
     for cs in Service._get_collection().find(
         {
             "parent": sd["_id"],
             "logical_status": "R"
         }, {
             "_id": 1,
             "subscriber": 1,
             "profile": 1
         }):
         for ns in iter_services(cs):
             yield ns
Esempio n. 3
0
 def handler(self):
     self.logger.info("NRI Service Mapper")
     if not self.object.remote_system:
         self.logger.info(
             "Created directly. No NRI integration. Skipping check")
         return
     if not self.object.remote_system.enable_service:
         self.logger.info(
             "NRI does not provide link information. Skipping check")
         return
     # Check object has interfaces
     if not self.has_capability("DB | Interfaces"):
         self.logger.info(
             "No interfaces discovered. Skipping interface status check")
         return
     # Get services related to Managed object
     scol = Service._get_collection()
     slist = [
         s for s in scol.find(
             {
                 "managed_object": self.object.id,
                 "nri_port": {
                     "$exists": True
                 }
             },
             {
                 "_id": 1,
                 "nri_port": 1,
                 "profile": 1
             },
         )
     ]
     # nri_port -> service_id
     smap = {s["nri_port"]: s["_id"] for s in slist}
     # service id -> service profile
     prof_map = {
         s["_id"]: ServiceProfile.get_by_id(s["profile"])
         for s in slist
     }
     icol = Interface._get_collection()
     nmap = {}
     bulk = []
     for i in icol.find({
             "managed_object": self.object.id,
             "nri_name": {
                 "$exists": True
             }
     }):
         if not i.get("nri_name"):
             continue
         if i["nri_name"] in smap:
             svc = smap[i["nri_name"]]
             p = prof_map.get(svc)
             if svc != i.get("service"):
                 self.logger.info("Binding service %s to interface %s", svc,
                                  i["name"])
                 op = {"service": svc}
                 if p and p.interface_profile:
                     op["profile"] = p.interface_profile.id
                 bulk += [UpdateOne({"_id": i["_id"]}, {"$set": op})]
             elif p and p.interface_profile and p.interface_profile.id != i[
                     "profile"]:
                 self.logger.info("Replace profile to %s on intertace %s",
                                  p.interface_profile, i["name"])
                 bulk += [
                     UpdateOne(
                         {"_id": i["_id"]},
                         {"$set": {
                             "profile": p.interface_profile.id
                         }})
                 ]
             del smap[i["nri_name"]]
         elif i.get("service"):
             self.logger.info("Removing service %s from interface %s",
                              i["service"], i["name"])
             op = {"$unset": {"service": ""}}
             if i["service"] in prof_map:
                 op["$set"] = {
                     "profile": InterfaceProfile.get_default_profile().id
                 }
             bulk += [UpdateOne({"_id": i["_id"]}, op)]
         nmap[i["nri_name"]] = i
     # Report hanging interfaces
     for n in smap:
         svc = smap[n]
         if n not in nmap:
             self.logger.info(
                 "Cannot bind service %s. Cannot find NRI interface %s",
                 svc, n)
             continue
         i = nmap[n]
         self.logger.info("Binding service %s to interface %s", svc,
                          i["name"])
         op = {"service": svc}
         p = prof_map.get(svc)
         if p:
             op["profile"] = p.interface_profile.id
         bulk += [UpdateOne({"_id": i["_id"]}, {"$set": op})]
     if bulk:
         self.logger.info("Sending %d updates", len(bulk))
         icol.bulk_write(bulk)
         ServiceSummary.refresh_object(self.object.id)
         change_tracker.register([("managedobject", self.object.id)])
Esempio n. 4
0
    def build_summary_for_object(cls, managed_object):
        """
        Build active services summary for managed object
        :param managed_object: Managed Object id
        :return: dict of interface id -> {service: ..., subscriber: ....}
            interface None means unbound or box-wise services
        """
        from noc.inv.models.interface import Interface
        from noc.sa.models.service import Service

        def iter_services(sd):
            yield sd
            for cs in Service._get_collection().find(
                {
                    "parent": sd["_id"],
                    "logical_status": "R"
                }, {
                    "_id": 1,
                    "subscriber": 1,
                    "profile": 1
                }):
                for ns in iter_services(cs):
                    yield ns

        def add_dict(d1, d2):
            """
            Add all d2 values to d1
            :param d1:
            :param d2:
            :return:
            """
            for k in d2:
                d1[k] = d1.get(k, 0) + d2[k]

        # service -> interface bindings
        svc_interface = dict((
            x["service"], x["_id"]
        ) for x in Interface._get_collection().find(
            {
                "managed_object": managed_object,
                "service": {
                    "$exists": True
                }
            }, {
                "_id": 1,
                "service": 1
            },
            comment=
            "[servicesummary.build_summary_for_object] Getting services for interfaces"
        ))
        # Iterate over object's services
        # And walk underlying tree
        ri = {}
        for svc in Service._get_collection(
        ).find({
                "managed_object": managed_object,
                "logical_status": "R"
        }, {
                "_id": 1,
                "subscriber": 1,
                "profile": 1
        },
               comment=
               "[servicesummary.build_summary_for_object] Getting object services for object"
               ):
            # All subscribers for underlying tree
            subscribers = set()
            # profile_id -> count
            svc_profiles = defaultdict(int)
            for s in iter_services(svc):
                subscribers.add(s["subscriber"])
                svc_profiles[s["profile"]] += 1
            # Get subscriber profiles count
            ra = Subscriber._get_collection().aggregate([{
                "$match": {
                    "_id": {
                        "$in": list(subscribers)
                    }
                }
            }, {
                "$group": {
                    "_id": "$profile",
                    "total": {
                        "$sum": 1
                    }
                }
            }])
            subscriber_profiles = dict((x["_id"], x["total"]) for x in ra)
            # Bind to interface
            # None for unbound services
            iface = svc_interface.get(svc["_id"])
            if iface in ri:
                add_dict(ri[iface]["service"], svc_profiles)
                add_dict(ri[iface]["subscriber"], subscriber_profiles)
            else:
                ri[iface] = {
                    "service": dict(svc_profiles),  # defaultdict -> dict
                    "subscriber": subscriber_profiles
                }
        return ri