* Add model and individual option * Add forms and views * minor changes
This commit is contained in:
@@ -50,4 +50,4 @@ class PowerFeedCoordinateSerializer(NetBoxModelSerializer):
|
|||||||
class IndividualOptionsSerializer(NetBoxModelSerializer):
|
class IndividualOptionsSerializer(NetBoxModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IndividualOptions
|
model = IndividualOptions
|
||||||
fields = ("ignore_cable_type", "save_coords", "show_unconnected", "show_cables", "show_logical_connections", "show_single_cable_logical_conns", "show_neighbors", "show_circuit", "show_power", "show_wireless", "group_sites", "group_locations", "group_racks", "group_virtualchassis", "draw_default_layout", "straight_cables", "grid_size")
|
fields = ("ignore_cable_type", "save_coords", "show_unconnected", "show_cables", "show_logical_connections", "show_single_cable_logical_conns", "show_neighbors", "show_circuit", "show_power", "show_wireless", "group_sites", "group_locations", "group_racks", "group_virtualchassis", "draw_default_layout", "straight_cables", "grid_size", "node_label_items")
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class ExportTopoToXML(BaseViewSet, ViewSet):
|
|||||||
|
|
||||||
if request.GET:
|
if request.GET:
|
||||||
|
|
||||||
filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size = get_query_settings(request)
|
filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size, node_label_items = get_query_settings(request)
|
||||||
|
|
||||||
# Read options from saved filters as NetBox does not handle custom plugin filters
|
# Read options from saved filters as NetBox does not handle custom plugin filters
|
||||||
if "filter_id" in request.GET and request.GET["filter_id"] != '':
|
if "filter_id" in request.GET and request.GET["filter_id"] != '':
|
||||||
@@ -138,6 +138,7 @@ class ExportTopoToXML(BaseViewSet, ViewSet):
|
|||||||
if show_neighbors == False and 'show_neighbors' in saved_filter_params: show_neighbors = saved_filter_params['show_neighbors']
|
if show_neighbors == False and 'show_neighbors' in saved_filter_params: show_neighbors = saved_filter_params['show_neighbors']
|
||||||
if straight_cables == False and 'straight_cables' in saved_filter_params: show_neighbors = saved_filter_params['straight_cables']
|
if straight_cables == False and 'straight_cables' in saved_filter_params: show_neighbors = saved_filter_params['straight_cables']
|
||||||
if grid_size == 0 and 'grid_size' in saved_filter_params: grid_size = saved_filter_params['grid_size']
|
if grid_size == 0 and 'grid_size' in saved_filter_params: grid_size = saved_filter_params['grid_size']
|
||||||
|
if node_label_items == () and 'node_label_items' in saved_filter_params: node_label_items = saved_filter_params['node_label_items']
|
||||||
except SavedFilter.DoesNotExist: # filter_id not found
|
except SavedFilter.DoesNotExist: # filter_id not found
|
||||||
pass
|
pass
|
||||||
except Exception as inst:
|
except Exception as inst:
|
||||||
@@ -170,8 +171,9 @@ class ExportTopoToXML(BaseViewSet, ViewSet):
|
|||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
straight_cables=straight_cables,
|
straight_cables=straight_cables,
|
||||||
grid_size=grid_size,
|
grid_size=grid_size,
|
||||||
|
node_label_items=node_label_items,
|
||||||
)
|
)
|
||||||
xml_data = export_data_to_xml(topo_data).decode('utf-8')
|
xml_data = export_data_to_xml(topo_data).decode('utf-8').replace('\n', '
')
|
||||||
|
|
||||||
return HttpResponse(xml_data, content_type="application/xml; charset=utf-8")
|
return HttpResponse(xml_data, content_type="application/xml; charset=utf-8")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from utilities.choices import ChoiceSet
|
||||||
|
|
||||||
|
class NodeLabelItems(ChoiceSet):
|
||||||
|
DEVICE_NAME = 'devicename'
|
||||||
|
PRIMARY_IPV4 = 'primaryipv4'
|
||||||
|
PRIMARY_IPV6 = 'primaryipv6'
|
||||||
|
OUT_OF_BAND_IP = 'outofbandip'
|
||||||
|
|
||||||
|
CHOICES = [
|
||||||
|
(DEVICE_NAME, 'Device Name'),
|
||||||
|
(PRIMARY_IPV4, 'Primary IPv4'),
|
||||||
|
(PRIMARY_IPV6, 'Primary IPv6'),
|
||||||
|
(OUT_OF_BAND_IP, 'Out-of-band IP'),
|
||||||
|
]
|
||||||
@@ -23,6 +23,7 @@ from utilities.forms.fields import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from netbox_topology_views.models import IndividualOptions, CoordinateGroup, Coordinate, CircuitCoordinate, PowerPanelCoordinate, PowerFeedCoordinate
|
from netbox_topology_views.models import IndividualOptions, CoordinateGroup, Coordinate, CircuitCoordinate, PowerPanelCoordinate, PowerFeedCoordinate
|
||||||
|
from netbox_topology_views.choices import NodeLabelItems
|
||||||
|
|
||||||
class DeviceFilterForm(
|
class DeviceFilterForm(
|
||||||
LocalConfigContextFilterForm,
|
LocalConfigContextFilterForm,
|
||||||
@@ -36,7 +37,7 @@ class DeviceFilterForm(
|
|||||||
FieldSet(
|
FieldSet(
|
||||||
'group', 'ignore_cable_type', 'save_coords', 'show_unconnected', 'show_cables', 'show_logical_connections',
|
'group', 'ignore_cable_type', 'save_coords', 'show_unconnected', 'show_cables', 'show_logical_connections',
|
||||||
'show_single_cable_logical_conns', 'show_neighbors', 'show_circuit', 'show_power', 'show_wireless',
|
'show_single_cable_logical_conns', 'show_neighbors', 'show_circuit', 'show_power', 'show_wireless',
|
||||||
'group_sites', 'group_locations', 'group_racks', 'group_virtualchassis', 'straight_cables', 'grid_size', name=_("Options")
|
'group_sites', 'group_locations', 'group_racks', 'group_virtualchassis', 'straight_cables', 'grid_size', 'node_label_items', name=_("Options")
|
||||||
),
|
),
|
||||||
FieldSet('id', name=_("Device")),
|
FieldSet('id', name=_("Device")),
|
||||||
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', name=_("Location")),
|
FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', name=_("Location")),
|
||||||
@@ -335,6 +336,11 @@ class DeviceFilterForm(
|
|||||||
max_value=1000,
|
max_value=1000,
|
||||||
help_text=_('Show grid and snap dragged icons to grid. Set to 0 to disable grid and snapping.')
|
help_text=_('Show grid and snap dragged icons to grid. Set to 0 to disable grid and snapping.')
|
||||||
)
|
)
|
||||||
|
node_label_items = forms.MultipleChoiceField(
|
||||||
|
label=_('Node Label Items'),
|
||||||
|
required=False,
|
||||||
|
choices=NodeLabelItems
|
||||||
|
)
|
||||||
|
|
||||||
class CoordinateGroupsForm(NetBoxModelForm):
|
class CoordinateGroupsForm(NetBoxModelForm):
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
@@ -530,6 +536,7 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
'draw_default_layout',
|
'draw_default_layout',
|
||||||
'straight_cables',
|
'straight_cables',
|
||||||
'grid_size',
|
'grid_size',
|
||||||
|
'node_label_items',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -681,6 +688,12 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
'Integers between 0 and 1000 are allowed. Snap to grid will be '
|
'Integers between 0 and 1000 are allowed. Snap to grid will be '
|
||||||
'automatically enabled for values > 0.')
|
'automatically enabled for values > 0.')
|
||||||
)
|
)
|
||||||
|
node_label_items = forms.MultipleChoiceField(
|
||||||
|
label=_('Node Label Items'),
|
||||||
|
required=False,
|
||||||
|
choices=NodeLabelItems,
|
||||||
|
help_text=_('Choose Label Items that you want to be displayed.')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IndividualOptions
|
model = IndividualOptions
|
||||||
@@ -689,5 +702,5 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
'save_coords', 'show_unconnected', 'show_cables', 'show_logical_connections',
|
'save_coords', 'show_unconnected', 'show_cables', 'show_logical_connections',
|
||||||
'show_single_cable_logical_conns', 'show_neighbors', 'show_circuit', 'show_power',
|
'show_single_cable_logical_conns', 'show_neighbors', 'show_circuit', 'show_power',
|
||||||
'show_wireless', 'group_sites', 'group_locations', 'group_racks', 'group_virtualchassis', 'draw_default_layout',
|
'show_wireless', 'group_sites', 'group_locations', 'group_racks', 'group_virtualchassis', 'draw_default_layout',
|
||||||
'straight_cables', 'grid_size'
|
'straight_cables', 'grid_size', 'node_label_items'
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.0.9 on 2024-09-27 18:19
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('netbox_topology_views', '0010_individualoptions_grid_size'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='individualoptions',
|
||||||
|
name='node_label_items',
|
||||||
|
field=models.CharField(blank=True, max_length=255),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -25,6 +25,7 @@ from netbox_topology_views.utils import (
|
|||||||
image_static_url,
|
image_static_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from netbox_topology_views.choices import NodeLabelItems
|
||||||
|
|
||||||
class RoleImage(ChangeLoggingMixin, ExportTemplatesMixin, EventRulesMixin):
|
class RoleImage(ChangeLoggingMixin, ExportTemplatesMixin, EventRulesMixin):
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -407,7 +408,11 @@ class IndividualOptions(NetBoxModel):
|
|||||||
grid_size = models.PositiveSmallIntegerField(
|
grid_size = models.PositiveSmallIntegerField(
|
||||||
default=0
|
default=0
|
||||||
)
|
)
|
||||||
|
node_label_items = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
|
|
||||||
_netbox_private = True
|
_netbox_private = True
|
||||||
|
|
||||||
def __str___(self):
|
def __str___(self):
|
||||||
|
|||||||
@@ -200,7 +200,11 @@ def get_query_settings(request):
|
|||||||
if "grid_size" in request.GET:
|
if "grid_size" in request.GET:
|
||||||
grid_size = request.GET.getlist('grid_size')
|
grid_size = request.GET.getlist('grid_size')
|
||||||
|
|
||||||
return filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size
|
node_label_items = ()
|
||||||
|
if "node_label_items" in request.GET:
|
||||||
|
node_label_items = request.GET.getlist('node_label_items')
|
||||||
|
|
||||||
|
return filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size, node_label_items
|
||||||
|
|
||||||
class LinePattern():
|
class LinePattern():
|
||||||
wireless = [2, 10, 2, 10]
|
wireless = [2, 10, 2, 10]
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ from netbox_topology_views.utils import (
|
|||||||
IMAGE_FILETYPES
|
IMAGE_FILETYPES
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from netbox_topology_views.choices import NodeLabelItems
|
||||||
|
|
||||||
def get_image_for_entity(entity: Union[Device, Circuit, PowerPanel, PowerFeed]):
|
def get_image_for_entity(entity: Union[Device, Circuit, PowerPanel, PowerFeed]):
|
||||||
is_device = isinstance(entity, Device)
|
is_device = isinstance(entity, Device)
|
||||||
@@ -97,7 +97,10 @@ def get_image_for_entity(entity: Union[Device, Circuit, PowerPanel, PowerFeed]):
|
|||||||
|
|
||||||
|
|
||||||
def create_node(
|
def create_node(
|
||||||
device: Union[Device, Circuit, PowerPanel, PowerFeed], save_coords: bool, group_id="default"
|
device: Union[Device, Circuit, PowerPanel, PowerFeed],
|
||||||
|
save_coords: bool,
|
||||||
|
node_label_items: list,
|
||||||
|
group_id="default"
|
||||||
):
|
):
|
||||||
node = {}
|
node = {}
|
||||||
node_content = ""
|
node_content = ""
|
||||||
@@ -229,7 +232,22 @@ def create_node(
|
|||||||
dev_title = "<table><tbody> %s</tbody></table>" % (node_content)
|
dev_title = "<table><tbody> %s</tbody></table>" % (node_content)
|
||||||
node["title"] = dev_title
|
node["title"] = dev_title
|
||||||
node["name"] = dev_name
|
node["name"] = dev_name
|
||||||
node["label"] = dev_name
|
|
||||||
|
# Create a list of possible label items. Omit None types
|
||||||
|
label_mapping = {
|
||||||
|
NodeLabelItems.DEVICE_NAME: dev_name,
|
||||||
|
NodeLabelItems.PRIMARY_IPV4: device.primary_ip4,
|
||||||
|
NodeLabelItems.PRIMARY_IPV6: device.primary_ip6,
|
||||||
|
NodeLabelItems.OUT_OF_BAND_IP: device.oob_ip,
|
||||||
|
}
|
||||||
|
|
||||||
|
label_items = []
|
||||||
|
for item in node_label_items:
|
||||||
|
if label_mapping[item] is not None:
|
||||||
|
label_items.append(str(label_mapping[item]))
|
||||||
|
node_label = '\n'.join(label_items)
|
||||||
|
|
||||||
|
node["label"] = node_label
|
||||||
node["shape"] = "image"
|
node["shape"] = "image"
|
||||||
node["href"] = device.get_absolute_url()
|
node["href"] = device.get_absolute_url()
|
||||||
node["image"] = get_image_for_entity(device)
|
node["image"] = get_image_for_entity(device)
|
||||||
@@ -350,6 +368,7 @@ def get_topology_data(
|
|||||||
group_id,
|
group_id,
|
||||||
straight_cables: bool,
|
straight_cables: bool,
|
||||||
grid_size: list,
|
grid_size: list,
|
||||||
|
node_label_items: list,
|
||||||
):
|
):
|
||||||
|
|
||||||
supported_termination_types = []
|
supported_termination_types = []
|
||||||
@@ -698,7 +717,7 @@ def get_topology_data(
|
|||||||
results = {}
|
results = {}
|
||||||
|
|
||||||
for d in nodes_devices.values():
|
for d in nodes_devices.values():
|
||||||
nodes.append(create_node(d, save_coords, group_id))
|
nodes.append(create_node(d, save_coords, node_label_items, group_id))
|
||||||
|
|
||||||
results["nodes"] = nodes
|
results["nodes"] = nodes
|
||||||
results["edges"] = edges
|
results["edges"] = edges
|
||||||
@@ -729,7 +748,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
if request.GET:
|
if request.GET:
|
||||||
|
|
||||||
filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size = get_query_settings(request)
|
filter_id, ignore_cable_type, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, group_virtualchassis, group, show_neighbors, straight_cables, grid_size, node_label_items = get_query_settings(request)
|
||||||
|
|
||||||
# Read options from saved filters as NetBox does not handle custom plugin filters
|
# Read options from saved filters as NetBox does not handle custom plugin filters
|
||||||
if "filter_id" in request.GET and request.GET["filter_id"] != '':
|
if "filter_id" in request.GET and request.GET["filter_id"] != '':
|
||||||
@@ -753,6 +772,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
if show_neighbors == False and 'show_neighbors' in saved_filter_params: show_neighbors = saved_filter_params['show_neighbors']
|
if show_neighbors == False and 'show_neighbors' in saved_filter_params: show_neighbors = saved_filter_params['show_neighbors']
|
||||||
if straight_cables == False and 'straight_cables' in saved_filter_params: straight_cables = saved_filter_params['straight_cables']
|
if straight_cables == False and 'straight_cables' in saved_filter_params: straight_cables = saved_filter_params['straight_cables']
|
||||||
if grid_size == 0 and 'grid_size' in saved_filter_params: grid_size = saved_filter_params['grid_size']
|
if grid_size == 0 and 'grid_size' in saved_filter_params: grid_size = saved_filter_params['grid_size']
|
||||||
|
if node_label_items == () and 'node_label_items' in saved_filter_params: node_label_items = saved_filter_params['node_label_items']
|
||||||
except SavedFilter.DoesNotExist: # filter_id not found
|
except SavedFilter.DoesNotExist: # filter_id not found
|
||||||
pass
|
pass
|
||||||
except Exception as inst:
|
except Exception as inst:
|
||||||
@@ -787,6 +807,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
group_id=group_id,
|
group_id=group_id,
|
||||||
straight_cables=straight_cables,
|
straight_cables=straight_cables,
|
||||||
grid_size=grid_size,
|
grid_size=grid_size,
|
||||||
|
node_label_items=node_label_items,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -816,6 +837,10 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
if individualOptions.group_virtualchassis: q['group_virtualchassis'] = "True"
|
if individualOptions.group_virtualchassis: q['group_virtualchassis'] = "True"
|
||||||
if individualOptions.straight_cables: q['straight_cables'] = "True"
|
if individualOptions.straight_cables: q['straight_cables'] = "True"
|
||||||
if individualOptions.grid_size: q['grid_size'] = individualOptions.grid_size
|
if individualOptions.grid_size: q['grid_size'] = individualOptions.grid_size
|
||||||
|
node_label_items = IndividualOptions.objects.get(id=individualOptions.id).node_label_items.translate({ord(i): None for i in '[]\''}).split(', ')
|
||||||
|
if node_label_items == ['']: node_label_items = []
|
||||||
|
q.setlist("node_label_items", node_label_items)
|
||||||
|
|
||||||
if individualOptions.draw_default_layout:
|
if individualOptions.draw_default_layout:
|
||||||
q['draw_init'] = "True"
|
q['draw_init'] = "True"
|
||||||
else:
|
else:
|
||||||
@@ -1177,6 +1202,7 @@ class TopologyIndividualOptionsView(PermissionRequiredMixin, View):
|
|||||||
'draw_default_layout': queryset.draw_default_layout,
|
'draw_default_layout': queryset.draw_default_layout,
|
||||||
'straight_cables': queryset.straight_cables,
|
'straight_cables': queryset.straight_cables,
|
||||||
'grid_size': queryset.grid_size,
|
'grid_size': queryset.grid_size,
|
||||||
|
'node_label_items': tuple(queryset.node_label_items.translate({ord(i): None for i in '[]\''}).split(', ')),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user