Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topology view with overlapping regexps #1498

Closed
candlerb opened this issue Sep 15, 2017 · 3 comments · Fixed by #1598
Closed

Topology view with overlapping regexps #1498

candlerb opened this issue Sep 15, 2017 · 3 comments · Fixed by #1598
Labels
type: bug A confirmed report of unexpected behavior in the application

Comments

@candlerb
Copy link
Contributor

Issue type

[ ] Feature request
[X] Bug report
[ ] Documentation

Environment

  • Python version: 3.5.2
  • NetBox version: v2.2-beta1

Description

When I enter a topology description like this:

sw
.

I was expecting to see all devices with "sw" in their name on the top line, and all other devices on the line below.

What I actually see is all devices on the same line.

It's not entirely clear what the intended behaviour is here. What I was hoping is that if a device matches an earlier regex, it should be excluded from matching a later one.

If I change this to:

.
sw

then I also get all the devices on the same line - but in this case, the 'sw' device is on the right-hand end of the line.

If I make a regex which explicitly matches the other hosts by name (i.e. all those without 'sw' in them), it works - but it can be long and hard to maintain.

@jeremystretch
Copy link
Member

I was expecting to see all devices with "sw" in their name on the top line, and all other devices on the line below.

Each line is evaluated as an independent regex (or set of regexes separated by semicolons). You should be getting two rows: the first with all devices with "sw" in their name, and the second with all devices.

If I make a regex which explicitly matches the other hosts by name (i.e. all those without 'sw' in them), it works - but it can be long and hard to maintain.

Try:

sw
^((?!sw).)*$

@candlerb
Copy link
Contributor Author

Each line is evaluated as an independent regex (or set of regexes separated by semicolons). You should be getting two rows: the first with all devices with "sw" in their name, and the second with all devices.

That doesn't happen. And

.
.

just puts one instance of each device, all on the same line.

OK, I found the issue. If you repeat a node (with the same name) in graphviz, then it's not added as another node - it's just a repeat instance of the same node.

This fixes it for me:

--- a/netbox/extras/models.py
+++ b/netbox/extras/models.py
@@ -273,6 +273,7 @@ class TopologyMap(models.Model):
         # Construct the graph
         graph = graphviz.Graph()
         graph.graph_attr['ranksep'] = '1'
+        seen = set()
         for i, device_set in enumerate(self.device_sets):

             subgraph = graphviz.Graph(name='sg{}'.format(i))
@@ -287,7 +288,10 @@ class TopologyMap(models.Model):
             devices = []
             for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                 devices += Device.objects.filter(name__regex=query).select_related('device_role')
+            # Exclude nodes which have already been added
+            devices = [d for d in devices if d.id not in seen]
             for d in devices:
+                seen.add(d.id)
                 bg_color = '#{}'.format(d.device_role.color)
                 fg_color = '#{}'.format(foreground_color(d.device_role.color))
                 subgraph.node(d.name, style='filled', fillcolor=bg_color, fontcolor=fg_color, fontname='sans')

@candlerb
Copy link
Contributor Author

Or if you prefer stylistically:

--- a/netbox/extras/models.py
+++ b/netbox/extras/models.py
@@ -273,6 +273,7 @@ class TopologyMap(models.Model):
         # Construct the graph
         graph = graphviz.Graph()
         graph.graph_attr['ranksep'] = '1'
+        seen = set()
         for i, device_set in enumerate(self.device_sets):

             subgraph = graphviz.Graph(name='sg{}'.format(i))
@@ -287,6 +288,9 @@ class TopologyMap(models.Model):
             devices = []
             for query in device_set.strip(';').split(';'):  # Split regexes on semicolons
                 devices += Device.objects.filter(name__regex=query).select_related('device_role')
+            # Remove duplicate devices
+            devices = [d for d in devices if d.id not in seen]
+            seen.update([d.id for d in devices])
             for d in devices:
                 bg_color = '#{}'.format(d.device_role.color)
                 fg_color = '#{}'.format(foreground_color(d.device_role.color))

candlerb pushed a commit to candlerb/netbox that referenced this issue Oct 16, 2017
@jeremystretch jeremystretch added the type: bug A confirmed report of unexpected behavior in the application label Oct 16, 2017
@lock lock bot locked as resolved and limited conversation to collaborators Jan 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: bug A confirmed report of unexpected behavior in the application
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants