Ejemplo n.º 1
0
 def update_name(self, object: Object):
     n = self.get_name(object, self.object)
     if n and n != object.name:
         object.name = n
         self.logger.info("Changing name to '%s'", n)
         object.save()
         object.log(
             "Change name to '%s'" % n,
             system="DISCOVERY",
             managed_object=self.object,
             op="CHANGE",
         )
Ejemplo n.º 2
0
 def api_add_group(self, request, type, name, container=None,
                   serial=None):
     if container is None:
         c = self.get_root()
     else:
         c = self.get_object_or_404(Object, id=container)
     m = self.get_object_or_404(ObjectModel, id=type)
     o = Object(name=name, model=m, container=c.id)
     if serial and m.get_data("asset", "part_no0"):
         o.set_data("asset", "serial", serial)
     o.save()
     o.log("Created", user=request.user.username,
           system="WEB", op="CREATE")
     return str(o.id)
Ejemplo n.º 3
0
 def api_create(self,
                request,
                model=None,
                name=None,
                srid=None,
                x=None,
                y=None):
     # Find suitable container
     to_pop = model.name == "Ducts | Cable Entry"
     p = (x, y, srid)
     if to_pop:
         # Cable entries are attached to nearest PoP
         pop_layers = list(Layer.objects.filter(code__startswith="pop_"))
         np, npd = map.find_nearest_d(p, pop_layers)
     else:
         # Or to the objects on same layer
         layer = Layer.objects.get(code=model.get_data("geopoint", "layer"))
         np, npd = map.find_nearest_d(p, layer)
     # Check nearest area
     layer = Layer.objects.get(code="areas")
     ap, apd = map.find_nearest_d(p, layer)
     if ap and (not np or apd < npd):
         np, npd = ap, apd
     # Check nearest city
     layer = Layer.objects.get(code="cities")
     ap, apd = map.find_nearest_d(p, layer)
     if ap and (not np or apd < npd):
         np, npd = ap, apd
     # Get best nearest container
     if to_pop and np.layer.code.startswith("pop_"):
         container = np.id
     else:
         container = np.container
     # Create object
     o = Object(
         name=name,
         model=model,
         container=container,
         data=[
             ObjectAttr(scope="",
                        interface="geopoint",
                        attr="srid",
                        value=srid),
             ObjectAttr(scope="", interface="geopoint", attr="x", value=x),
             ObjectAttr(scope="", interface="geopoint", attr="y", value=y),
         ],
     )
     o.save()
     return {"id": str(o.id)}
Ejemplo n.º 4
0
 def api_add_group(self, request, type, name, container=None, serial=None):
     if is_objectid(container):
         c = Object.get_by_id(container)
         if not c:
             return self.response_not_found()
         c = c.id
     elif container:
         return self.response_bad_request()
     m = ObjectModel.get_by_id(type)
     if not m:
         return self.response_not_found()
     o = Object(name=name, model=m, container=c)
     if serial and m.get_data("asset", "part_no0"):
         o.set_data("asset", "serial", serial)
     o.save()
     o.log("Created", user=request.user.username, system="WEB", op="CREATE")
     return str(o.id)
Ejemplo n.º 5
0
 def api_connect(
     self,
     request,
     object,
     name,
     remote_object,
     remote_name,
     cable: Optional[str] = None,
     reconnect=False,
 ):
     lo: Object = self.get_object_or_404(Object, id=object)
     ro: Object = self.get_object_or_404(Object, id=remote_object)
     cable_o: Optional[Object] = None
     if cable:
         cable = ObjectModel.get_by_name(cable)
         cable_o = Object(
             name="Wire %s:%s <-> %s:%s" %
             (lo.name, name, ro.name, remote_name),
             model=cable,
             container=lo.container.id,
         )
         cable_o.save()
     print(lo, ro, cable_o)
     try:
         if cable_o:
             c1, c2 = cable_o.model.connections[:2]
             self.logger.debug("Wired connect c1:c2", c1, c2)
             lo.connect_p2p(name, cable_o, c1.name, {}, reconnect=reconnect)
             ro.connect_p2p(remote_name,
                            cable_o,
                            c2.name, {},
                            reconnect=reconnect)
             lo.save()
             ro.save()
         else:
             lo.connect_p2p(name, ro, remote_name, {}, reconnect=reconnect)
     except ConnectionError as e:
         self.logger.warning("Connection Error: %s", str(e))
         return self.render_json({"status": False, "text": str(e)})
     return True
Ejemplo n.º 6
0
 def api_create_ducts(self, request, id, ducts=None):
     o = self.app.get_object_or_404(Object, id=id)
     conns = {}  # target -> conneciton
     for c, t, _ in o.get_genderless_connections("ducts"):
         conns[t] = c
     conduits = defaultdict(list)  # target, conduits
     for c, t, _ in o.get_genderless_connections("conduits"):
         for cc, tt, _ in t.get_genderless_connections("conduits"):
             if tt.id != o.id:
                 conduits[tt] += [t]
     left = set(conns)
     for cd in ducts:
         target = cd["target"]
         if target not in left:
             # New record
             o.connect_genderless(
                 "ducts",
                 target,
                 "ducts",
                 data={"project_distance": cd["project_distance"]},
                 type="ducts")
         else:
             c = conns[target]
             # Updated
             if cd["project_distance"] != c.data.get("project_distance"):
                 # Updated
                 c.data["project_distance"] = cd["project_distance"]
                 c.type = "ducts"
                 c.save()
             left.remove(target)
         left_conduits = set(conduits[target])
         for cc in cd["conduits"]:
             if "id" not in cc or cc["id"] not in left_conduits:
                 # Create new conduit
                 conduit = Object(name=str(cc["n"]),
                                  model=self.conduits_model)
                 conduit.save()
                 # Connect to both manholes
                 o.connect_genderless(
                     "conduits",
                     conduit,
                     "conduits",
                     data={
                         # Conduit position
                         "plan": {
                             "x": cc["x"],
                             "y": cc["y"]
                         }
                     },
                     type="conduits")
                 target.connect_genderless(
                     "conduits",
                     conduit,
                     "conduits",
                     data={
                         # @todo: Mirror position
                         # Conduit position
                         "plan": {
                             "x": cc["x"],
                             "y": cc["y"]
                         }
                     },
                     type="conduits")
             else:
                 # Change.
                 conduit = cc["id"]
                 for ccc, ro, _ in conduit.get_genderless_connections(
                         "conduits"):
                     odata = ccc.data.copy()
                     ccc.data["plan"]["x"] = cc["x"]
                     ccc.data["plan"]["y"] = cc["y"]
                     if ccc.data != odata:
                         ccc.save()
             if "id" in cc:
                 left_conduits.remove(cc["id"])
         for t in left_conduits:
             cc = left_conduits[t]
             print "DEL", cc
     # Deleted
     for x in left:
         for c, remote, _ in conns[x].get_genderless_connecitons(
                 "conduits"):
             remote.delete()
         conns[x].delete()
     return {"status": True}
Ejemplo n.º 7
0
 def submit(
     self,
     type: str,
     part_no: List[str],
     number: Optional[str] = None,
     builtin: bool = False,
     vendor: Optional[str] = None,
     revision: Optional[str] = None,
     serial: Optional[str] = None,
     mfg_date: Optional[str] = None,
     description: Optional[str] = None,
 ):
     # Check the vendor and the serial are sane
     # OEM transceivers return binary trash often
     if vendor:
         # Possible dead code
         try:
             vendor.encode("utf-8")
         except UnicodeDecodeError:
             self.logger.info("Trash submited as vendor id: %s",
                              vendor.encode("hex"))
             return
     if serial:
         # Possible dead code
         try:
             serial.encode("utf-8")
         except UnicodeDecodeError:
             self.logger.info("Trash submited as serial: %s",
                              serial.encode("hex"))
             return
     #
     is_unknown_xcvr = not builtin and part_no[0].startswith(
         "Unknown | Transceiver | ")
     if not type and is_unknown_xcvr:
         type = "XCVR"
     # Skip builtin modules
     if builtin:
         # Adjust context anyway
         self.prepare_context(type, number)
         return  # Builtin must aways have type set
     #
     if is_unknown_xcvr:
         self.logger.info("%s S/N %s should be resolved later", part_no[0],
                          serial)
         self.prepare_context(type, number)
         self.objects += [("XCVR", part_no[0], self.ctx.copy(), serial)]
         return
     # Cache description
     if description:
         for p in part_no:
             if p not in self.pn_description:
                 self.pn_description[p] = description
     # Find vendor
     vnd = self.get_vendor(vendor)
     if not vnd:
         # Try to resolve via model map
         m = self.get_model_map(vendor, part_no, serial)
         if not m:
             self.logger.error("Unknown vendor '%s' for S/N %s (%s)",
                               vendor, serial, description)
             return
     else:
         # Find model
         m = ObjectModel.get_model(vnd, part_no)
         if not m:
             # Try to resolve via model map
             m = self.get_model_map(vendor, part_no, serial)
             if not m:
                 self.logger.info(
                     "Unknown model: vendor=%s, part_no=%s (%s). "
                     "Skipping",
                     vnd.name,
                     part_no,
                     description,
                 )
                 self.register_unknown_part_no(vnd, part_no, description)
                 return
     # Sanitize serial number against the model
     serial = self.clean_serial(m, number, serial)
     #
     if m.cr_context and type != m.cr_context:
         # Override type with object mode's one
         self.logger.info("Model changes type to '%s'", m.cr_context)
         type = m.cr_context
     if not type:
         self.logger.info(
             "Cannot resolve type for: vendor=%s, part_no=%s (%s). "
             "Skipping",
             vnd.name,
             description,
             part_no,
         )
         return
     self.prepare_context(type, number)
     # Get connection rule
     if not self.rule and m.connection_rule:
         self.set_rule(m.connection_rule)
         # Set initial context
         if type in self.rule_context:
             scope = self.rule_context[type][0]
             if scope:
                 self.set_context(scope, number)
     # Find existing object or create new
     o: Optional["Object"] = Object.objects.filter(model=m.id,
                                                   data__match={
                                                       "interface": "asset",
                                                       "attr": "serial",
                                                       "value": serial
                                                   }).first()
     if not o:
         # Create new object
         self.logger.info("Creating new object. model='%s', serial='%s'",
                          m.name, serial)
         data = [
             ObjectAttr(scope="",
                        interface="asset",
                        attr="serial",
                        value=serial)
         ]
         if revision:
             data += [
                 ObjectAttr(scope="",
                            interface="asset",
                            attr="revision",
                            value=revision)
             ]
         if mfg_date:
             data += [
                 ObjectAttr(scope="",
                            interface="asset",
                            attr="mfg_date",
                            value=mfg_date)
             ]
         if self.object.container:
             container = self.object.container.id
         else:
             container = self.lost_and_found
         o = Object(model=m, data=data, container=container)
         o.save()
         o.log(
             "Created by asset_discovery",
             system="DISCOVERY",
             managed_object=self.object,
             op="CREATE",
         )
     else:
         # Add all connection to disconnect list
         self.to_disconnect.update(
             set((o, c[0], c[1], c[2]) for c in o.iter_inner_connections()))
     # Check revision
     if o.get_data("asset", "revision") != revision:
         # Update revision
         self.logger.info(
             "Object revision changed [%s %s] %s -> %s",
             m.name,
             o.id,
             o.get_data("asset", "revision"),
             revision,
         )
         o.set_data("asset", "revision", revision)
         o.save()
         o.log(
             "Object revision changed: %s -> %s" %
             (o.get_data("asset", "revision"), revision),
             system="DISCOVERY",
             managed_object=self.object,
             op="CHANGE",
         )
     # Check manufacturing date
     if mfg_date and o.get_data("asset", "revision") != revision:
         # Update revision
         self.logger.info(
             "Object manufacturing date changed [%s %s] %s -> %s",
             m.name,
             o.id,
             o.get_data("asset", "mfg_date"),
             mfg_date,
         )
         o.set_data("asset", "mfg_date", mfg_date)
         o.save()
         o.log(
             "Object manufacturing date: %s -> %s" %
             (o.get_data("asset", "mfg_date"), mfg_date),
             system="DISCOVERY",
             managed_object=self.object,
             op="CHANGE",
         )
     # Check management
     if o.get_data("management", "managed"):
         if o.get_data("management", "managed_object") != self.object.id:
             self.logger.info("Changing object management to '%s'",
                              self.object.name)
             o.set_data("management", "managed_object", self.object.id)
             o.save()
             o.log(
                 "Management granted",
                 system="DISCOVERY",
                 managed_object=self.object,
                 op="CHANGE",
             )
         self.update_name(o)
         if o.id in self.managed:
             self.managed.remove(o.id)
     self.objects += [(type, o, self.ctx.copy(), serial)]
     # Collect stack members
     if number and o.get_data("stack", "stackable"):
         self.stack_member[o] = number
Ejemplo n.º 8
0
 def resolve_object(self, name: str, m_c: str, t_object: Object, t_c: str,
                    serial: str) -> Optional["Object"]:
     """
     Resolve object type
     """
     # Check object is already exists
     c, object, c_name = t_object.get_p2p_connection(t_c)
     if c is not None:
         if c_name == m_c and object.get_data("asset", "serial") == serial:
             # Object with same serial number exists
             return object
         else:
             # Serial number/connection mismatch
             return None
     # Check connection type
     c = t_object.model.get_model_connection(t_c)
     if c is None:
         self.logger.error("Connection violation for %s SN %s", name,
                           serial)
         return None  # ERROR
     # Transceiver formfactor
     tp = c.type.name.split(" | ")
     ff = tp[1]
     m = "NoName | Transceiver | Unknown %s" % ff
     if name != "Unknown | Transceiver | Unknown":
         mtype = name[24:].upper().replace("-", "")
         if "BASE" in mtype:
             speed, ot = mtype.split("BASE", 1)
             spd = {"100": "100M", "1000": "1G", "10G": "10G"}.get(speed)
             if spd:
                 m = "NoName | Transceiver | %s | %s %s" % (spd, ff, ot)
             else:
                 self.logger.error("Unknown transceiver speed: %s", speed)
                 m = name
         else:
             m = name
     # Add vendor suffix when necessary
     if len(tp) == 3:
         m += " | %s" % tp[2]
     #
     if m in self.unk_model:
         model = self.unk_model[m]
     else:
         model = ObjectModel.objects.filter(name=m).first()
         self.unk_model[m] = model
     if not model:
         self.logger.error("Unknown model '%s'", m)
         self.register_unknown_part_no(self.get_vendor("NONAME"), m,
                                       "%s -> %s" % (name, m))
         return None
     # Create object
     self.logger.info("Creating new object. model='%s', serial='%s'", m,
                      serial)
     if self.object.container:
         container = self.object.container.id
     else:
         container = self.lost_and_found
     o = Object(
         model=model,
         data=[
             ObjectAttr(scope="",
                        interface="asset",
                        attr="serial",
                        value=serial)
         ],
         container=container,
     )
     o.save()
     o.log(
         "Created by asset_discovery",
         system="DISCOVERY",
         managed_object=self.object,
         op="CREATE",
     )
     return o
Ejemplo n.º 9
0
 def submit(self,
            type,
            part_no,
            number=None,
            builtin=False,
            vendor=None,
            revision=None,
            serial=None,
            description=None):
     # Check the vendor and the serial are sane
     # OEM transceivers return binary trash often
     if vendor:
         try:
             vendor.encode("utf-8")
         except UnicodeDecodeError:
             self.info("Trash submited as vendor id: %s" %
                       vendor.encode("hex"))
             return
     if serial:
         try:
             serial.encode("utf-8")
         except UnicodeDecodeError:
             self.info("Trash submited as serial: %s" %
                       serial.encode("hex"))
             return
     #
     is_unknown_xcvr = (not builtin and
                        part_no[0].startswith("Unknown | Transceiver | "))
     if not type and is_unknown_xcvr:
         type = "XCVR"
     # Skip builtin modules
     if builtin:
         # Adjust context anyway
         self.prepare_context(type, number)
         return  # Builtin must aways have type set
     #
     if is_unknown_xcvr:
         self.debug("%s S/N %s should be resolved later" %
                    (part_no[0], serial))
         self.prepare_context(type, number)
         self.objects += [("XCVR", part_no[0], self.ctx.copy(), serial)]
         return
     # Cache description
     if description:
         for p in part_no:
             if p not in self.pn_description:
                 self.pn_description[p] = description
     # Find vendor
     vnd = self.get_vendor(vendor)
     if not vnd:
         # Try to resolve via model map
         m = self.get_model_map(vendor, part_no, serial)
         if not m:
             self.error("Unknown vendor '%s' for S/N %s (%s)" %
                        (vendor, serial, description))
             return
     else:
         # Find model
         m = ObjectModel.get_model(vnd, part_no)
         if not m:
             # Try to resolve via model map
             m = self.get_model_map(vendor, part_no, serial)
             if not m:
                 self.debug(
                     "Unknown model: vendor=%s, part_no=%s (%s). Skipping" %
                     (vnd.name, description, part_no))
                 self.register_unknown_part_no(vnd, part_no, description)
                 return
     if m.cr_context and type != m.cr_context:
         # Override type with object mode's one
         self.debug("Model changes type to '%s'" % m.cr_context)
         type = m.cr_context
     if not type:
         self.debug(
             "Cannot resolve type for: vendor=%s, part_no=%s (%s). Skipping"
             % (vnd.name, description, part_no))
         return
     self.prepare_context(type, number)
     # Get connection rule
     if not self.rule and m.connection_rule:
         self.set_rule(m.connection_rule)
         # Set initial context
         if type in self.rule_context:
             scope = self.rule_context[type][0]
             if scope:
                 self.set_context(scope, number)
     #
     if not serial or serial == "None":
         serial = self.generate_serial(m, number)
         self.info("Generating virtual serial: %s" % serial)
     # Find existing object or create new
     o = Object.objects.filter(model=m.id,
                               data__asset__serial=serial).first()
     if not o:
         # Create new object
         self.info("Creating new object. model='%s', serial='%s'" %
                   (m.name, serial))
         data = {"asset": {"serial": serial}}
         if revision:
             data["asset"]["revision"] = revision
         o = Object(model=m, data=data, container=self.lost_and_found)
         o.save()
         o.log("Created by asset_discovery",
               system="DISCOVERY",
               managed_object=self.object,
               op="CREATE")
     # Check revision
     if o.get_data("asset", "revision") != revision:
         # Update revision
         self.info(
             "Object revision changed [%s %s] %s -> %s" %
             (m.name, o.id, o.get_data("asset", "revision"), revision))
         o.set_data("asset", "revision", revision)
         o.save()
         o.log("Object revision changed: %s -> %s" %
               (o.get_data("asset", "revision"), revision),
               system="DISCOVERY",
               managed_object=self.object,
               op="CHANGE")
     # Check management
     if o.get_data("management", "managed"):
         if o.get_data("management", "managed_object") != self.object.id:
             self.info("Changing object management to '%s'" %
                       self.object.name)
             o.set_data("management", "managed_object", self.object.id)
             o.save()
             o.log("Management granted",
                   system="DISCOVERY",
                   managed_object=self.object,
                   op="CHANGE")
         self.update_name(o)
         if o.id in self.managed:
             self.managed.remove(o.id)
     self.objects += [(type, o, self.ctx.copy(), serial)]
     # Collect stack members
     if number and o.get_data("stack", "stackable"):
         self.stack_member[o] = number