Commit ba7c2ca0 authored by Andrey Vertiprahov's avatar Andrey Vertiprahov
Browse files

Merge branch 'backport-5698' into 'release-20.4'

release-20.4:Backport!5698 Fix UI MIB's tree for multiple root.

See merge request noc/noc!5779
parents d4e489d0 74db6a39
# ---------------------------------------------------------------------
# fm.mib application
# ---------------------------------------------------------------------
# Copyright (C) 2007-2019 The NOC Project
# Copyright (C) 2007-2021 The NOC Project
# See LICENSE for details
# ---------------------------------------------------------------------
# Third-party modules
import networkx as nx
# NOC modules
from import ExtDocApplication, view
from import MIB
......@@ -54,18 +57,76 @@ class MIBApplication(ExtDocApplication):
for c in data["children"]:
def oid_to_list(oid):
return [int(x) for x in oid.split(".")]
def list_to_oid(li):
return ".".join(str(x) for x in li)
def find_start_node(s):
path = oid_to_list(s.pop())
if len(s) == 0:
return path
for i in s:
pathi = oid_to_list(i)
if len(path) > len(pathi):
path = pathi
elif len(path) == len(pathi):
path = pathi if path[-1] > pathi[-1] else path
return path
def find_root_node(g):
root = None
for n in g.nodes(data=True):
if root is None or len(root[1]["ds"]["path"]) > len(n[1]["ds"]["path"]):
root = n
return root[0]
G = nx.DiGraph()
mib = self.get_object_or_404(MIB, id=id)
data = {"oid": "", "leaf": True, "path": []}
for d in MIBData.objects.filter("oid"):
ds = {
"oid": d.oid,
"path": [int(x) for x in d.oid.split(".")],
"path": oid_to_list(d.oid),
"leaf": True,
"description": d.description,
"syntax": self.get_syntax(d),
insert_tree(data, ds)
G.add_node(ds["oid"], ds=ds)
for child in G.nodes(data=True):
for parent in G.nodes(data=True):
if (
child[1]["ds"]["oid"] != parent[1]["ds"]["oid"]
and parent[1]["ds"]["path"] == child[1]["ds"]["path"][:-1]
G.add_edge(parent[0], child[0])
while sum(1 for x in nx.connected_components(G.to_undirected())) != 1:
for g in nx.connected_components(G.to_undirected()):
start_node = find_start_node(g)
oid_new_node = list_to_oid(start_node[:-1])
path_new_node = start_node[:-1]
"oid": oid_new_node,
"name": "",
"path": path_new_node,
"leaf": False,
"decription": "",
G.add_edge(oid_new_node, list_to_oid(start_node))
for parent in G.nodes(data=True):
if (
oid_new_node != parent[1]["ds"]["oid"]
and parent[1]["ds"]["path"] == path_new_node[:-1]
G.add_edge(parent[0], oid_new_node)
for a in nx.dfs_tree(G, find_root_node(G)):
insert_tree(data, nx.get_node_attributes(G, "ds")[a])
return data
......@@ -100,10 +161,10 @@ class MIBApplication(ExtDocApplication):
errors = {}
while len(left):
n = len(left)
for name in left:
for name in list(left.keys()):
svc = open_sync_rpc("mib")
r = svc.compile(left[name].read())
r = svc.compile(MIB.guess_encoding(left[name].read()))
if r.get("status"):
del left[name]
if name in errors:
......@@ -115,8 +176,9 @@ class MIBApplication(ExtDocApplication):
if len(left) == n:
# Failed to upload anything, stopping
r = {"success": len(left) == 0, "errors": errors}
return r
return self.render_json(
{"success": len(left) == 0, "message": f"ERROR: {errors}"}, status=self.OK
@view(url="^(?P<id>[0-9a-f]{24})/text/$", method=["GET"], access="launch", api=True)
def api_text(self, request, id):
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment