feat: integrate site prefix column from Netbox-Prefixes
Device and rack tables show the first word of the site name as the first data column. Replaces the separate netbox_site_prefix plugin and can be disabled with site_prefix_column_enabled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,7 @@ PLUGINS_CONFIG = {
|
|||||||
"topology_views_rack_width_enabled": True,
|
"topology_views_rack_width_enabled": True,
|
||||||
"tenant_filter_enabled": True,
|
"tenant_filter_enabled": True,
|
||||||
"tenant_required": True,
|
"tenant_required": True,
|
||||||
|
"site_prefix_column_enabled": True,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -246,8 +247,35 @@ Vor Produktivupdates sollte der neue Stand in einer Testumgebung geprüft
|
|||||||
werden. Ein Backup der NetBox-Datenbank bleibt unabhängig vom Plugin dringend
|
werden. Ein Backup der NetBox-Datenbank bleibt unabhängig vom Plugin dringend
|
||||||
empfohlen.
|
empfohlen.
|
||||||
|
|
||||||
|
### Umstieg von NetBox Site Prefix
|
||||||
|
|
||||||
|
Die Prefix-Spalte ist jetzt Teil von NetBox Utilities. Das separate Plugin
|
||||||
|
`netbox_site_prefix` muss entfernt werden, sonst wird die Spalte doppelt
|
||||||
|
registriert:
|
||||||
|
|
||||||
|
1. `"netbox_site_prefix"` aus `PLUGINS` in `configuration.py` entfernen.
|
||||||
|
2. Die Zeile `git+https://git.mrblake.cc/MrBlake/Netbox-Prefixes.git` aus
|
||||||
|
`/opt/netbox/local_requirements.txt` entfernen.
|
||||||
|
3. `/opt/netbox/venv/bin/pip uninstall netbox-site-prefix` ausführen und
|
||||||
|
NetBox neu starten.
|
||||||
|
|
||||||
|
Der Spaltenname `site_prefix` bleibt gleich, gespeicherte Tabellenkonfigurationen
|
||||||
|
der Benutzer funktionieren daher weiter.
|
||||||
|
|
||||||
## Verwendung
|
## Verwendung
|
||||||
|
|
||||||
|
### Prefix-Spalte in Geräte- und Rack-Listen
|
||||||
|
|
||||||
|
Die Geräte- und Rack-Listen erhalten eine Spalte **Prefix** als erste
|
||||||
|
Datenspalte. Der Wert ist das erste Wort des Standortnamens, z. B. `Berlin`
|
||||||
|
für `Berlin Campus West` oder `DC01` für `DC01 Frankfurt`; ohne Standort
|
||||||
|
bleibt die Zelle leer.
|
||||||
|
|
||||||
|
Hat ein Benutzer bereits eine eigene Spaltenauswahl gespeichert, hat diese
|
||||||
|
Vorrang. Dann unter **Spalten konfigurieren** die Spalte **Prefix** auswählen
|
||||||
|
und nach vorne schieben oder die Tabellenkonfiguration zurücksetzen. Mit
|
||||||
|
`"site_prefix_column_enabled": False` lässt sich die Spalte abschalten.
|
||||||
|
|
||||||
### Vorfilter für die B-Seite einer Verkabelung
|
### Vorfilter für die B-Seite einer Verkabelung
|
||||||
|
|
||||||
Beim Anlegen und Bearbeiten eines Kabels erscheint im Abschnitt **B-Seite**
|
Beim Anlegen und Bearbeiten eines Kabels erscheint im Abschnitt **B-Seite**
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class NetBoxUtilitiesConfig(PluginConfig):
|
|||||||
"tenant_filter_enabled": True,
|
"tenant_filter_enabled": True,
|
||||||
"tenant_required": True,
|
"tenant_required": True,
|
||||||
"offline_svg_export_enabled": True,
|
"offline_svg_export_enabled": True,
|
||||||
|
"site_prefix_column_enabled": True,
|
||||||
}
|
}
|
||||||
middleware = [
|
middleware = [
|
||||||
"netbox_utilities.middleware.GlobalTenantFilterMiddleware",
|
"netbox_utilities.middleware.GlobalTenantFilterMiddleware",
|
||||||
@@ -37,6 +38,10 @@ class NetBoxUtilitiesConfig(PluginConfig):
|
|||||||
install_tenant_validation()
|
install_tenant_validation()
|
||||||
install_patchpanel_automation()
|
install_patchpanel_automation()
|
||||||
install_rack_width_support()
|
install_rack_width_support()
|
||||||
|
if get_plugin_config("netbox_utilities", "site_prefix_column_enabled"):
|
||||||
|
from .site_prefix import install_site_prefix_column
|
||||||
|
|
||||||
|
install_site_prefix_column()
|
||||||
if get_plugin_config("netbox_utilities", "connection_vlans_enabled"):
|
if get_plugin_config("netbox_utilities", "connection_vlans_enabled"):
|
||||||
from .connection_vlans import install_connection_vlan_support
|
from .connection_vlans import install_connection_vlan_support
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
COLUMN_NAME = "site_prefix"
|
||||||
|
|
||||||
|
|
||||||
|
def first_word(value):
|
||||||
|
"""Return the first whitespace-delimited word of a value."""
|
||||||
|
words = str(value or "").split()
|
||||||
|
return words[0] if words else None
|
||||||
|
|
||||||
|
|
||||||
|
class SitePrefixColumn(tables.Column):
|
||||||
|
"""Render the first word of a record's site name."""
|
||||||
|
|
||||||
|
def render(self, value):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return first_word(value.name)
|
||||||
|
|
||||||
|
|
||||||
|
def prepend_to_default_columns(table):
|
||||||
|
"""Show the prefix column first for users without saved table preferences."""
|
||||||
|
defaults = tuple(table.Meta.default_columns)
|
||||||
|
table.Meta.default_columns = (
|
||||||
|
"pk",
|
||||||
|
COLUMN_NAME,
|
||||||
|
*(name for name in defaults if name not in {"pk", COLUMN_NAME}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def install_site_prefix_column():
|
||||||
|
from dcim.tables import DeviceTable, RackTable
|
||||||
|
from utilities.tables import register_table_column
|
||||||
|
|
||||||
|
column = SitePrefixColumn(
|
||||||
|
accessor=tables.A("site"),
|
||||||
|
verbose_name="Prefix",
|
||||||
|
empty_values=(),
|
||||||
|
orderable=False,
|
||||||
|
)
|
||||||
|
register_table_column(column, COLUMN_NAME, DeviceTable, RackTable)
|
||||||
|
prepend_to_default_columns(DeviceTable)
|
||||||
|
prepend_to_default_columns(RackTable)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
|
||||||
|
from netbox_utilities.site_prefix import COLUMN_NAME, SitePrefixColumn, first_word, prepend_to_default_columns
|
||||||
|
|
||||||
|
|
||||||
|
class SitePrefixTest(SimpleTestCase):
|
||||||
|
def test_first_word(self):
|
||||||
|
self.assertEqual(first_word("Berlin Campus West"), "Berlin")
|
||||||
|
self.assertEqual(first_word(" DC01\tFrankfurt "), "DC01")
|
||||||
|
|
||||||
|
def test_first_word_handles_missing_or_blank_value(self):
|
||||||
|
self.assertIsNone(first_word(None))
|
||||||
|
self.assertIsNone(first_word(" "))
|
||||||
|
|
||||||
|
def test_column_renders_first_word_of_site_name(self):
|
||||||
|
column = SitePrefixColumn()
|
||||||
|
|
||||||
|
self.assertEqual(column.render(SimpleNamespace(name="DC01 Frankfurt")), "DC01")
|
||||||
|
self.assertIsNone(column.render(None))
|
||||||
|
|
||||||
|
def test_prefix_column_is_first_default_column(self):
|
||||||
|
table = SimpleNamespace(Meta=SimpleNamespace(default_columns=("pk", "name", COLUMN_NAME, "status")))
|
||||||
|
|
||||||
|
prepend_to_default_columns(table)
|
||||||
|
|
||||||
|
self.assertEqual(table.Meta.default_columns, ("pk", COLUMN_NAME, "name", "status"))
|
||||||
|
|
||||||
|
def test_device_and_rack_tables_offer_prefix_column(self):
|
||||||
|
from dcim.tables import DeviceTable, RackTable
|
||||||
|
|
||||||
|
self.assertIn(COLUMN_NAME, DeviceTable.base_columns)
|
||||||
|
self.assertIn(COLUMN_NAME, RackTable.base_columns)
|
||||||
|
self.assertEqual(DeviceTable.Meta.default_columns[:2], ("pk", COLUMN_NAME))
|
||||||
|
self.assertEqual(RackTable.Meta.default_columns[:2], ("pk", COLUMN_NAME))
|
||||||
Reference in New Issue
Block a user